楔子
学习
《设计模式之禅(第2版)》
笔记。
定义
定义一个用于常见对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类
工厂类的通用类图
工厂方法模式优点
# 1 降低了模块间的耦合。
# 2 工厂方法模式的扩展性非常优秀
# 3 工厂方法模式是典型的解耦框架
使用场景
# 1 工厂方法模式是new一个对象的替代品,因此在所有需要生产对象的地方都可以使用。(但是要慎重考虑增加一个工厂类进行管理带来的代码复杂度)
# 2 可以用在灵活可扩展的框架。
# 3 工厂方法模式可以用在异构项目中,例如WebService与非JAVA项目的交互。
工厂方法模式的扩展
工厂方法模式扩展很多,而且与其他摸手结合使用威力更大。下面介绍4中扩展。
1 缩小为简单工厂模式(静态工厂模式)
一个模块紧需要一个工厂类,没必要把它生产出来,使用静态的方法就可以了。但是其缺点是工厂扩展比较困难,不符合开闭原则。
2 升级为多个工厂类
遇到初始化一个对象很耗费精力的情况,所有的产品类放到一个工厂中进行初始化会使代码结构不清晰。例如:一个产品类有5个具体实现,每个实现的初始化都不相同,写在一个工厂方法中,势必导致该方法巨大无比。
考虑需要结构清晰,我们为每个产品定义一个创造者,然后由调动者决定去哪个工厂方法关联。
3 替代单例模式
public class SingleFactory {
private static Singleton singleton;
static {
try {
Class cl = Class.forName(Singleton.class.getName());
// 获得无参构造函数
Constructor constructor = cl.getDeclaredConstructor();
// 设置无参构造函数为可访问
constructor.setAccessible(true);
singleton = (Singleton) constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Singleton getSingleton() {
return singleton;
}
}
4 延迟初始化
public class ProductFactory {
private static final Map<String, Product> prMap = new HashMap<String, Product>();
public static synchronized Product createProduct(String type) throws Exception {
Product product = null;
if (prMap.containsKey(type)) {
product = prMap.get(type);
} else {
if (type.equals("pro1")) {
product = new ConcreProduct1();
} else {
product = new ConcreProduct2();
}
}
return product;
}
}
一个对象被消费完毕后,并不会立刻释放,工厂类保持其初始化状态,等待再次被使用,延迟初始化是工厂方法模式的一个扩展应用。
延迟加载对象可以降低对象的产生和销毁带来的复杂性。