Обсуждение порождающих паттернов

Есть два наиболее распространенных способа параметризовать систему клас-

сами создаваемых ей объектов. Первый способ - порождение подклассов от клас-

са, создающего объекты. Он соответствует паттерну фабричный метод. Основ-

ной недостаток метода:требуется создавать новый подкласс лишь для того, чтобы

изменить класс продукта. И таких изменений может быть очень много. Напри-

мер, если создатель продукта сам создается фабричным методом, то придется

замещать и создателя тоже.

Другой способ параметризации системы в большей степени основан на ком-

позиции объектов. Вы определяете объект, которому известно о классах объек-

тов-продуктов, и делаете его параметром системы. Это ключевой аспект таких

паттернов, как абстрактная фабрика, строитель и прототип. Для всех трех

характерно создание ≪фабричного объекта≫, который изготавливает продукты.

В абстрактной фабрике фабричный объект производит объекты разных классов.

Фабричный объект строителя постепенно создает сложный продукт, следуя спе-

циальному протоколу. Фабричный объект прототипа изготавливает продукт пу-

тем копирования объекта-прототипа. В последнем случае фабричный объект

и прототип - это одно и то же, поскольку именно прототип отвечает за возврат

продукта.

Рассмотрим каркас графических редакторов, описанный при обсуждении naV-

терна прототип. Есть несколько способов параметризовать класс GraphicTool

классомпродукта:

а применить паттерн фабричный метод. Тогда для каждого подкласса клас-

са Graphic в палитре будет создан свой подкласс GraphicTool. В классе

GraphicTool будет присутствовать операция NewGraphic, переопределя-

емая каждым подклассом;

а использовать паттерн абстрактная фабрика. Возникнет иерархия классов

GraphicsFactories, по одной для каждого подкласса Graphic. В этом

случае каждая фабрика создает только один продукт: CircleFactory -

окружности Circle, LineFactory - отрезки Line и т.д. GraphicTool па-

раметризуется фабрикой для создания подходящих графических объектов;

о применить паттерн прототип. Тогда в каждом подклассе Graphic будет ре-

ализована операция Clone, a GraphicTool параметризуется прототипом

создаваемого графического объекта.

Выбор паттерна зависит от многих факторов. В нашем примере каркаса гра-

фических редакторов, на первый взгляд, проще всего воспользоваться фабрич-

ным методом. Определить новый подкласс GraphicTool легко, а экземпляры

GraphicTool создаются только в момент определения палитры. Основной недо-

статок такого подхода заключается в комбинаторном росте числа подклассов

GraphicTool, причем все они почти ничего не делают.

Абстрактная фабрика лишь немногим лучше, поскольку требует создания

равновеликой иерархии классов GraphicsFactory. Абстрактную фабрику сле-

дует предпочесть фабричному методу лишь тогда, когда уже и так существует

иерархия класса GraphicsFactory: либо потому, что ее автоматически строит

компилятор (как в Smalltalk или Objective С), либо она необходима для другой

части системы.

Очевидно, целям каркаса графических редакторов лучше всего отвечает пат-

терн прототип, поскольку для его применения требуется лишь реализовать опе-

рацию Clone в каждом классе Graphics. Это сокращает число подклассов,

a Clone можно с пользой применить и для решения других задач - например, для

реализации пункта меню Duplicate(дублировать), - а не только для инстанциро-

вания.

В случае применения паттерна фабричный метод проект в большей степени

поддается настройке и оказывается лишь немногим более сложным. Другие пат-

терны нуждаются в создании новых классов, а фабричный метод - только в со-

здании одной новой операции. Часто этот паттерн рассматривается как стандарт-

ный способ создания объектов, но вряд ли его стоит рекомендовать в ситуации,

когда инстанцируемый класс никогда не изменяется или когда инстанцирование

выполняется внутри операции, которую легко можно заместить в подклассах (на-

пример, во время инициализации).

Проекты, в которых используются паттерны абстрактная фабрика, прототип

или строитель, оказываются еще более гибкими-, чем те, где применяется фабрич-

ный метод, но за это приходится платить повышенной сложностью. Часто

в начале работы над проектом за основу берется фабричный метод, а позже, когда

проектировщик обнаруживает, что решение получается недостаточно гибким, он

выбирает другие паттерны. Владение разными паттернами проектирования откры-

вает перед вами широкий выбор при оценке различных критериев.

Обсуждение порождающих паттернов

Наши рекомендации