Just enjoy programming

c++设计模式(八) 工厂模式:封装对象的创建

     工厂模式不允许将创建对象的代码散布于整个系统。如果程序中所有需要创建对象的代码都转到这个工厂执行,那么在增加新对象时所要做的全部工作就是只需修改工厂。这种设计时众所周知的工厂方法模式的一种变体。由于每个面向对象应用程序都需要创建对象,并且由于人们可能通过添加新类型来扩展应用程序,工厂模式可能是所有设计模式中最有用的模式之一。实现工厂模式的一种方法就是在基类中定义一个静态成员函数,示例如下:
#include<iostream>
#include<stdexcept>
#include<cstddef>
#include<string>
#include<vector>

using namespace std;

class Shape
{
public:
    virtual void draw()=0;
    virtual void erase()=0;
    virtual ~Shape(){}
    class BadShapeCreation :public logic_error
    {
    public:
        BadShapeCreation(string type):
            logic_error("Cannot create type"+type){}
    };
    static Shape* factory(const string &type)
        throw(BadShapeCreation);
};

class Circle:public Shape
{
    Circle(){}
    friend class Shape;
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 Shape;
public:
    void draw(){cout<<"Square::draw"<<endl;}
    void erase(){cout<<"Square::erase"<<endl;}
    ~Square(){cout<<"Square::~Square"<<endl;}
};

Shape *Shape::factory(const string & type)
    throw(Shape::BadShapeCreation)
{
    if(type=="Circle")return new Circle;
    if(type=="Square")return new Square;
    throw BadShapeCreation(type);
}

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(Shape::factory(sl[i]));
    }catch(Shape::BadShapeCreation e)
    {
        cout<<e.what()<<endl;
        return -1;
    }
    for(size_t i=0;i<shapes.size();i++)
    {
        shapes[i]->draw();
        shapes[i]->erase();
    }
}

函数factory 允许以一个参数来决定创建何种类型的Shape。在这里,参数类型为string,也可以是任何数据集。为了确保对象的创建只能发生在函数factory()中,Shape的特定类型的构造函数被设为私有,同时Shape被声明为友元类,因此factory()能够访问这些构造函数。

参考: C++编程思想卷2

posted on 2011-05-03 23:12 周强 阅读(1495) 评论(0)  编辑 收藏 引用 所属分类: c/c++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理