**Абстрактная фабрика** Паттерн Абстрактная фабрика предназначен для случаев, когда требуется создать сложный объект, состоящий из других объектов, причем все составляющие объекты принадлежат одному «семейству». **Построитель** Паттерн Построитель аналогичен паттерну Абстрактная фабрика в том смысле, что оба предназначены для создания сложных объектов, составленных из других объектов. Но отличается он тем, что не только предоставляет методы для построения сложного объекта, но и хранит внутри себя его полное представление. Этот паттерн допускает такую же композиционную структуру, как Абстрактная фабрика (то есть сложные объекты, составленные из нескольких более простых), но особенно удобен в ситуациях, когда представление составного объекта должно быть отделено от алгоритмов композиции. **Фабричный метод** Паттерн Фабричный метод применяется, когда мы хотим, чтобы подклассы выбирали, какой класс инстанцировать, когда запрашивается объект. Это полезно само по себе, но можно пойти дальше и использовать в случае, когда класс заранее неизвестен (например, зависит от информации, прочитанной из файла или введенных пользователем данных). **Прототип** Паттерн Прототип применяется для создания нового объекта путем клонирования исходного с последующей модификацией клона. **Одиночка** Паттерн Одиночка (Синглтон) применяется, когда необходим класс, у которого должен быть единственный экземпляр во всей программе. В некоторых объектно-ориентированных языках создать одиночку на удивление трудно, но Python к ним не относится. В сборнике рецептов для Python (code.activestate.com/recipes/langs/python/ ) приводится простой класс Singleton, которому любой класс может унаследовать, чтобы стать одиночкой. И класс Borg , который дает тот же результат совсем другим способом. Однако самый простой способ получить функциональность одиночки в Python - создать модуль с глобальным состоянием, которое хранится в закрытых переменных, и предоставить открытые функции для доступа к нему. **Адаптер** Паттерн Адаптер описывает технику адаптации интерфейса. Задача состоит в том, чтобы один класс мог воспользоваться другим с несовместимым интерфейсом - без внесения каких-либо изменений в оба класса. Это полезно, например, когда требуется воспользоваться не подлежащим изменению классом в контексте, на который он не был рассчитан. **Мост** Паттерн Мост используется в ситуациях, когда требуется отделить абстракцию (например, интерфейс или алгоритм) от ее реализации. Традиционный подход без использования паттерна Мост состоит в том, чтобы создать один или несколько абстрактных базовых классов, а затем предоставить две или более конкретных реализации каждого базового класса. А паттерн Мост предлагает создать две независимых иерархии классов: «абстрактную», которая определяет операции (например, интерфейс и алгоритмы верхнего уровня) и конкретную, предоставляющую реализацию, которые в конечном итоге и будут вызваны из абстрактных операций. «Абстрактный» класс агрегирует экземпляр одного из конкретных классов с реализацией - и этот последний служит мостом между абстрактным интерфейсом и конкретными операциями. **Компоновщик** Паттерн Компоновщик позволяет единообразно обрабатывать объекты, образующие иерархию, вне зависимости от того, содержат они другие объекты или нет. Такие объекты называются составными. В классическом решении составные объекты - как отдельные, так и коллекции - имеют один и тот же базовый класс. У составных и несоставных объектов обычно одни и те же основные методы, но составные объекты добавляют методы для поддержки добавления, удаления и перебора дочерних объектов. **Декоратор** Вообще говоря, декоратором называется функция, которая принимает функцию в качестве своего единственного аргумента и возвращает новую функцию с таким же именем, как у исходной, но с расширенной функциональностью. Декораторы часто используются в каркасах (например, в веб-каркасах), чтобы упростить интеграцию пользовательских функций с каркасом. Паттерн Декоратор настолько полезен, что в Python встроена специальная поддержка для него. В Python декорировать можно как функции, так и методы. Кроме того, Python поддерживает декораторы классов: функции, которые принимают класс в качестве аргумента и возвращают новый класс с таким же именем, как у исходного, но с дополненной функциональностью. Иногда декораторы классов удобно использовать как альтернативу производным классам. * Декораторы функций и методов Все декораторы функций (и методов) устроены одинаково. Прежде всего, они создают функцию-обертку (которую в этой книге мы всегда будем называть wrapper() ). Из обертки мы должны вызвать исходную функцию. Однако мы вправе выполнить до этого вызова произвольную предобработку, затем получить результат вызова, выполнить произвольную постобработку и вернуть все, что пожелаем - исходный результат, модифицированный результат или еще что-нибудь. Наконец, мы возвращаем функцию-обертку в виде результата декоратора, и эта функция заменяет исходную с тем же именем. Чтобы применить декоратор к функции, методу или классу, нужно написать знак @ с тем же отступом, что соответствующее предложение def или class , а сразу за ним указать имя декоратора. Ничто не мешает создавать вложенные декораторы, то есть применить декоратор к уже декорированной функции и так сколь угодно много раз. * Декораторы классов Классы с большим числом свойств, доступных для чтения и записи, - обычное дело. Нередко в них много повторяющегося или почти повторяющегося кода в методах чтения и установки свойств. Возьмем, к примеру, класс B o o k , в котором имеются свойства, содержащие название книги, ее код ISBN, цену и количество. Нам понадобилось бы четыре практически одинаковых декоратора @property (в каждом был бы КОД вида `@property def title(self): return title )`. Еще нужно было бы написать четыре метода установки, каждый со своей валидацией - хотя код валидации цены и количества отличался бы только величиной минимального и максимального значения. Если таких классов будет много, то у нас на руках окажется уйма почти одинакового кода.