分类
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式在《Java 与模式》中分为三类:
1)简单工厂模式(Simple Factory)
2)工厂方法模式(Factory Method)
3)抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF 在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
两者皆可,在本篇使用《Java 与模式》的分类方法。
简单工厂模式
简单工厂模式又称静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。
先来看看它的组成:
1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。
2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。
3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。
例子:
1.抽象茶角色
public interface Tea { public void method(); }
2.具体茶品种角色
public class GreenTea implements Tea { @Override public void method() { System.out.println("I'm GreenTea!"); } } public class BlackTea implements Tea { @Override public void method() { System.out.println("I'm BlackTea!"); } }
3.工厂类角色
public class SimpleFactory { public IProduct produce(String type) { if("GreenTea".equals(type)) { return new GreenTea(); } else if("BlackTea".equals(type)) { return new BlackTea(); } else { System.out.println("没有你要的品种"); return null; } } }
4.测试类
public class MainTest { public static void main(String args[]) { SimpleFactory factory = new SimpleFactory(); Tea tea = factory.produce("GreenTea"); tea.method(); } }
输出:I’m GreenTea!
在Java中java.text.DateFormat就是简单工厂模式的典型案例。
优点:专门定义一个工厂类负责创建其他类的实例,最大的优点在于工厂类中包含了必要的逻辑,根据客户需要的条件动态实例化相关的类。
缺点:当需要增加一种产品时,比如ProductC就需要修改简单工厂类SimpleFactory(增加if-else块),这违背了开闭原则。
TIPS
其实如果采用反射机制实现简单工厂并没有违背开闭原则。
利用反射机制,将简单工厂类改成:
public class SimpleFactory { public Tea buy(Class<? extends Tea> c) throws Exception { return (Tea)Class.forName(c.getName()).newInstance(); // return (Tea)c.newInstance(); // 或者采用这种方法 } }
测试类:
public class MainTest { public static void main(String args[]) throws Exception { SimpleFactory factory = new SimpleFactory(); Tea tea = factory.buy(GreenTea.class); tea.method(); } }
这样当有新的产品时,其实并不需要修改工厂类。《Effective Java(Second Edition)》中明确指出:通常,普通应用程序在运行时不应该以反射方式访问对象。所以本篇文章建立在不采用反射机制的情况下,在下面介绍的工厂方法模式其实也可以改用反射机制实现,博主就不展示了。至于《Effective Java(Second Edition)》为什么不推荐反射机制,可以参考此书的“接口优先于反射机制”这一主题。
工厂方法模式
工厂方法模式是简单工厂模式的进一步抽象化和推广,工厂方法模式里不再只由一个工厂类决定那一个产品类应当被实例化,这个决定被交给抽象工厂的子类去做。