• «Объект-значение» (Value Object) – после создания объекта его значение никогда не меняется, благодаря этому удается избежать проблем, связанных с наложением имен (aliasing);
• «Нуль-объект» (Null Object) – соответствует базовому случаю вычислений объекта;
• «Шаблонный метод» (Template Method) – представляет собой инвариантную последовательность операций, определяемую при помощи абстрактных методов, которые можно переопределить с помощью наследования;
• «Встраиваемый объект» (Pluggable Object) – представляет собой вариацию в виде объекта с двумя реализациями или большим их количеством;
• «Встраиваемый переключатель» (Pluggable Selector) – позволяет избежать создания многочисленных подклассов путем динамического обращения к различным методам для различных экземпляров класса;
• «Фабричный метод» (Factory Method) – вместо конструктора для создания объекта используется специальный метод;
• «Самозванец» (Imposter) – представляет собой вариацию путем создания новой реализации существующего протокола;
• «Компоновщик» (Composite) – композиция объектов ведет себя так же, как один объект;
• «Накапливающий параметр» (Collecting Parameter) – результаты вычислений, выполняемых в разных объектах, накапливаются в специальном объекте, который передается объектам, выполняющим вычисления, в качестве параметра.
В табл. 30.1 описывается, на каких этапах TDD используется тот или иной шаблон проектирования.
Таблица 30.1.Использование шаблонов проектирования при разработке через тестирование (TDD)
Команда (Command)
Что делать, если выполнение некоторой операции представляет собой нечто более сложное, чем простое обращение к методу? Создайте объект, соответствующий этой операции, и обратитесь к этому объекту.
Передача сообщений – это отличный механизм. Языки программирования делают передачу сообщений синтаксически простым действием, а среды разработки позволяют с легкостью манипулировать сообщениями (например, автоматическое выполнение рефакторинга по переименованию метода). Однако в некоторых случаях простой передачи сообщения недостаточно.
Например, представьте, что вы хотели бы занести в журнал запись о том, что сообщение было передано. Для этой цели можно воспользоваться средствами языка (например, методы-обертки), однако простые операции журналирования – это далеко не все, в чем вы можете нуждаться. Представьте, что мы хотим вызвать некоторую процедуру, но несколько позднее. Для этой цели можно создать новый программный поток, сразу же приостановить его работу, а затем, когда это потребуется, запустить его. Однако в подобной ситуации нам придется иметь дело с параллельными потоками, а это может оказаться слишком тяжеловесным подходом.
Для выполнения операций с подобными дополнительными условиями зачастую требуются сложные затратные механизмы. Однако в большинстве случаев мы можем избежать излишней сложности и лишних затрат. Проблему вызова можно решить с помощью более конкретной и гибкой формы, чем сообщение. Для этого достаточно создать специальный объект. Создайте объект, представляющий собой вызов операции. Занесите в этот объект все необходимые параметры операции. Когда операция готова к выполнению, используйте для этого универсальный протокол, например метод run().
Отличным примером использования данного подхода является интерфейс Runnable языка Java:
Runnable
interface Runnable
public abstract void run();
В рамках реализации метода run() вы можете делать все, что вам нравится. К сожалению, Java не поддерживает синтаксически легковесного способа создания объектов Runnable и обращения к этим объектам, поэтому они не используются так часто, как их эквиваленты в других языках (блоки или лямбда-выражения в Smalltalk/Ruby или LISP).
Объект-значение (Value Object)
Как следует спроектировать объект, который будет широко использоваться, но для которого идентификация не имеет особого значения? Настройте состояние объекта в момент его создания и никогда не меняйте его. В результате выполнения любых операций с данным объектом должен получаться новый объект.
Объектно-ориентированный подход – это великолепная вещь. Надеюсь, я имею право написать эту фразу в данной книге. Объекты являются отличным способом организации логики для последующего понимания и роста. Однако существует одна маленькая проблема (хорошо, хорошо, вообще-то проблем больше, однако сейчас мы коснемся только одной из них).
Читать дальше
Конец ознакомительного отрывка
Купить книгу