- •Гагарина. Л.Г., Федоров а.Р., Федоров п.А. Введение в архитектуру проектирования программного обеспечения Москва
- •Оглавление
- •5.11. Паттерны grasp
- •Глава 1. Архитектура как форма концептуального существования по
- •1.1. Определения архитектуры по и ее значимость
- •1.2. Место архитектурных решений
- •1.3. Роль архитектурных решений
- •1.4. Архитектурные концептуальные схемы. Определение и ретроспектива
- •Глава 2. Нормативные практики архитектурного описания по
- •2.1. Основные понятия
- •2.2. Содержание стандарта
- •2.3. Представления схемы ieee-1471
- •Глава 3. Рациональный процесс архитектурного моделирования
- •3.1. Архитектурные парадигмы
- •3.2. Примеры архитектурных стилей и моделей
- •Глава 4. Сравнительное сопоставление архитектурных видов
- •4.1. Сопоставление систем видов
- •4.2. Примеры систем видов
- •Языки описания архитектуры
- •Глава 5. Проектирование с учетом будущих изменений.
- •5.1. Что такое паттерн проектирования.
- •5.2. Как решать задачи проектирования с помощью паттернов
- •3. Зависимость от аппаратной и программной платформ.
- •5.4. Порождающие паттерны
- •5.4.1. Паттерн Фабричный метод (Factory Method) - уровень класса
- •Классический вариант фабричного метода, когда интерфейс фабричных методов объявляется в независимом классе-фабрике, а их реализация определяется конкретными подклассами этого класса (Рис. 33).
- •Реализация паттерна Factory Method на основе обобщенного конструктора
- •Void info() {
- •Void info() {
- •Void info() {
- •Int main()
- •V.Push_back( Warrior::createWarrior( Infantryman_id));
- •V.Push_back( Warrior::createWarrior( Archer_id));
- •V.Push_back( Warrior::createWarrior( Horseman_id));
- •Void info() {
- •Void info() {
- •Void info() {
- •Int main()
- •5.4.2. Паттерн Одиночка (Singleton) - уровень объекта
- •Классическая реализация Singleton
- •If(!p_instance)
- •Singleton Мэйерса
- •Улучшенная версия классической реализации Singleton
- •Void initialize( Singleton* p );
- •Void SingletonDestroyer::initialize( Singleton* p ) {
- •If(!p_instance) {
- •Использование нескольких взаимозависимых одиночек
- •Int main()
- •5.4.3. Паттерн Абстрактная фабрика (Abstract Factory) - уровень объекта
- •Пример кода для паттерна Abstract Factory
- •Void info() {
- •Int main()
- •5.4.4. Паттерн Строитель (Builder) - уровень объекта
- •Void info() {
- •Int main()
- •Infantryman
- •Infantryman
- •5.4.5. Паттерн Прототип (Prototype) - уровень объекта
- •Void info() {
- •Void info() {
- •5.4.6. Обсуждение порождающих паттернов
- •5.5. Структурные паттерны
- •5.5.1. Паттерн Адаптер, обертка (Adapter, wrapper)
- •Адаптер объекта применяет композицию объектов.
- •Int main()
- •Void adjust() {} // Настройка датчика (защищенный метод)
- •5.5.2. Паттерн Мост (Bridge)
- •Void log( string & str );
- •Достоинства паттерна Bridge
- •5.5.3. Паттерн компоновщик (Composite)
- •Описание паттерна Composite
- •Virtual void addUnit(Unit* p) {
- •Int main()
- •Virtual CompositeUnit* getComposite() {
- •Void addUnit(Unit* p);
- •Достоинства паттерна Composite
- •Недостатки паттерна Composite
- •5.5.4. Паттерн декоратор (Decorator , wrapper, обертка)
- •Реализация паттерна Decorator
- •Int width, height;
- •5.5.5. Паттерн фасад (Facade)
- •Void submitNetworkRequest()
- •If (_engineer.CheckOnStatus())
- •5.5.6. Паттерн приспособленец (Flyweight)
- •Структура паттерна приспособленец (Flyweight)
- •Icon(char *fileName)
- •Icon *FlyweightFactory::_icons[];
- •5.5.7 Паттерн заместитель (Proxy, surrogate, суррогат)
- •Void draw()
- •Int balance;
- •5.5.8. Обсуждение структурных паттернов
- •5.6. Паттерны поведения
- •5.6.1. ПаттернЦепочка обязанностей (Chain of Responsibility)
- •Void setNext(Base *n)
- •5.6.2. Паттерн Command (команда)
- •Реализация паттерна Command
- •5.6.3. Паттерн Interpreter (интерпетатор)
- •Совместное использование паттернов Interpreter и Template Method
- •Int interpret(char*); // interpret() for client
- •Virtual void interpret(char *input, int &total)
- •Int index;
- •If (!strncmp(input, nine(), 2))
- •Virtual char one(){}
- •Int items[10];
- •Int main()
- •5.6.5. Паттерн Mediator (посредник)
- •Virtual void changed();
- •Void Widget::changed()
- •Int main()
- •5.6.6. Паттерн Memento (хранитель)
- •Int _state;
- •Void static redo()
- •Int main()
- •Integer: 11
- •5.6.7. Паттерн Observer (наблюдатель)
- •Int value;
- •5.6.8. Паттерн State
- •Void setCurrent(State *s)
- •5.6.9. Паттерн Strategy
- •Void compress( const string & file ) {
- •5.6.10. Паттерн Template Method (шаблонный метод)
- •Void a()
- •V.Visit(this);
- •V.Visit(this);
- •V.Visit(this);
- •Int main()
- •5.6.12. Обсуждение паттернов поведения
- •5.7. Дальнейшее развитие идеи паттернов проектирования
- •5.8. Архитектурные системные паттерны
- •5.9. Паттерны управления
- •5.9.1. Паттерны централизованного управления
- •5.10. Паттерны интеграции корпоративных информационных систем
- •5.10.1. Структурные паттерны интеграции
- •5.10.2. Паттерны по методу интеграции
- •5.10.3. Паттерны интеграции по типу обмена данными
- •5.12. Антипаттерны (anti-patterns)
- •Глава 6. Архитектура и характеристики качества
- •6.1. Специфика требований к качеству по
- •6.2. Подход к построению архитектуры с позиций качества
- •6.3. Подходы к оцениванию архитектуры
Void info() {
cout << "Infantryman" << endl;
}
private:
Infantryman() {}
};
class Archer: public Warrior
{
friend class PrototypeFactory;
public:
Warrior* clone() {
return new Archer( *this);
}
void info() {
cout << "Archer" << endl;
}
private:
Archer() {}
};
class Horseman: public Warrior
{
friend class PrototypeFactory;
public:
Warrior* clone() {
return new Horseman( *this);
}
void info() {
cout << "Horseman" << endl;
}
private:
Horseman() {}
};
// Фабрика для создания боевых единиц всех родов войск
class PrototypeFactory
{
public:
Warrior* createInfantrman() {
static Infantryman prototype;
return prototype.clone();
}
Warrior* createArcher() {
static Archer prototype;
return prototype.clone();
}
Warrior* createHorseman() {
static Horseman prototype;
return prototype.clone();
}
};
int main()
{
PrototypeFactory factory;
vector<Warrior*> v;
v.push_back( factory.createInfantrman());
v.push_back( factory.createArcher());
v.push_back( factory.createHorseman());
for(int i=0; i<v.size(); i++)
v[i]->info();
// ...
}
В приведенной реализации для упрощения кода реестр прототипов не ведется. Воины всех родов войск создаются при помощи соответствующих методов фабричного класса PrototypeFactory, где и определены прототипы в виде статических переменных.
Результаты применения паттерна Prototype
Достоинства паттерна Prototype
Для создания новых объектов клиенту необязательно знать их конкретные классы.
Возможность гибкого управления процессом создания новых объектов за счет возможности динамических добавления и удаления прототипов в реестр.
Недостатки паттерна Prototype
Каждый тип создаваемого продукта должен реализовывать операцию клонирования clone(). В случае, если требуется глубокое копирование объекта (объект содержит ссылки или указатели на другие объекты), это может быть непростой задачей.
Родственные паттерны
В некоторых отношениях прототип и абстрактная фабрика являются кон-курентами. Но их используют и совместно. Абстрактная фабрика может хранить набор прототипов, которые клонируются и возвращают изготовленные объекты.
В тех проектах, где активно применяются паттерны компоновщик и декоратор, тоже можно извлечь пользу из прототипа.
5.4.6. Обсуждение порождающих паттернов
Есть два наиболее распространенных способа параметризовать систему клас-
сами создаваемых ей объектов. Первый способ - порождение подклассов от класса, создающего объекты. Он соответствует паттерну фабричный метод. Основной недостаток метода: требуется создавать новый подкласс лишь для того, чтобы изменить класс продукта. И таких изменений может быть очень много.
Другой способ основан на композиции объектов. Вы определяете объект, которому известно о классах объектов-продуктов, и делаете его параметром системы. Это ключевой аспект таких паттернов, как абстрактная фабрика, строитель и прототип. Для всех трех характерно создание ≪фабричного объекта≫, который изготавливает продукты.
В абстрактной фабрике фабричный объект производит объекты разных классов.
Фабричный объект строителя постепенно создает сложный продукт, следуя специальному протоколу. Фабричный объект прототипа изготавливает продукт путем копирования объекта-прототипа. В последнем случае фабричный объект
и прототип - это одно и то же, поскольку именно прототип отвечает за возврат
продукта.
Выбор паттерна зависит от многих факторов. В случае применения паттерна фабричный метод проект в большей степени поддается настройке. Другие пат-
терны нуждаются в создании новых классов, а фабричный метод - только в со-
здании одной новой операции. Часто этот паттерн рассматривается как стандартный способ создания объектов, но вряд ли его стоит рекомендовать в ситуации, когда инстанцируемый класс никогда не изменяется или когда инстанцирование выполняется внутри операции, которую легко можно заместить в подклассах (например, во время инициализации).
Проекты, в которых используются паттерны абстрактная фабрика, прототип
или строитель, оказываются еще более гибкими, чем те, где применяется фабричный метод, но за это приходится платить повышенной сложностью. Часто в начале работы над проектом за основу берется фабричный метод, а позже, когда проектировщик обнаруживает, что решение получается недостаточно гибким, он выбирает другие паттерны. Владение разными паттернами проектирования открывает перед вами широкий выбор при оценке различных критериев.
