工厂方法模式与抽象工厂模式
工厂方法模式
工厂方法模式(Factory Method,别名虚拟构造):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法模式使一个类的实例化延迟到其子类。
工厂模式的结构中包括4种角色:
1.抽象产品(Product):抽象产品是抽象类或接口,负责定义具体产品的规范,即具体产品必须实现的方法。
2.具体产品(ConcreteProduct):如果Product是一个抽象类,那么具体产品是Product的子类;如果Product是一个接口,那么具体产品是实现Product接口的类。具体产品决定了产品在客户端中的行为。
3.构造者(Creator):构造者是一个接口或抽象类。构造者负责定义一个称做工厂方法的抽象方法,该方法返回具体产品类的实例。
4.具体构造者(ConcreteCreator):如果构造者是抽象类,具体构造者是构造者的子类;如果构造者是接口,具体构造者是实现构造者的类。具体构造者覆写工厂方法使该方法返回具体产品的实例。在实际编程中,具体构造者决定如何实例化具体产品,是实现扩展的途径,需要有多少种具体产品,就需要有多少个具体构造者。
工厂方法模式的UML类图如下图所示:
错误纠正(上图中的Creator应该是依赖于Product,所以两者间的连线应该是虚线加箭头)
工厂方法模式代码:
interface Product{ //抽象产品接口,负责定义具体产品必须实现的方法 public abstract void productMethod(); } class ConcreteProduct implements Product{ //具体产品 public void productMethod(){ ......} } interface Creator{ //构造者负责定义一个工厂方法的抽象方法,该方法负责返回具体产品的实例 public abstract Product factoryMethod(); } class ConcreteCreator implements Creator{ //具体构造者覆写了抽象工厂方法使该方法返回具体产品的实例 public Product factoryMethod(){ return new ConcreteProduct(); } } public class Client{ //客户端 public static void main(String args[]){ Creator creator=new ConcreteCreator(); Product product=creator.factoryMethod();//使用工厂方法返回具体产品实例 } }
工厂模式的优点:
1.可以使代码结构清晰,有效的封装变化。在编程中,产品类的实例化有时候是比较复杂和多变的,通过工厂方法模式,将产品的实例化封装起来,使得调用者根本无需关心产品的实例化过程,只需依赖工厂方法即可得到自己想要的产品。
2.对调用者屏蔽具体的产品类。如果使用工厂模式,调用者只关心抽象产品的接口就可以了,至于具体的实现,调用者根本无需关心。即使变更了具体的实现,对调用者来说没有任何影响。
3.降低耦合度。产品类的实例化通常来说是很复杂的,它需要依赖很多的类,而这些类对于调用者来说根本无需知道,如果使用了工厂方法,我们需要做的仅仅是实例化好具体的产品,然后交给调用者使用。对调用者来说,具体产品所依赖的类都是透明的。
工厂方法模式的应用场景:
不管是简单工厂模式,工厂方法模式还是抽象工厂模式,他们具有类似的特征,所以它们的适用场景也是类似的。
1.作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂方法模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂方法模式。如果使用工厂方法模式,就需要引入一个构造者类,会增加系统的复杂度。
2.工厂方法模式是一种典型的解耦模式,如果调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂方法模式,将会大大降低对象之间的耦合度。
3.由于工厂方法模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的具体构造者组装。
典型应用:
参考http://blog.csdn.net/zhengzhb/article/details/7348707
注:本文参考自http://blog.csdn.net/zhengzhb/article/details/7348707以及《面向对象与设计模式》耿祥义 张跃平
抽象工厂模式
抽象工厂模式(别名配套):提供一个创建一系列或相互依赖对象的接口,而无须指定它们具体的类。
抽象工厂模式的结构中包括4种角色:
1.抽象产品(Product):抽象产品是一个抽象类或接口,负责定义具体产品必须实现的方法。
2.具体产品(ConcreteProduct):具体产品是一个类,如果Product是一个抽象类,那么具体产品是Product的子类;如果Product是一个接口,那么具体产品是实现Product接口的类。
3.抽象工厂(AbstractFactory):抽象工厂是一个接口或抽象类,负责定义若干个抽象方法。
4.具体工厂(ConcreteFactory):如果抽象工厂是抽象类,具体工厂就是抽象工厂的子类;如果抽象工厂是接口,具体工厂是实现抽象工厂的类。具体工厂覆写抽象工厂中的抽象方法,使该方法返回具体产品的实例。
抽象工厂模式的UML类图如下图所示:
抽象工厂模式与工厂方法模式的区别
抽象工厂模式是工厂方法模式的升级版,它用来创建一组相关或者相互依赖的对象。
它与工厂方法模式的区别在于:工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品等级结构,表现为一个接口或抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类,如上图中的ProductA和ProductB。
在抽象工厂模式中,有一个产品族的概念,所谓产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成了一个产品族;而工厂方法提供的一系列产品称为一个等级结构。如上图中的ProductA和ProductB称为两个不同的等级结构,ProductA1和ProductA2属于同一个等级结构,ProductB1和ProductB2属于另一个等级结构,而ProductA1和ProductB1属于同一个产品族,ProductA1和ProductB1同属于一个产品族。
如果产品全部属于同一个等级结构(即同一个接口或抽象类),则属于工厂方法模式;如果产品来自多个等级结构(即多个不同的接口或抽象类),则属于抽象工厂模式。
抽象工厂模式的优点
1.抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。产品族一般或多或少的都存在一定的关联,抽象工厂模式就可以在类的内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
2.抽象工厂模式可以为用户创建一系列相关的对象,使得用户和创建这些对象的类脱耦。
3.使用抽象工厂模式可以方便的为用户配置一系列对象。用户使用不同的具体工厂就能得到一组相关的对象,同时也能避免用户混用不同系列中的对象。
4.在抽象工厂模式中,可以随时增加“具体工厂”为用户提供一组相关的对象。
适合使用抽象工厂模式的情景:
1.系统需要为用户提供多个对象,但不希望用户直接使用new运算符实例化这些对象,即希望用户和创建对象的类脱耦。
2.系统需要为用户提供多个相关的对象,以便用户联合使用它们,但又不希望用户来决定这些对象是如何关联的。
3.系统需要为用户提供一系列对象,但只需要用户知道这些对象有哪些方法可用,不需要用户知道这些对象的创建过程。
4.在一个继承体系中,如果存在多少个等级结构(即存在多个抽象类或接口),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,会更适合。
一个抽象工厂模式的例子:
总结
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用 时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需 求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的 提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。
以上参考自http://blog.csdn.net/zhengzhb/article/details/7359385以及《面向对象与设计模式》耿祥义 张跃平