Предположим, вы разделяете свои системы на объекты-ценности и объекты-службы (как это предлагается в статье «Развитие объектно-ориентированного программного обеспечения на основе тестов». Миско Хевери называет их «новыми» и «инъекционными»).
Что происходит, когда одному из ваших объектов-значений внезапно требуется доступ к сервису для реализации его методов?
Допустим, у вас есть хороший простой объект Value. Он неизменяем, содержит несколько битов информации и все. Допустим, мы используем его примерно так:
CreditCard card = new CreditCard("4111-1111-1111-1111", "07/10");
if (card.isValid())
{
// do stuff
}
else
{
// don't do stuff
}
Все идет нормально. isValid()
реализует алгоритм контрольной цифры номера карты и возвращает true/false.
Теперь предположим, что я хочу улучшить систему, сверив дату истечения срока действия с текущим временем. Как бы вы предложили это сделать, не нарушая парадима объект-значение/объект-сервис? Я хотел бы, чтобы этот класс продолжал тестироваться.
CreditCard
теперь имеет зависимость, но из-за способа ее создания ее нельзя внедрить, поэтому внедрение зависимостей исключено.- Класс
CreditCard
не должен обращаться к синглтонам (я считаю, что глобальный доступ к синглтону — плохая практика) - Помещение поведения на
CreditCardVerificationService.validateCard()
означает, что весь существующий код должен быть пересмотрен. Реализация isValid() просачивается.
Я знаю, что есть вещи, которые можно сделать, чтобы обойти это, но каков самый чистый способ?