简单工厂模式的核心思想是把创建对象过程和对象本身业务处理分离,工厂处理创建对象的细节。
具体实现如下:
1. 定义一个操作接口:
class COperation
{
public:
virtual double GetResult(double a, double b) = 0;
};
2. 定义具体的操作类:
class COperationAdd : public COperation
{
public:
virtual double GetResult(double a, double b)
{
return a+b;
}
};
class COperationSub : public COperation
{
public:
virtual double GetResult(double a, double b)
{
return a-b;
}
};
3. 定义简单工厂类:
class CSimpleOperationFactory
{
public:
virtual COperation* createOperation(int type)
{
COperation* op = NULL;
switch(type)
{
case 1:
{
op = new COperationAdd();
}
break;
case 2:
{
op = new COperationSub();
}
break;
default:
break;
}
return op;
}
};
//静态方法
class CSimpleOperationFactory
{
public:
static COperation* createOperation(int type)
{
COperation* op = NULL;
switch(type)
{
case 1:
{
op = new COperationAdd();
}
break;
case 2:
{
op = new COperationSub();
}
break;
default:
break;
}
return op;
}
};
4. 用户端代码:
class calculator
{
public:
calculator(CSimpleOperationFactory* factory)
{
mFactory = factory;
}
double operate(double a, double b, int type)
{
COperation* op = mFactory->createOperation(type);
return op->GetResult(a, b);
}
private:
CSimpleOperationFactory* mFactory;
};
我们无需提供具体的子类类名,只需要提供一个类型(type)即可得到相应的实例对象。这样的话,当子类的类名更换或者增加子类时我们都无需修改客户端代码,只需要在简单工厂类上增加一个分支判断代码即可。
缺点:
该模式使得工厂的负担过重,而且每次添加新产品,都需要修改工厂,不是很符合开闭原则,但是比直接在业务逻辑里添加要好很多了。
问:这么做有什么好处?似乎只是把问题搬到另一个对象罢了,问题依然存在。
答:别忘了,SimpleFactory可以有许多客户。所以把创建对象的代码封装进一个类,当以后实现改变时,只需要修改这个类即可。别忘了,我们也正要把具体实例化的过程,从客户的代码中删除!
问:我曾看过一个类似的实现,把工厂定义成一个静态的方法。这有何差别?
答:利用静态方法实现一个简单工厂,这是很常见的技巧,常被称为静态工厂。为何使用静态方法?因为不需要使用创建对象的方法来实例化对象。但请记住,这也有缺点,不能通过继承来改变创建方法的行为。