简单工厂违背了开闭原则,每次新增产品类都会修改工厂类,为了改正上述问题,出现了工厂方法。
工厂方法模式把创建具体类交给具体的工厂类去完成。类图如下:
代码:
抽象产品类Product:
/**
* 产品类的抽象类
*/
public abstract class Product {
public abstract void method();
}
具体产品类A、B:
public class ConcreateProductA extends Product{
@Override
public void method() {
System.out.println("我是具体的产品A");
}
}
public class ConcreateProductB extends Product{
@Override
public void method() {
System.out.println("我是具体的产品B");
}
}
抽象工厂类:
/**
* 抽象工厂类
* 生产什么由子类去实现
*/
public abstract class Factory {
//返回具体的产品底箱
public abstract Product createProduct();
}
具体工厂类:
/**
* 工厂类A创建产品A
*/
public class ConcreateAFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreateProductA();
}
}
/**
* 工厂类B创建产品B
*/
public class ConcreateBFactory extends Factory {
@Override
public Product createProduct() {
return new ConcreateProductB();
}
}
当客户需要具体的产品时,由具体的工厂类创建。
上述方案也有不好的地方:当产品类增多时具体工厂类会增多
改进措施:使用反射,在工厂方法的参数中传入一个Class类来决定是哪一个产品类
抽象工厂类:
public abstract class Factory{
/**
* 抽象工厂方法
* 具体生产什么由子类去实现
*
* @param clz 产品对象类型
* @return 具体的产品对象
*/
public abstract <T extends Product> T createProduct(Class<T> clz);
}
具体工厂类:
public class ConcreteFactory extends Factory{
public <T extends Product> T createProduct(Class<T> clz) {
Product product = null;
try{
product = (Product)Class.forName(clz.getName()).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}
客户端实现:
public class Client {
public static void main(String[] args){
Factory factory = new ConcreteFactory();
Product product = factory.createProduct(ConcreateProductA.class);
product.method();
}
}