Что передать через конструктор и что передать через интерфейс? - PullRequest
3 голосов
/ 28 октября 2010

Это вопрос о внедрении зависимости.При создании объекта службы мы передаем соавторов через конструктор на этапе построения.Служебный объект будет реализовывать интерфейс, и он будет вызываться во время фазы выполнения.

Иногда трудно понять, должен ли конкретный объект передаваться через конструктор или быть частью интерфейса, реализуемогокласс обслуживания?

Существуют ли правила выбора одного варианта из другого?Вопрос сложнее всего, когда вы знаете, что интерфейс будет вызываться только один раз в сценарии, для которого вы кодируете.

Ответы [ 2 ]

5 голосов
/ 28 октября 2010

Мне нравится думать об этом так:

  • Аргументы конструктора являются деталями реализации
    • Они относятся ко всем операциям
    • Они не изменяются в ответ на какую-либо операцию (инвариант)
    • Интерфейс можно понять без них
    • Это значения конфигурации, которые отражают швы приложения
  • Аргументы метода являются контекстными
    • Они относятся к отдельной операции
    • Это значения времени выполнения, которые отражают поток данных приложения

Большая часть искусства заключается в правильном определении проблемы. Например, мы можем сказать себе: «Мне нужно создать новую строку в пользовательской таблице». С этой точки зрения любая из этих подписей выглядит нормально:

void Insert(User user);

void Insert(User user, IDbConnection dbConnection);

Однако мы можем разбить наше определение задачи:

Намерение: Создать нового пользователя

Подробности реализации: Пользователь - это строка в таблице

Давайте вместо этого сформулируем задачу как «Мне нужно создать пользователя». Это дает нам возможность оценить две подписи выше, отдавая предпочтение той, которая соответствует нашему намерению:

void Insert(User user);

Анализ цели операции и применимого объема ее данных обычно дает надежные результаты.

2 голосов
/ 28 октября 2010

Практическое правило, которое я часто использую, заключается в том, может ли класс функционировать без передаваемого значения, сбалансированного со сложностью конструктора. Если класс не может работать должным образом без аргумента, обычно лучше поместить его в конструктор. С другой стороны, если класс предназначен для выполнения чего-то, что требует дополнительной работы, например, принимать соединения через сокет, такую ​​работу обычно следует отложить до более поздней функции.

...