[设计模式]创建模式-工厂模式(C++描述)
[设计模式]创建模式-工厂模式(C++描述)
second60 20180424
1. 什么是创建者模式
创建模式是设计模式中三类之一,主要是为了对象的创建而产生的一系列设计模式。
包括:
a) Factory Pattern: 工厂模式
b) AbstartFactory: 抽象工厂
c) Singleton:单例
d) Builder:创建者
e) Prototype:原型模式
这五类创建者模式都很常用,至少在我做过的项目中,都见遇到过。最常用的有:单例,工厂,抽象工厂。
下面我会一个一个详细介绍,并写下自已的经验。
2. 什么是Factory Pattern
2.1 由例子引发
例子:某工厂造出了A类机器人,名字为RobotA,不久,又造出了B类机器人,名字为RobotB,后面还会造出不同类型的机器要,C,D,E,F.....
分析:
a) 在面向对象中,通常会做的第一件事就是把类进行抽象,形成抽象基类,抽象父类。
对上面的机器人抽象,抽象类为Robot,子类分别为:RobotA,RobotB
b) 继续分析,工厂可以造机器人,但造什么类型的机器人是不清楚的,要看上级的具体安排。因此,名为工厂的类RobotFactory,可以先产机器人。
总结,工厂模式
1. 创建对象的接口
2. 使得具体化类延迟到子类中。
2.2 简单工厂模式
工厂类:生产产品 RobotFactory
产品抽象类: Robot
具体产品类:RobotA RobotB
图我这里就不画了,没装rose,百度搜一个。
为了代码易看,就不分头和内容了,只要看懂了就OK:
// 抽象机器人类
class Robot
{
public:
Robot(){}
virtual ~Robot() = 0; // virtual一定要加,我就不多解释了
};
// 实体机器人A
class RobotA:public Robot{};
// 实体机器人B
class RobotB:public Robot{};
// 新加机器人C
class RobotC:public Robot{};
// 机器人工厂类:专门用来生产机器人
class RobotFactory
{
public :
Robot* createRobot(int robotType)
{
Robot * robotPtr = NULL:
switch(robotType)
{
case 1:robotPtr = new RobotA();
case 2:robotPtr = new RobotB();
case 3:robotPrt = new RobotC();// 新加机器人C
}
return robotPtr;
}
};
简单工厂写完了,说说他的优缺点吧
2.2.1优点:
1. 抽象出了产品类,后续新加新产品,只需增加一个类并继承即可
2. 工厂类提供了一个生产产品的地方,具体生产什么产品,由延迟子类决定
曾通做法,没有工厂类:
Robot* robotA = new RobotA();
Robot* robotB = new RobotB();
Robot* robotC = new RobotC();
没有工厂类,那么使用对象的人,需要关心具体是什么子类,要知道子类的名字叫什么。
但有工厂类的好处:
RobotFactory * factoryPtr = new RobotFactory();
Robot* robotA = factoryPtr.createRobot(EROBOT_A);
Robot* robotB = factoryPtr.createRobot(EROBOT_B);
Robot* robotC = factoryPtr.createRobot(EROBOT_C);
这样开发人员无须知道子类的名字,无须关心子类是什么样的。只需关心我创建出来的是机器人就OK了, 至于想创建什么样的机器人,由开发人员自已决定,。
2.2.2缺点:
1. 如果新加一个机器人C,是要修改工厂类滴createRobot,如果工厂类是一个公共部份,那么改动将会影响到其他的对象创建,至少测试时,要把之前涉及的用例都测一随。
上面代码红色部分为新加一个机器人C
有什么办法来避象简单工厂的缺点呢,就是不用改动任何代码,新增机器人也没问题呢。答安是当然有,就是升级版工厂模式。
2.3 进阶处工厂模式
怎么样来避免简单工厂新增机器人会改动到工厂类的办法呢?其实也就是不用在更改任何之前代码的情况下,新加机器人C,机器人D....
答案很简单:抽象啊!!!!(学设计模式的目的之一)
是的,我们再把工厂类抽象出来。
进阶工厂模式图(百度的):
其他的不变,只是把Factory类抽象了出来,具体的工厂,由具体的工厂实现类去做。
代码如下:
// 抽象机器人类
class Robot
{
public:
Robot(){}
virtual ~Robot() = 0; // virtual一定要加,我就不多解释了
};
// 实体机器人A
class RobotA:public Robot{};
// 实体机器人B
class RobotB:public Robot{};
// 把机器人工厂类抽象出来
class RobotFactory
{
public :
RobotFactory(){}
virtual ~RobotFactory() = 0;
virtual Robot* createRobot() = 0;
};
// 生产机器人A的工厂
class RobotFactoryA: public RobotFactory
{
public:Robot* createRobot(){return new RobotA();}
};
// 生产机器人B的工厂
class RobotFactoryB: public RobotFactory
{
public:Robot* createRobot(){return new RobotB();}
};
// 新加机器人C
class RobotC:public Robot{};
// 生产机器人C的工厂
class RobotFactoryC: public RobotFactory
{
public:Robot* createRobot(){return new RobotC();}
};
int main()
{
// 机器人A在A工厂生产
RobotFactory *factoryA = new RobotFactoryA();
Robot *robotA = factoryA.creatRobot();
// 机器人B在B工厂生产
RobotFactory *factoryB = new RobotFactoryB();
Robot *robotB = factoryB.creatRobot();
// 新加机器人C在C工厂生产
RobotFactory *factoryC = new RobotFactoryC();
Robot *robotC = factoryC.creatRobot();
//delete 不写了
}
2.3.1 优点
a) 扩展和维护性好:新增机器人,无须再修改原逻辑,上面红色部份(是不是很强大,没有修改任何逻辑,只加了机器人C,和工厂C,就可以支持新的机器人了,这就是设计模式的强大之处了)
2.3.2 缺点
a) 需要增加一个新工厂类的代价,如果产品很多,工厂类也会很多。当然,你也可以只有一个工厂类,在工厂类里创建不同机器人,新加不同方法。但这又回归到简单工厂了。
2.4 总结
工厂模型是创建模型的一种。
工厂模型的好处:
1. 具产品抽象化
2. 延迟了子类的实例化
3. 易用性:开发者无须关心具体的产品,只需用工厂生产即可
4. 易扩展,易维护:进阶工厂模型,可以不改任何代码的情况下,新增产品
工厂模型的局限性:
1. 只能对一类产品进行创建
3 后话
这里举了上机器人创建的举子,是我随时发挥的一个例子。我也不知道自已写的是不是很明白,尽量很简单的写,让人明白,为什么会有工厂模式,工厂模式的好处是什么,同时,让人了解设计模式的强大的特点,抽象化,可扩展,可维护。后续继讲抽象工厂模式,能解决工厂模式的局限性问题。
夜深了,人更静了。