工厂模式:
工厂模式分为三种 : 简单工厂模式,工厂方法模式,抽象工厂模式。
《Head First 设计模式》中把以上三种合并成了一章,《Java与模式》中则是分了三章。前者认为简单工厂模式并不是一个设计模式更像是一种编程习惯,但是后者还是给了简单工厂模式较长的篇幅。这篇为简单工厂模式。
定义
简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂类决定创建出哪一种产品类的实例。
(工厂类负责处理创建产品对象的细节,产品的创建对于客户端来说是透明的,客户端只需用产品就行,不需要知道产品是怎么来的)。
(这里的"静态工厂方法"按我的理解,因为这个工厂类和方法是在编译期就已经确定了,这也是"简单工厂"相对后面的"工厂方法模式"的一个缺点)。
结构与角色
工厂类(Factory)角色 : 此类是简单工厂模式的核心。客户端直接调用此类创建产品。(一般此角色是一个具体类,和一个静态方法)
抽象产品(Product)角色 : 所有产品的父类,定义产品的行为,抽象类或接口(当子类有相同的逻辑时,可以使用抽象类,将子类的相同逻辑上移实现代码重用,否则使用接口)。
具体(ConcreteProduct)产品角色 : 实现抽象产品,是一个具体类。
package ds.factory.sf; public interface Product { void operation(); }
package ds.factory.sf; public class ConcreteProduct implements Product { @Override public void operation() { System.out.println("ConcreteProduct operation..."); } }
package ds.factory.sf; public class Factory { public static Product factory(String type) { // 当多个产品时用type判断创建某个产品 return new ConcreteProduct(); } }
package ds.factory.sf; public class Client { public static void main(String[] args) { Product product = Factory.factory(""); product.operation(); } }
优缺点
简单工厂模式的优点是断掉了客户端和产品之间的耦合,因为产品在应用中一般都是可变的,使用工厂其实就是封装变化的体现。当产品发生改变时客户端不受影响。这也是开闭原则的一个体现,只不过简单工厂模式并没有完全实现开闭原则,当产品发生变化时,工厂类的方法是要改变的。
工厂类集中了所有的产品创建逻辑,形成一个无所不知的全能类,(上帝类 God Class)。随着产品的增多这个类的逻辑也就更复杂,也就更容易出现问题。
应用
java.text.DateFormat
(静态工厂方法是为了将具体子类实例化的工作隐藏起来,从而客户端不必考虑如何将具体子类实例化,因为抽象类DateFormat 会提供它的合适的具体子类的实例。这是简单工厂方法模式的绝佳应用)
XMLReaderFactory
Spring 框架的工厂
当只有一个产品时,采用简单工厂模式,使用工厂类来隐藏具体产品的创建细节。