工厂方法模式(Factory method)

  在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。

  工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。工厂方法定义一个用于创建对象的接口,但是让子类决定实例化哪个类。压注成型演示了这种模式。塑料玩具制造商加工塑料粉,将塑料注入到希望形状的模具中。玩具的类别(车,人物等等)是由模具决定的。

  在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。  

工厂模式在《Java与模式》中分为三类:

  1)简单工厂模式(Simple Factory):不利于产生系列产品。

  2)工厂方法模式(Factory Method):又称为多形性工厂。

  3)抽象工厂模式(Abstract Factory):又称为工具箱,产生产品族,但不利于产生新的产品。

  这三种模式从上到下逐步抽象,并且更具一般性。

  GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

  二、简单工厂模式

  简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。

  在简单工厂模式中,一个工厂类处于对产品类实例化调用的中心位置上,它决定那一个产品类应当被实例化, 如同一个交通警察站在来往的车辆流中,决定放行那一个方向的车辆向那一个方向流动一样。

  先来看看它的组成:

  1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。

  2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。

  3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

  三、工厂方法模式

  工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。来看下它的组成:

  1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

  2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

  3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

  4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。

  工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代 码。可以看出工厂角色的结构也是符合开闭原则的! 代码:

 1 //抽象产品角色
 2  2 public interface Moveable {
 3  3     void run();
 4  4 }
 5  5 //具体产品角色
 6  6 public class Plane implements Moveable {
 7  7     @Override
 8  8     public void run() {
 9  9         System.out.println("plane....");
10 10     }
11 11 }
12 12 public class Broom implements Moveable {
13 13     @Override
14 14     public void run() {
15 15         System.out.println("broom.....");
16 16     }
17 17 }
18 18 //抽象工厂
19 19 public abstract class VehicleFactory {
20 20     abstract Moveable create();
21 21 }
22 22 //具体工厂
23 23 public class PlaneFactory extends VehicleFactory{
24 24     public Moveable create() {
25 25         return newPlane();
26 26     }
27 27 }
28 28 
29 29 public class BroomFactory extends VehicleFactory{
30 30     public Moveable create() {
31 31         return new Broom();
32 32     }
33 33 }
34 34 //测试类
35 35 public class Test {
36 36     public static void main(String[] args) {
37 37         VehicleFactory factory=new BroomFactory();
38 38         Moveable m=factory.create();
39 39         m.run();
40 40     }
41 41 }

  可以看出工厂方法的加入,使得对象的数量成倍增长。当产品种类非常多时,会出现大量的与之对应的工厂对象,这不是我们所希望的。因为如果不能避免这种情 况,可以考虑使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类:即对于产品树上类似的种类(一般是树的叶子中互为兄弟的)使用简单工厂模式来实现。

四、简单工厂和工厂方法模式的比较

  工厂方法模式和简单工厂模式在定义上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类,而不像简单工厂模式, 把核心放在一个实类上。工厂方法模式可以允许很多实的工厂类从抽象工厂类继承下来, 从而可以在实际上成为多个简单工厂模式的综合,从而推广了简单工厂模式。

  反过来讲,简单工厂模式是由工厂方法模式退化而来。设想如果我们非常确定一个系统只需要一个实的工厂类, 那么就不妨把抽象工厂类合并到实的工厂类中去。而这样一来,我们就退化到简单工厂模式了。

  五、抽象工厂模式

  代码:

 1 //抽象工厂类
 2 public abstract class AbstractFactory {
 3   public abstract Vehicle createVehicle();
 4   public abstract Weapon createWeapon();
   5 public abstract Food createFood();
 6 }
 7 //具体工厂类,其中Food,Vehicle,Weapon是抽象类,
 8 public class DefaultFactory extends AbstractFactory{
 9   @Override
10   public Food createFood() {
11     return new Apple();
12   }
13   @Override
14   public Vehicle createVehicle() {
15     return new Car();
16   }
17   @Override
18   public Weapon createWeapon() {
19     return new AK47();
20   }
21 }
22 //测试类
23 public class Test {
24   public static void main(String[] args) {
25     AbstractFactory f=newDefaultFactory();
26     Vehicle v=f.createVehicle();
27     v.run();
28     Weapon w=f.createWeapon();
29     w.shoot();
30     Food a=f.createFood();
31     a.printName();
32   }
33 }

  在抽象工厂模式中,抽象产品 (AbstractProduct) 可能是一个或多个,从而构成一个或多个产品族(Product Family)。 在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。

  六、总 结

  (1)简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的。

  (2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。

  (3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。  

posted @ 2012-11-25 12:06  beanmoon  阅读(317)  评论(0编辑  收藏  举报