Внедрение зависимостей при создании класса также требует значений времени выполнения? - PullRequest
7 голосов
/ 25 июня 2010

Предположим, вы разделяете свои системы на объекты Value и объекты Services (как это предлагается в "Растущем объектно-ориентированном программном обеспечении, управляемом тестами". Misko Hevery называет эти "newables" и "injectables".

Чтопроисходит, когда одному из ваших объектов-значений внезапно требуется доступ к сервису для реализации его методов?

Допустим, у вас есть хороший простой объект Value. Он неизменный, содержит несколько битов информации и все об этом.мы используем его примерно так:

CreditCard card = new CreditCard("4111-1111-1111-1111", "07/10");
if (card.isValid())
{
  // do stuff
} 
else
{
  // don't do stuff
}

Пока все хорошо. isValid() реализует алгоритм контрольной цифры для номера карты и возвращает true / false.

Теперь, скажем, яВы хотите улучшить систему, проверив дату окончания срока действия по текущему времени. Как бы вы предположили, что это делается без нарушения парадигмы объекта Value / Service? Мне бы хотелось, чтобы этот класс продолжал проверяться модулем.

  • CreditCard теперь имеет зависимость, но из-за того, как она создается, ее нельзя внедрить, поэтому зависимость зависитction out.
  • Класс CreditCard не должен вызывать синглтоны (я считаю, что глобальный доступ к синглтону - плохая практика)
  • Включение поведения на CreditCardVerificationService.validateCard() означает, что весь существующий код должен быть пересмотрен.Реализация isValid () просачивается.

Я знаю, что можно обойти это, но какой самый чистый способ?

Ответы [ 3 ]

4 голосов
/ 25 июня 2010

Я бы сказал, что проверять что-либо не является задачей объекта CreditCard.Фабрика проверит контрольные цифры, чтобы убедиться, что она создает соответствующую карту, в то время как служба проверки проверит карту на срок действия / лимит $.

1 голос
/ 25 июня 2010

Я бы хотел сказать, что CreditCard не является объектом значения.

Из C2 wiki :

Примерами объектов стоимости являются вещи как числа, даты, деньги и строки. Обычно они маленькие объекты, которые используются довольно широко. Их личность основана на их состоянии а не на их объекте идентичности. Таким образом, вы можете иметь несколько копий одного и того же концептуального объекта значения.

Объект значения не является BusinessObject / ReferenceObject. BusinessObject / ReferenceObject - это то, что вы найдете в мире, в то время как ValueObject является мерой или описание чего-либо.

Если CreditCardNumber может быть объектом значения, CreditCard больше похож на бизнес-объект, который содержит некоторую бизнес-логику, например, проверка.

У меня обычно есть Объект Значения, Сервис и Бизнес-объект. Я не знаю о «Растущем объектно-ориентированном программном обеспечении», но ограничение себя только Value Object и Service мне кажется странным.

0 голосов
/ 29 марта 2011

Я бы назвал CreditCard сущность , а не объект значения , поскольку он, вероятно, будет постоянным и будет иметь уникальную идентичность.

В любом случае, этодолжно быть прекрасно для класса сущностей использовать классы обслуживания.Если реализации указанных сервисов не нужно выбирать во время выполнения на основе внешней конфигурации, то я бы просто создал и использовал нужный класс сервиса внутри метода client.Вопреки тому, что некоторые могут подумать, это не исключает модульного тестирования, поскольку инструмент изоляции может использоваться для изоляции.

Если реализацию службы действительно нужно выбрать во время выполнения, чем Сервисный локатор может быть использован.Этот шаблон может обеспечить прямую поддержку для насмешек / подделок, без необходимости в специальном инструменте для насмешек.Использование DI-фреймворка, поддерживающего внедрение в «новые» объекты, было бы другой альтернативой.

...