工厂模式:封装对象的创建(二、多态工厂)
2015-12-07 15:28
495 查看
在上篇中,静态成员函数 static Shape* factory(const string& type) 迫使所有创建对象的操作都集中在一个地方,因此这个地方就是唯一需要修改代码的地方。这是一个合理的决解方法,因为它完美的封装了对象的创建过程。但是工厂方法模式——可以使不同类型的的工厂派生自基本类型的工厂。工厂方法事实上就是多态工厂模式的一个特例。所以下面例子是——工厂方法模式做为一个单独的类中的虚函数出现。#include <stdexcept>#include <cstddef>#include <string>#include <vector>#include <algorithm>#include <iostream>using namespace std;template<class Seq> void purge(Seq& c){typename Seq::iterator i;for(i = c.begin(); i != c.end(); ++i){delete *i;*i = 0;}}// Iterator version:template<class InpIt> void purge(InpIt begin, InpIt end){while(begin != end){delete *begin;*begin = 0;++begin;}}class Shape{public: virtual void draw() = 0; virtual void erase() = 0; virtual ~Shape() {}};class ShapeFactory { virtual Shape* create() = 0; static map< string , ShapeFactory* > factories;public: virtual ~ShapeFactory(){} friend class ShapeFactoryInitializer; class BadShapeCreation : public logic_error { public: BadShapeCreation(string type): logic_error("Cannot create type " + type) {} }; static Shape * createShape(const string& id) throw(BadShapeCreation) { if(factories.find(id) != factories.end()) return factories[id]->create(); else throw BadShapeCreation(id); } };
//define static object map< string , ShapeFactory* > ShapeFactory::factories; class Circle : public Shape { Circle() {} // Private constructor friend class ShapeFactoryInitializer; class Factory; friend class Factory; class Factory:public ShapeFactory { public: Shape* create() { return new Circle; } friend class ShapeFactoryInitializer; }; public: void draw() { cout << "Circle::draw" << endl; } void erase() { cout << "Circle::erase" << endl; } ~Circle() { cout << "Circle::~Circle" << endl; } };
class Square : public Shape { Square() {} friend class ShapeFactoryInitializer; class Factory; friend class Factory; class Factory:public ShapeFactory { public: Shape* create() { return new Square; } friend class ShapeFactoryInitializer; }; public: void draw() { cout << "Square::draw" << endl; } void erase() { cout << "Square::erase" << endl; } ~Square() { cout << "Square::~Square" << endl; } }; //Singleton to initialize the ShapeFactory class ShapeFactoryInitializer { static ShapeFactoryInitializer si; ShapeFactoryInitializer() { ShapeFactory::factories["Circle"]=new Circle::Factory; ShapeFactory::factories["Square"]=new Square::Factory; } ~ShapeFactoryInitializer() { map<string,ShapeFactory*>::iterator it=ShapeFactory::factories.begin(); while(it!=ShapeFactory::factories.end()) delete it++->second; } };
//static member definition ShapeFactoryInitializer ShapeFactoryInitializer::si; char* sl[] = { "Circle", "Square", "Square","Circle", "Circle", "Circle", "Square"}; int main() { vector<Shape*> shapes; try { for(size_t i = 0; i < sizeof sl / sizeof sl[0]; i++) shapes.push_back(ShapeFactory::createShape(sl[i])); } catch(ShapeFactory::BadShapeCreation e) { cout << e.what() << endl; return -1; } for(size_t i = 0; i < shapes.size(); i++) { shapes[i]->draw(); shapes[i]->erase(); } purge(shapes); }工厂方法模式作为virtual create() 出现在它自己的 ShapeFactory 类中,这是一个私有的成员函数。意味着不能直接调用它,但是可以被覆盖。Shape 的子类必须创建各自的 ShapeFactory子类,并且覆盖成员函数 create()以创建其自身类型的对象。这些工厂是私有的,只能被工厂方法模式访问。采用这种方法的所有客户代码都必须通过工厂方法模式创建对象。Shape对象的实际创建是通过调用ShapeFactory::createShape() 完成对的,这是一个静态成员函数,使用ShapeFactory 中的map 根据传递给它的标识符找到相应的工厂对象。工厂直接创建Shape 对象,但是可以设想一个更为复杂的问题:在某个地方返回一个合适的工厂对象。然后该工厂对象被调用者用于以更复杂的方法创建一个对象。然而,似乎在大多数情况下不需要这么复杂地使用多态工厂方法模式。注意,ShapeFactory 必须通过装载它的map 与工厂对象进行初始化,这些操作发生在单例ShapeFactoryInitializer, 以便将工厂的一个实例插入到map中。这些额外的复杂的操作再次暗示,如果不需要创建独立的工厂对象,应该尽可能使用静态(static)工厂方法模式
相关文章推荐
- C#与.net高级编程 C#的多态介绍
- C#中面向对象编程机制之多态学习笔记
- C#中的多态深入理解
- C#中多态、重载、重写区别分析
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- 介绍php设计模式中的工厂模式
- asp.net 简单工厂模式和工厂方法模式之论述
- 深入理解JavaScript系列(28):设计模式之工厂模式详解
- js简单工厂模式用法实例
- javascript 模式设计之工厂模式详细说明
- c#基础学习之多态
- PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)
- 从汇编看c++中多态的应用
- javascript 面向对象全新理练之继承与多态
- Java多态的使用注意事项
- python中getattr函数使用方法 getattr实现工厂模式
- 工厂模式在Zend Framework中应用介绍
- 浅析php工厂模式
- C++设计模式之抽象工厂模式
- C++设计模式之简单工厂模式实例