C++设计模式新解三 简单工厂 工厂模式 抽象工厂

来源:互联网 发布:票乎为什么停止运营 编辑:程序博客网 时间:2024/04/24 10:59

先对比看两段代码

//水杯类,定义了一些功能  class Cup{     };  //玻璃杯  class GlassCup : public Cup{};//钢杯  class SteelCup: public Cup{};

下面就是重点了:

如果是 简单工厂 那么工厂的实现代码就是:

//简单工厂类  class SimpleFactory  {     public:   static Cup* CreateCup(int type)     {  Cup* result = NULL;  switch (type) //判断选择要创建对象的类型  {   case 1:     result = new GlassCup();     break;  case 2:     result = new SteelCup();     break;  }  return result;  }  };

如果是工厂

//工厂  class IFactory //定义一个接口,实现创建杯子类的功能  {  public:virtual Cup* CreateCup() = 0;  };  class GlassFactory : public IFactory//玻璃工厂  {  public:virtual Cup * CreateCup()  {  return new GlassCup();  }  };  class SteelFactory: public IFactory//钢铁工厂  {  public: virtual Cup * CreateCup()  {  return new SteelCup();  }  };int main(){IFactory * f1 = new GlassFactory();Cup* c1 = f1->CreateCup();IFactory * f2 = new SteelFactory();Cup* c2 = f2->CreateCup();system("Pause");}



从上面我们可以看到,简单工厂里把继承水杯接口的真实角色的创建放在了一个工厂里,每添加一个新的真实角色,就要修改简单工厂的工厂代码。

而工厂则同样封装了真实角色的创建过程,但把不同的真实角色放在了不同的工厂里创建,每添加一个新的真实角色,新加一个继承了工厂接口的工厂类就可以了。

符合OCP原则。对修改关闭,对扩展开放。

何时使用简单工厂模式:

(这里值是使用简单工厂模式)举个更实际例子,比如你写了个应用,里面用到了数据库的封装,你的应用可以今后需要在不同的数据库环境下运行,可能是oracle,db2,sql server等,那么连接数据库的代码是不一样的,你用传统的方法,就不得不进行代码修改来适应不同的环境,非常麻烦,但是如果你采用工厂类的话,将各种可能的数据库连接全部实现在工厂类里面,通过你配置文件的修改来达到连接的是不同的数据库,那么你今后做迁移的时候代码就不用进行修改了。

Server.ini

GameWorld = 12
TryCatch = 0
InterStub = 0
InterGateway = 0
InterCache = 0
WorldServerIP = 127.0.0.1
WorldServerPort = 9401
WorldClientPort = 9402
UpdateServerIP = 127.0.0.1
UpdateServerPort = 9404
GatewayServerIP = 127.0.0.1
GatewayServerPort = 8701
GatewayClientPort = 9701
CacheServerIP = 127.0.0.1
CacheServerPort = 7701
AutoStartManagerConnect = 0
ManagerServerIP = 127.0.0.1
ManagerServerPort = 28701
FixQueue = 0
AdjustQueue=1


比如 读取到第一个GameWorld = 1 怎样处理等,相当于传的那个 which参数了。


抽象工厂模式代码:

// 水壶class Kettle{}//玻璃水壶class GlassKettle: public Kettle{}//铁水壶class SteelKettle: public Kettle{}

如果那么就要在工厂接口里,

//工厂  class IFactory //定义一个接口,实现创建杯子类的功能  {  public:virtual Cup* CreateCup() = 0;         virtual Cup* CreateKettle() = 0; };  class GlassFactory : public IFactory//玻璃工厂  {  public:virtual Cup * CreateCup()  {  return new GlassCup();  }          virtual Cup * CreateCup()  {  return new GlassKettle();  }  };  class SteelFactory: public IFactory//钢铁工厂  {  public: virtual Cup * CreateCup()  {  return new SteelCup();  }         virtual Kettle * CreateKettle()       {               return new SteelKettle();       };}


大家注意这里最重要的一点是什么,不同的工厂真实对象里有相同的原料,没错 无论是玻璃水杯,玻璃水壶,玻璃花瓶 用的原料都是玻璃。

这就是抽象工厂中不同的函数之间的耦合关系。而工厂模式则没有这种耦合关系。因为一个工厂里只生产一种产品,无所谓耦合不耦合。



大部分抽象工厂模式都是这样的:
---它的里面是一堆工厂方法,每个工厂方法返回某种类型的对象。

比如说工厂可以生产鼠标和键盘。那么抽象工厂的实现类(它的某个具体子类)的对象都可以生产鼠标和键盘,但可能工厂A生产的是罗技的键盘和鼠标,工厂B是微软的。

这样A和B就是工厂,对应于抽象工厂;
每个工厂生产的鼠标和键盘就是产品,对应于工厂方法;

用了工厂方法模式,你替换生成键盘的工厂方法,就可以把键盘从罗技换到微软。但是用了抽象工厂模式,你只要换家工厂,就可以同时替换鼠标和键盘一套。如果你要的产品有几十个,当然用抽象工厂模式一次替换全部最方便(这个工厂会替你用相应的工厂方法)

所以说抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线
----------------

有人做如下的比较:工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类只能创建一个具体产品类的实例。抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类可以创建多个具体产品类的实例。区别:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂模式是对具体产品进行扩展,有的项目可能需要更多的扩展性,要对这个“工厂”也进行扩展,那就成了“抽象工厂模式”。
本文参考:
http://baike.baidu.com/view/1306799.htm
http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/06/2579100.html
http://zhidao.baidu.com/question/56572039.html?
http://zhidao.baidu.com/link?url=gPlMaK_UQogcLh27dxuY13bK24myNbPa_5sYRluAId30Oj1wxKs_AmPRKLChhvyvWRiAkvHxOrc9DXkoZLpuDJ7UPoEP1AtTUNHzvwK0alyqbl=relate_question_0&word=%B9%A4%B3%A7%C4%A3%CA%BD%20%BC%F2%B5%A5%B9%A4%B3%A7
http://blog.csdn.net/lishuangzhe7047/article/details/8491269



0 0