Chenxs110 发表于 2012-8-16 23:41

<漫谈设计模式>======对象创建型模式之工厂方法模式

本帖最后由 Chenxs110 于 2012-8-16 23:52 编辑

Factory Method 工厂方法模式
1.意图

   定义一个用于创建对象的接口,让子类去决定实例化哪一个类.Factory Method使一个类的实例化延迟到其子类.

2.动机

   假设有这样一个应用框架(client端),它可以向用户显示多个文档.在这个框架中,有两个抽象的类.Application和
Document.这两个类都是抽象的,客户必须通过它们的子类来做与具体应用相关的实现.例如,我们有一个画图程序.
我们定义类DrawingApplication和DrawingDocument.Application类负责管理Document并根据需要创建它们---比如,
当用户选择open或者new的时候(这种情形我们也经常遇到,比如MFC中的Application和Document的关系).
   因为被实例化的特定Document子类是与特定应用相关的.所以Application类不可能预测到哪个Document子类
即将被实例化.Application类仅知道一个新的文档什么时候被创建.但是它不知道哪一种Document将被创建.
这样就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能实例化的抽象类.
Factory Method模式提供了一个解决方案,它封装了哪一个Document子类将被创建的信息并将这些信息从该框架中分离出来
放入单独的类中(MyApplication类),UML图如下.

Application中定义了虚函数CreateDocument用来创建文档,这就好比定义了具有生产功能的工厂.但是这个工厂到底能生产什么,
我们需要在它的子类(MyApplication)中来决定(也就是将类的实例化放入的它的子类).因为它重写了CreateDocument这个虚函数.

4.结构图


5.适用性
<1>当一个类不知道它所必须创建的对象的类的时候.(想想Application=。=)
<2>当一个类希望由它的子类来指定它所创建的对象的时候.
<3>当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将某一个帮助子类是代理者这一信息局部化的时候.

6.实现(大话设计模式中的计算器例子)

以加法为例:class Factory
{
public:
        virtual Operation * CreateOperation() = 0;
        Factory();
        virtual ~Factory();
};定义一个抽象的Factory类(VC自动生成的代码,没用的东西我就懒得去掉了),用来生产对象.
接下来定义我们需要生产的产品,这个例子中就是Operation(运算法则).class Operation
{
public:
        virtual int GetResult();
        Operation();
        virtual ~Operation();
        int _result;
        int _numberB;
        int _numberA;
};其中包含了获取结果的接口和两个操作数,还有返回值.这个就是我们需要生产的产品的抽象类.
具体到某个产品就可以使加法,减法等操作.
我们定义一个加法操作类AddOperationclass AddOperation : public Operation
{
public:
        int GetResult();
        AddOperation();
        virtual ~AddOperation();

};并重写GetResult方法int AddOperation::GetResult()
{
        _result=_numberA+_numberB;
        return _result;
}需要生产的对象有了,接下来就是具体生产这种对象的工厂了.这个例子中就是AddFactoryclass AddFactory : public Factory
{
public:
        Operation * CreateOperation();
        AddFactory();
        virtual ~AddFactory();

};重写CreateOperation方法Operation * AddFactory::CreateOperation()
{
        return new AddOperation();
}到这里,工厂模式已经完成.

接下来看看客户端怎么使用它吧.int main()
{
        Operation * factory;
        int result;
        factory = new AddOperation();
        result=factory->GetResult();
        cout<<result<<endl;
}是不是方便了很多=。=
以后要添加除法,乘法,甚至是多个操作数的运算.
我们只需要拓展类就行了,不用修改代码.正好满足开发-封闭原则(软件实体应该可以拓展,但是不可修改).



可乐煎饼 发表于 2012-8-16 23:44

看了楼主的帖子 我终于承认自己不学无术了

Chenxs110 发表于 2012-8-17 14:46

汗这个貌似是冷门啊{:1_937:}
页: [1]
查看完整版本: <漫谈设计模式>======对象创建型模式之工厂方法模式