简单工厂模式虽然不在GOF的23种设计模式中提到,却被广泛地运用。简单工厂模式的最大优点是去除了客户端与具体产品的依赖,因为工厂类中包含了需要的逻辑判断,
虽然简单工厂违背了开闭原则,但是保持了封装对象创建过程的优点。
可以说工厂方法模式是简单工厂模式的进一步抽象和推广,也可以说简单工厂模式是工厂方法模式的简化。对于多态的进一步使用,工厂方法模式在保留简单工厂模式优点
的同时,也克服了它的缺点。工厂方法模式也有其缺点,每增加一个产品,就要添加一个产品工厂类,增加了额外的开发量。
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式适用的地方大致有以下3点:
- 当一个类不知道它所必须创建的对象的类时,比如要创建一个白面包对象,但是并不知道它的类WhiteBread。
- 当一个类希望由它的子类来指定它所创建的对象时。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化时。 对于是选择工厂方法模式和简单工厂模式,要取决与具体的应用。正如从两个模式的名称就可以看出,对于一些比较简单的应用,“产品”比较少时,使用简单工厂模式就可以 满足要求。而对于“产品”比较丰富的应用,过多的分支不利于程序的维护,这时应该选择工厂方法模式来降低程序的维护量。
在开发一个类时,开发人员通常都需要给一个类编写对应的构造函数,这样一来,使用这个类的人员就可以通过构造函数来对这个类进行实例化。
但是有时也会发生这种情况:需要使用某个对象的人员并不知道对一些类中的哪些类进行初始化。解决这个问题的方式就是使用工厂方法模式来定义一个接口,其他开发者
就可以使用这个接口来创建一个对象。这样做的另外一个好处就是可以控制对哪些类进行实例化。
工厂方法模式在开发中经常被使用到,尤其是在我们不希望使用者知道应该对哪几个类进行实例化操作时,工厂模式可以大展身手。那么为什么我们不希望使用者知道应该对
哪些类进行实例化呢?原因很简单,那就是这个类的实例化过程需要以来某些其它的因素。
一个方法可以创建出新的对象,但这并不意味着它就是工厂方法模式的体现。因为工厂方法模式需要包含这样一个操作,即这个操作可以创建一个对象,同时也会使使用者不需要去了解具体实例化哪一个类。
定义:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。
抽象工厂模式适用于以下情况:
- 一个系列要独立它的产品的创建、组合和表示时。
- 一个系统要由多个产品系列中的一个来配置时。
- 当要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当要提供一个产品类库,而只要显示它们的接口而不是实现时。 抽象工厂适用于客户端经常需要切换配置(交换产品系列)时,客户端通过抽象接口来操纵实例,具体的类名不会出现在客户端中。
简单工厂模式比较简单,优点如下:
- 分离了客户端和后台逻辑,使得客户端毋须关心后台的实现,去除了客户端与具体产品的依赖,增强了移植性。
- 实现简单,易于操作。
缺点:
- 违背了开放-封闭原则。
- 添加新的产品是比较麻烦。
工厂方法模式是简单工厂模式的升级,优点如下:
- 易于添加新产品。
- 后台模块契合了开放-封闭原则。
其缺点也是显而易见的:
- 新产品的添加带来了大量的新的类的创建,增加了工作量。
- 客户端部分仍然违反了开放-封闭原则,只是后台判断逻辑移到了前端。
而抽象工厂模式可以说是工厂方法模式的升级,也算是工厂方法模式的一种变种,其优点如下:
- 分离了具体的类,工厂封装了创建产品对象的责任和过程,将客户端和类的实现分离,客户端通过抽象接口操纵实例。
- 易于交换产品系列,一个具体的工厂类在一个应用中仅在初始化时出现一次。
- 有利于产品的一致性,一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一系列中的对象。
缺点:
- 难以支持新种类的产品,抽象工厂接口确定了可以被创建的产品集合。新种类产品的加入需要扩展抽象工厂接口,这就涉及了接口本身和实现类的改变。(利用反射技术可以解决)