工厂模式:封装对象的创建(二、多态工厂)

在上篇中,静态成员函数  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)工厂方法模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值