好友
阅读权限20
听众
最后登录1970-1-1
|
本帖最后由 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;
}
是不是方便了很多=。=
以后要添加除法,乘法,甚至是多个操作数的运算.
我们只需要拓展类就行了,不用修改代码.正好满足开发-封闭原则(软件实体应该可以拓展,但是不可修改).
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|