Как правильно выразить композицию в программе? - PullRequest
0 голосов
/ 29 сентября 2019

Предположим, у нас есть 2 класса: автомобиль и двигатель. Двигатель зависит от автомобиля - когда автомобиль уничтожен, двигатель тоже. Как правильно выразить зависимость Энгина от автомобиля? Отношения таковы, что класс Engine не имеет смысла вне автомобиля. На мой взгляд, впрыск двигателя указывает на некоторую независимость от автомобиля. Какой конструктор автомобилей является правильным в этом случае? С DI или без?

Пример кода:

interface IEngine { }

class Engine : IEngine { }

class Car
{
    private readonly IEngine _engine;

    public Car()
    {
        _engine = new Engine();
    }

    public Car(IEngine engine)
    {
        _engine = engine;
    }

}

Ответы [ 3 ]

0 голосов
/ 29 сентября 2019

Две мысли:

  1. Архитектура может зависеть от тестируемости. Инъекция облегчает тестирование класса, потому что можно вводить макеты или заглушки.

  2. Будьте осторожны, принимая слишком строгие отношения: двигатели, безусловно, могут существовать независимо от автомобилей, например, на заводах,ремонтные мастерские и в утилизации. Аналогично для шин и т. Д. (Вот почему я не хотел бы проектировать его как внутренний класс, как предложил Оливье.)

0 голосов
/ 29 сентября 2019

Используйте один с DI.

Что касается аналогии;если ваш автомобиль отвечает за сборку двигателя;трудно изменить двигатель в какой-то момент. Даже если вы не измените фактический тип (например, газовый на электрический), смена конструктора вызовет у вас некоторые проблемы.

Конечно, автомобиль не зависит от двигателя и, наоборот, от конкретного типа. то есть.

Например;Вы могли бы иметь показную модель автомобиля с фиктивным двигателем. Или испытательный центр для вашего сверхсовременного двигателя.

Итак, если это возможно: не делайте нового (особенно при работе с интерфейсами), но используйте DI. Особенно;когда вы имеете дело с реальным оборудованием; -)

0 голосов
/ 29 сентября 2019

Вы можете использовать вложенный класс:

public interface IEngine
{
  void SomeMethod();
}

public class Car
{

  private class DefaultEngine : IEngine
  {
    void IEngine.SomeMethod()
    {
      throw new NotImplementedException();
    }
  }

  private readonly IEngine _engine;

  public Car()
  {
    _engine = new DefaultEngine ();
  }

  public Car(IEngine engine)
  {
    _engine = engine;
  }

}

Вот некоторые объяснения:

Вложенные типы (Руководство по программированию в C #)

Почему / когда вы должны использовать вложенные классы в .net? Или нет?

...