
- •1.Объявление и определение класса.
- •3. Дружественные функции.
- •4. Пеpегpузка опеpаций ( синтаксис operator)
- •5. Статические компоненты класса.
- •7. Иерархия классов ( последовательность работы конструкторов и деструкторов )
- •8. Доступ к наследуемым компонентам
- •9. Виртуальные функции (когда применяются, форма вызова)
- •10 . Шаблоны ( пример template)
- •15 Преобразование типов данных.
- •17 Ввод-вывод в файл. Сохранение объектов в файле.
- •18 Обработка исключений (блоки try, throw, catch)
- •Примеры обработки исключительных ситуаций
- •20. Паттерны и их классификация. Принцип классификации паттернов проектирования
- •Паттерны проектирования классов/обьектов
- •21. Абстрактная фабрика.
- •22. Классификация типов данных. Система типов
- •Oбщий взгляд
- •Класс String
- •Объявление строк. Конструкторы класса string
- •Операции над строками
- •Цикл foreach
- •Наследование
- •Добавление полей потомком
- •Конструкторы родителей и потомков
- •Интерфейсы
- •Две стратегии реализации интерфейса
- •Преобразование к классу интерфейса
Паттерны проектирования классов/обьектов
Согласно классификации, предложенной в предыдущем разделе, описание системы в терминах классов/обьектов следует считать низшим уровнем ее представления. В свою очередь, при моделировании системы на уровне классов/обьектов обычно проводят дополнительную типологизацию в двух аспектах, а именно, описывают структуру системы в терминах микроскопических элементов (см. раздел 2) и то, каким образом такая система обеспечивает требуемый функционал. Соответственно, среди паттернов проектирования выделены структурные паттерны, см. раздел 3.1 и паттерны распределения обязанностей между классами/объектами, 3.2. Поскольку отдельные объекты создаются и уничтожаются в процессе работы системы, выделена еще одна большая группа паттернов проектирования, которые служат для создания обьектов, 3.3.
Необходимо отметить наличие еще одной классификации паттернов, которое очевидно из наименования данного раздела: паттерны проектирования классов и паттерны проектирования обьектов (определения класса и объекта см. в разделе 7.2). В качестве примера паттернов проектирования классов можно привести "Фабричный метод", "Шаблонный метод"; паттернов проектирования обьектов - "Абстрактную фабрику", "Хранителя" и др.
Кроме этого необходимо отметить, что некоторые паттерны проектирования обьектов часто используются совместно, например, паттерн "Компоновщик" часть применяется вместе с "Итератором" или "Посетителем". Помимо этого, одну и ту же задачу можно решить используя различные паттерны проектирования классов/обьектов в качестве альтернативы, так, например, "Прототип" зачастую используют вместо "Абстрактной фабрики".
21. Абстрактная фабрика.
Фабрика, по сути, это виртуальный конструктор. Предположим, у нас есть базовый класс и несколько его наследников. Мы хотим создавать объекты наследников, скрывая их за указателем на базовый класс. Кроме того, мы хотим, чтобы тип наследника определялся в динамике через какой-то параметр. Например, через строковое имя класса, как это сделано в моем примере.
#include <iostream>
#include <string>
#include <map>
#include <boost/shared_ptr.hpp>
template <class TBase>
class TFactory
{ public:
typedef boost::shared_ptr<TBase> BasePtr;
template <class TDerived>
void Register(const std::string& name)
{ m_FactoryContainer[name] = BaseTypePtr(new TDerivedType<TDerived>); }
BasePtr Create(const std::string& name)
{ return m_FactoryContainer[name]->Create(); }
private:
class BaseType
{ public:
virtual ~BaseType() {}
virtual BasePtr Create() const = 0; };
typedef boost::shared_ptr<BaseType> BaseTypePtr;
template <class T>
class TDerivedType : public BaseType
{ public:
virtual BasePtr Create() const
{ return new T; } };
typedef std::map<std::string, BaseTypePtr> FactoryContainer;
FactoryContainer m_FactoryContainer; };
class Furniture {
public:
~Furniture() {}
virtual void ShowName() = 0; };
class Table : public Furniture
{public:
virtual void ShowName()
{ std::cout << "Table" << std::endl; }};
class Chair : public Furniture
{public:
virtual void ShowName()
{std::cout << "Chair" << std::endl; }};
int main()
{ typedef TFactory<Furniture> FurnitureFactory;
typedef FurnitureFactory::BasePtr FurniturePtr;
FurnitureFactory factory;
factory.Register<Table>("Table");
factory.Register<Chair>("Chair");
FurniturePtr f1 = factory.Create("Table");
FurniturePtr f2 = factory.Create("Chair");
f1->ShowName();
f2->ShowName();
return 0;}
Итак, каждый наследник должен зарегистрироваться в фабрике и передать ей свой идентификатор. После этого фабрика может создавать объекты данного типа.
На мой взгляд, фабрика — ненужный паттерн.
Желание воспользоваться фабрикой возникает сразу же после того, как возникает желание отображать языковые функциональные типы в какие-то внешние системы. Например, сохранение на диск или передача по сети. Языковые функциональные типы не должны покидать пределов пространства языка. С внешними системами можно обмениваться только данными.