工厂方法
在任何需要生成复杂对象的地方,都可以使用工厂方法模式,复杂对象适合使用工厂方法模式,用 new 就可以完成创建的对象无需使用工厂方法模式。
优点:降低了对象之间的耦合度,工厂模式依赖于抽象的架构,其将实例化的任务交由子类去完成,有非常好的扩展性。
缺点:每次为工厂方法添加新的产品时就要编写一个新的产品类,同还要引入抽象层,必然会导致代码类结构的复杂化。
工厂方法模式的通用模式代码如下:
抽象工厂方法(核心),具体生产什么由子类去实现:
123public abstract class Factory {public abstract Product createProduct();}具体工厂类(实现了具体业务逻辑):
1234567public class ConcreteFactory extends Factory{public Product createProduct() {return new ConcreteProductA(); // 返回具体的产品对象//return new ConcreteProductB(); // 返回具体的产品对象}}抽象产品类,由具体的产品类去实现:
123public abstract class Product {public abstract void method();}具体产品类(包含ConcreteProductA、ConcreteProductB等):
123456789101112public class ConcreteProductA extends Product {public void method() {System.out.println("ConcreteProductA method");}}public class ConcreteProductB extends Product {public void method() {System.out.println("ConcreteProductB method");}}测试程序:
123456public void factoryTest() throws Exception {Factory factory = new ConcreteFactory();Product product = factory.createProduct();product.method();}
输出:ConcreteProductA method
这种方式比较常见,需要哪个就生产哪个,有时候还可以利用反射的方式更加简洁地来生产具体产品对象,此时,需要在工厂方法的参数列表中传入一个 Class 类来决定是哪一个产品类:
对应的具体工厂类则通过反射获取类的实例即可:
再看一下测试代码的实现:
输出:
ConcreteProductA method
ConcreteProductB method
需要哪个类的对象传入哪一个类即可,这种方法比较简洁、动态。如果不喜欢这一种,也可以尝试为每一个产品都定义一个具体的工厂,各司其职,像拥有多个工厂的方式我们称为多工厂方法模式,同样当我们的工厂类只有一个的时候,我们还可以简化掉抽象类,只需要将对应的工厂方法给为静态方法即可:
源码中的应用
工厂方法模式应用很广泛,开发中使用到的数据结构中就隐藏着对工厂方法模式的应用,例如 List、Set,List、Set 继承自 Collection 接口,而 Collection 接口继承于 Iterable 接口:
这意味着 List、Set 接口也会继承 iterator() 方法,下面以 ArrayList 为例进行分析:
ArrayList 中 iterator() 方法的实现就是构造并返回一个迭代器对象:
其中的 iterator() 方法其实就相当于一个工厂方法,专为 new 对象而生,构造并返回一个具体的迭代器。
其实Android中对工厂方法模式的应用更多,先看如下代码:
实际上,onCreate方法就相当于一个工厂方法,因为LinearLayout是一个ViewGroup,而ViewGroup又继承于View,简单地说,所有控件都是View的子类。在AActivity的onCreate方法中构造一个View对象,并设置为当前的ContentView返回给framework处理,如果现在又有一个BActivity,这时又在onCreate方法中通过setContentView方法设置另外不同的View,这是不是一个工厂模式的结构呢,其实设计模式离我们非常近!!!