简单工厂、工厂、抽象工厂

来源:互联网 发布:as3程序员到底是什么 编辑:程序博客网 时间:2024/04/28 13:29

简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式,属于类的创建型模式。

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

意图:提供一个类,由它负责根据一定的条件创建某一具体类的实例

角色及其职责:

  • 工厂(Creator)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
  • 抽象(Product)角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
  • 具体产品(Concrete Product)角色:简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。一般来讲它是抽象产品类的子类,实现了抽象产品类中定义的所有接口方法。

模式的特点:

  • 优点:简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
  • 缺点:体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以"高内聚"方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

 

 

工厂方法模式 工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作推延到其子类去完成。

意图:定义一个用户创建对象的接口,让子类决定实例化哪一个类,工厂方法模式使一个类的实例化延迟到其子类。

优点:实现了开闭原则,可以在不改变工厂的前提下增加新产品。

实现要点:

  • Factory Method模式的两种情况:一是Creator类是一个抽象类且它不提供它所声明的工厂方法的实现;二是Creator是一个具体的类且它提供一个工厂方法的缺省实现。
  • 工厂方法是可以带参数的。
  • 工厂的作用并不仅仅只是创建一个对象,它还可以做对象的初始化,参数的设置等。

效果:

  • 用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。
  • Factory Method模式通过面向对象的手法,将所要创建的具体对象的创建工作延迟到了子类,从而提供了一种扩展的策略,较好的解决了这种紧耦合的关系。

适用性:

  • 当一个类不知道它所必须创建的对象的类的时候。
  • 当一个类希望由它的子类来指定它所创建的对象的时候。
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

附注

  • 基类是一个抽象类,模式必须返回一个完整的可工作的类
  • 基类包含默认方法,除非这些默认方法不能胜任才调用子类方法
  • 可以讲参数传递给工厂,告诉工厂返回哪一个类。

 

 

抽象工厂模式提供创建对象的接口。与工厂方法类似,但此处返回的一系列相关产品。实现过程同样推延到子系列类去实现。与工厂方法的区别在于他们的层次模型。工厂方法的抽象基类只有儿子,而抽象工厂模式却是有孙子,而且每个儿子的儿子们之间有相互关联依赖关系。

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

角色及职责

  • 抽象工厂(Abstract Factory):声明生成一系列抽象产品的方法
  • 具体工厂(Concrete Factory):执行生成一系列抽象产品的方法,生成一系列具体的产品
  • 抽象产品(Abstract Product):为这一系列的某一种产品声明接口
  • 具体产品(Product):定义具体工厂生成的具体产品的对象,实现产品接口
  • 客户(Client):我们的应用程序客户端(不要理解成人),使用抽象产品和抽象工厂生成对象。

 

附注:简单工厂、工厂方法、抽象工厂比较

简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。

  • 简单工厂:简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。不修改代码的话,是无法扩展的。
  • 工厂方法:工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。
  • 抽象工厂:抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品

小结

  • 工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。

 

区别:

  • 简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
  • 工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)  
  • 抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)  

以上三种工厂方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

 

转载自http://www.cnblogs.com/BLoodMaster/archive/2010/03/01/1675856.html,感谢作者的辛勤劳动

如有任何不同的见解,请留言,如果在下还会喘气,会尽快给您答复

 

示例代码

待生成类

enum CoreType{coreA = 0, coreB = 1};class CSinglecore{private:CSinglecore();};class CSinglecoreA:public CSinglecore{public:CSinglecoreA();};class CSinglecoreB:public CSinglecore{public:CSinglecoreB();};class CMulticore{private:CMulticore();};class CMulticoreA:public CMulticore{public:CMulticoreA();};class CMulticoreB:public CMulticore{public:CMulticoreB();};

 

简单工厂模式

class CFactory{public:CSinglecore* CreateSinglecore(CoreType type){CSinglecore* pCore = NULL;if (type == CoreType::coreA)pCore = new CSinglecoreA;else if (type == CoreType::coreB)pCore = new CSinglecoreB;}};


工厂模式

class CFactory{public:virtual CSinglecore* CreateSinglecore() = 0;};class CFactoryA:public CFactory{public:virtual CSinglecore* CreateSinglecore(){CSinglecore* pCore = new CSinglecoreA;return pCore;}};class CFactoryB:public CFactory{public:virtual CSinglecore* CreateSinglecore(){CSinglecore* pCore = new CSinglecoreB;return pCore;}};

 

抽象工厂模式

class CFactory{public:virtual CSinglecore* CreateSinglecore() = 0;virtual CMulticore* CreateMulticore() = 0;};class CFactoryA:public CFactory{public:virtual CSinglecore* CreateSinglecore(){CSinglecore* pCore = new CSinglecoreA;return pCore;}virtual CMulticore* CreateMulticore(){CMulticore* pCore = new CMulticoreA;return pCore;}};class CFactoryB:public CFactory{public:virtual CSinglecore* CreateSinglecore(){CSinglecore* pCore = new CSinglecoreB;return pCore;}virtual CMulticore* CreateMulticore(){CMulticore* pCore = new CMulticoreB;return pCore;}};