一、简单工厂
1、简单工厂的定义
(1)提供一个创建对象实例的功能,而无需关心其具体实现。类图如下:
接口:接口是对行为的抽象,是一种行为规范。
抽象类:抽象类是对事物的抽象(类的抽象),模版式设计。
API接口:定义客户所需要的功能接口。(抽象类和接口均可以)
Impl:具体实现Api的实现类,可能会有多个
SimpleFatory类:工厂,选择合适的实现类来创建Api接口对象
Client:客户端,通过Factory来获取Api接口对象,然后面向Api接口编程。
(2)简单工厂的本质
选择实现,重点在选择。工厂类内部主要的功能是:选择合适的实现类来创建实例对象。
(3)简单工厂的目的
为客户端选择实现类,从而使得客户端和实现之间解耦。具体的实现类发生变化,也就不用变动客户端,这个变
化点被简单工厂吸收屏蔽掉。
(4)简单工厂命名建议
a、类名建议为“模块名称+Factory”。比如,用户模块的工厂就为UserFactory
b、方法名通常为“get+接口名称”或者是“create+接口名称”。
2、简单工厂的优缺点
(1)简单工厂的优点
a、帮助封装:虽然简单,有好帮助我们实现组件的封装,组件外部能够真正的面向接口编程。
b、解耦:客户端和具体实现类之间的解耦,客户端根本不知道具体是由谁来实现的,也不知道具体如何实现,只是
通过工厂获取接口对象。
(2)简单工厂的缺点
a、可能增加客户端的复杂度,客户端通过参数选择具体的实现类,必须让客户端了解各个参数所代表的具体功能和
含义,会增加使用难度,部分暴露内部实现。
b、不方便扩展子工厂,将工厂类的构造函数设为私有使用静态方法创建接口。通常情况下,不需要为简单工厂创建
子类
c、当新增加接口的实现类时,必须修改工厂类的代码,不符合开闭原则。
d、所有产品都是由一个工厂创建,工厂类的职责较重,业务逻辑较复杂,具体产品与工厂类之间的耦合度高,严重
影响系统灵活性和扩展性。
3、何时选择简单工厂
(1)完全封装隔离具体的实现,让外部通过接口操作封装。可以选用简单工厂,让客户端通过工厂获取相应的接口,
而无须关心具体的实现
(2)如果想把创建对象的职责集中管理控制,可选择简单工厂。
实例分析:简单工厂实现计算器
//创建型模式:简单工厂模式
#include <iostream>
using namespace std;
//运算类(其他的加减乘除类从这里继承)
class COperator
{
protected:
double mFirst;
double mSecond;
public:
void setFirst(double obj) { mFirst = obj; }
double getFirst(double obj) { return mFirst; }
void setSecond(double obj) { mSecond = obj; }
double getSecond(double obj) { return mSecond; }
virtual double getResult() { return 0; }
};
class CAdd : public COperator
{
public:
double getResult() { return mFirst + mSecond; }
};
class CSub : public COperator
{
public:
double getResult() { return mFirst - mSecond; }
};
class CMul : public COperator
{
public:
double getResult() { return mFirst * mSecond; }
};
class CDiv : public COperator
{
public:
double getResult()
{
double p = 0.000000001;
if (mSecond < p && mSecond > p) //除数不能为0
{
cout << "除数为零..." << endl;
return 0;
}
else
{
return mFirst / mSecond;
}
}
};
class CSimpleFactory
{
public:
/**
*创建具体运算实现类对象的方法
*@参数:从外部传入的选择条件(+、-、*、/)
*@返回值:创建好的运算实现类对象
*/
//将创建函数定义为静态成员函数,可以让客户端省去创建工厂类对象
static COperator* createOperator(char coperator)
{
COperator* obj = NULL;
switch (coperator) //根据客户端传入的参数选择具体的实现类
{
case '+':
obj = new CAdd();
break;
case '-':
obj = new CSub();
break;
case '*':
obj = new CMul();
break;
case '/':
obj = new CDiv();
break;
default:
break;
}
return obj;
}
};
int main()
{
COperator*obj = CSimpleFactory::createOperator('+');
obj->setFirst(10);
obj->setSecond(101);
double value = obj->getResult();
cout << "value = " << value << endl;
delete obj;
cin.get();
return 0;
}