Предположите деление систем на объекты Значения и Сервисные объекты (как предложено в "Росте Объектно-ориентированного программного обеспечения, Ведомого Тестами". Misko Hevery называет эти "newables" и "injectables".
Что происходит, когда один из Ваших объектов значения внезапно должен получить доступ к сервису для реализации, это - методы?
Скажем, у Вас есть хороший простой объект Значения. Это неизменно, содержит несколько битов информации, и это об этом. Скажем, мы используем его что-то вроде этого:
CreditCard card = new CreditCard("4111-1111-1111-1111", "07/10");
if (card.isValid())
{
// do stuff
}
else
{
// don't do stuff
}
Пока все хорошо. isValid()
реализует алгоритм контрольного разряда на номере карты и возвращает true.
Теперь, скажем, я хочу улучшить систему путем проверки даты окончания срока действия против текущего времени. Как Вы предположили бы, что это сделано, не повреждая паратусклый Объект/Объект службы Значения? Я хотел бы, чтобы этот класс продолжил быть тестируемой единицей.
CreditCard
теперь имеет зависимость, но из-за пути она создается, она не может быть введена, таким образом, внедрение зависимости отсутствует.CreditCard
класс не должен обращаться к Одиночным элементам (я имею положение, что глобальный доступ к Singleton является плохой практикой),CreditCardVerificationService.validateCard()
средство весь существующий код должно быть пересмотрено. Реализация isValid () просачивается.Я знаю, что существуют вещи, которые могут быть сделаны для обхождения этого, но каков самый чистый путь?
Я бы утверждал, что объект CreditCard не обязан ничего проверять. Фабрика проверит контрольные цифры, чтобы убедиться, что она инстанцирует соответствующую карту, а служба проверки проверит карту на срок действия/$-лимит.
Я бы склонен был сказать, что CreditCard
не является объектом значения.
Из C2 wiki:
Примерами объектов значения являются такие вещи. такие как числа, даты, деньги и строки. Обычно это небольшие объекты, которые используются довольно широко. Их идентичность основана на их состоянии а не на идентификации объекта. Таким образом, вы можете иметь несколько копий одного и того же концептуального объекта значения.
Объект ценности не является BusinessObject/ReferenceObject. A BusinessObject/ReferenceObject - это это то, что вы находите в мире, в то время как ценностный объект - это мера или описание чего-либо.
Если CreditCardNumber
может быть объектом значения, то CreditCard
больше похож на бизнес-объект, который содержит некоторую бизнес-логику, например, валидацию.
Обычно у меня есть Value Object, Service и Business Object. Я не знаю о "растущем объектно-ориентированном ПО", но ограничивать себя только Value Object и Service мне кажется странным.