Предположим, вы делите свои системы в Value объектов и служб объектов (как это было предложено в «Growing объектно-ориентированного программного обеспечения, руководствуясь Tests». Мисько Hevery называет эти «newables» и «уколы».Инъекция зависимостей, когда созданный класс также требует значений времени выполнения?
Что происходит, когда один из ваших объектов значения вдруг нужно получить доступ к службе, чтобы реализовать ее методы?
Предположим, у вас есть хороший простой объект 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 object paradim? Я бы хотел, чтобы этот класс оставался единым проверяемым.
CreditCard
теперь имеет зависимость, но из-за способа его создания его нельзя вводить, поэтому инъекция зависимостей отсутствует.CreditCard
класс не должен быть взывает к Одиночки (я придерживаюсь позиции, что глобальный доступ к Singleton является плохой практикой)- Положив поведение на
CreditCardVerificationService.validateCard()
означает, что все существующий код должен быть пересмотрен. Выполняется реализация isValid().
Я знаю, что есть вещи, которые можно сделать, чтобы обойти это, но что является самым чистым способом?
Интересно. Мне кажется естественным, что поведение (валидация) должно соответствовать данным, а не объекту CreditCard. –
Это превращает реальный мир в его голову. У кредитной карты нет никакого способа проверить себя - подделанные, просроченные карты живут в дикой природе и не имеют представления о том, являются ли они действительными или нет. Если вы отправите запрос платежному процессору, они не будут спрашивать вас, действительна ли ваша карта или занять свое слово - они сами это определит и просто запросят данные, необходимые для этого. – expedient
@WW: Также Роберт К. Мартин «Дядя Боб» рассказывает об этом при описании принципа единственной ответственности SOLID в своем примере модема (6-страничная статья: http://www.objectmentor.com/resources/articles/srp.pdf). Я думаю, что в прошлом CreditCard.Validate() считался бы хорошим объектно-ориентированным дизайном, но эта тенденция, похоже, отходит от многих отдельных классов. Также я задал вопрос об этом на ProgrammersSE http://programmers.stackexchange.com/questions/77690/design-object-method-vs-separate-classs-method-which-takes-object-as-parameter – User