在《Java编程思想》泛型一章中看到了工厂方法模式,就将工厂方法模式作为设计模式的第一个来写吧。
在写工厂方法模式之前,先来看一下简单工厂模式。
简单工厂模式:又称为静态方法工厂模式,是由一个工厂对象决定创建哪一个产品类的实例。
UML类图如下:
简单工厂模式中,在一个简单工厂类SimpleFactory里创建需要的产品。
产品抽象类:
public interface Product {
int getResult(int numA, int numB);
}
具体产品实现类:
public class PlusProduct implements Product {
@Override public int getResult(int numA, int numB) {
return numA + numB;
}
}
public class MinusProduct implements Product {
@Override public int getResult(int numA, int numB) {
return numA - numB;
}
}
简单工厂类:
public class SimpleFactory {
public final static int TYPE_PLUS = 1;
public final static int TYPE_MINUS = 2;
public Product getProduct(int type) {
Product product;
switch (type) {
default:
case TYPE_PLUS:
product = new PlusProduct();
break;
case TYPE_MINUS:
product = new MinusProduct();
break;
}
return product;
}
}
使用:
public class Client {
public static void main(String[] args) {
SimpleFactory factory = new SimpleFactory();
Product plusProduct = factory.getProduct(SimpleFactory.TYPE_PLUS);
int result1 = plusProduct.getResult(10,12);
Product minusProduct = factory.getProduct(SimpleFactory.TYPE_MINUS);
int result2 = minusProduct.getResult(10,12);
}
}
使用时通过,SimpleFactory创建需要的对象,再进行相关的操作。
如果需要增加一个乘法实现类怎么办?就需要修改SimpleFactory,让SimpleFactory支持创建更多的产品实现类。
这其实违反了面向对象的六大原则之一的开放封闭原则。符合开放封闭原则的SimpleFactory应该是对修改封闭的,而对扩展开放。这里增加产品类型的时候,却需要修改SimpleFactory的内部实现。
为了让SimpleFactory符合开放封闭的原则,就需要对SimpleFactory的修改封闭,扩展开放。
怎么做呢?改造SimpleFactory,创建抽象工厂类Factory,用具体的工厂类来实现抽象工厂。
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
UML类图:
抽象工厂类:
public abstract class Factory {
public abstract Product createProduct();
}
具体实现的工厂类:
public class PlusFactory extends Factory {
@Override public Product createProduct() {
return new PlusProduct();
}
}
public class MinusFactory extends Factory {
@Override public Product createProduct() {
return new MinusProduct();
}
}
使用:
public class Client {
public static void main(String[] args) {
Product plusProduct = new PlusFactory().createProduct();
int plusResult = plusProduct.getResult(10,12);
Product minusProduct = new MinusFactory().createProduct();
int minusResult = minusProduct.getResult(12, 10);
}
}
这个时候,如果我们想增加一个乘法产品类,不需要再去修改Factory类,而是需要创建乘法工厂类,来创建乘法产品类。使得Factory对修改封闭,对扩展开放。
乘法产品类:
public class MultiProduct implements Product {
@Override public int getResult(int numA, int numB) {
return numA * numB;
}
}
乘法工厂类:
public class MultiFactory extends Factory {
@Override public Product createProduct() {
return new MultiProduct();
}
}
可以看出工厂方法模式是简单工厂模式的优化版。
具体实现的工厂类,也可以用反射获取类的实例,统一工厂类的实现:
public abstract class Factory {
public abstract <T extends Product> T createProduct(Class<T> clz);
}
public class ConcreteFactory extends Factory {
@Override public <T extends Product> T createProduct(Class<T> clz) {
Product p = null;
try {
p = (Product) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) p;
}
public static void main(String[] args) {
Factory concreteFactory = new ConcreteFactory();
Product plusProduct = concreteFactory.createProduct(PlusProduct.class);
Product minusProduct = concreteFactory.createProduct(MinusProduct.class);
}
}
这样就不需要创建多个具体的工厂类,传入产品的类型,就能够创建具体的产品对象。
另:别看简单工厂模式违反了开闭原则,其作为23种设计模式之一也是有它的理由的。在系统复杂的情况下,简单工厂能减少很多工厂类,起到简化的作用。
下个设计模式,写一下抽象工厂模式。