前言 : 工厂方法的作用是, 替你封装对象的实例化过程, 即 new Class() 的过程, 达到解耦对象创建这件事情, 具体为什么要解耦这个事情, 解决的问题域有很多, 可以自己去延伸, 这里不做说明 .
一. 工厂方法模式
演变之路 : 普通工厂方法 --> 多个工厂方法 --> 静态工厂方法
1 普通工厂方法
直接上代码 :
// 产品接口
public interface Product { public void printMe();
}
// 具体的两个产品
public class ConcreteProduct1 implements Product {@Overridepublic void printMe() {System.out.println("this is ConcreteProduct1 .");}
}
public class ConcreteProduct2 implements Product {@Overridepublic void printMe() {System.out.println("this is ConcreteProduct2 .");}
}
// 普通工厂方法
public class ProductCreator { public Product create(String productType) {if ("ConcreteProduct1".equals(productType)) {return new ConcreteProduct1();} else if ("ConcreteProduct2".equals(productType)) {return new ConcreteProduct2();}}
}
分析 : 很明显, 用传入要生产的类的类名来换取需要的类的实例, 这个想法太糟糕, 如果传错了类名该当如何, 因此引申出了第二种实现方式, 多个工厂方法模式 .
2 多个工厂方法
直接上代码 :
// 多个工厂方法
public class ProductCreator { public Product createConcreteProduct1() {return new ConcreteProduct1();}public Product createConcreteProduct2() {return new ConcreteProduct2();}
}
分析 : 看起来好多了, 一个方法对应一个类实例的生产, 但是工厂类 TargetFactory 每次使用都得实例化一个它, 不方便, 引申出静态工厂方法 .
3 静态工厂方法
跟 2 比, 变化很小, 即把方法变为 static 静态的, 直接变为工厂类方法, 省掉了工厂类实例化的过程 .
// 静态工厂方法
public class ProductCreator { public static Product createConcreteProduct1() {return new ConcreteProduct1();}public static Product createConcreteProduct2() {return new ConcreteProduct2();}
}
分析 : 看起来已经挺好了, 需要创建什么类, 就调用创建该类的方法去创建它, 但是问题来了, 如果对 Target 的实现进行扩展, 我们的工厂类代码就需要修改, 需要注入新的扩展类的实例化方法, 这违背了 '开闭原则', 因此引申出终极的抽象工厂模式 .
二. 抽象工厂模式
直接上代码 :
// 产品接口
public interface Product { public void printMe();
}
// 工厂接口
public interface Creator { public void create();
}
// 具体的两个产品
public class ConcreteProduct1 implements Product {@Overridepublic void printMe() {System.out.println("this is ConcreteProduct1 .");}
}
public class ConcreteProduct2 implements Product {@Overridepublic void printMe() {System.out.println("this is ConcreteProduct2 .");}
}
// 抽象工厂
public class Product1Creator implements Creator { public Product create() {return new ConcreteProduct1();}
}
public class Product2Creator implements Creator { public Product create() {return new ConcreteProduct2();}
}
分析 : 虽然代码越写越多, 但是好处是显而易见的, 当 Product 需要扩展一个新实现时, 只需要写一个实现类实现 Product 接口, 并新做一个对应的工厂类实现 Creator 接口, 并生产出对应的类的对象即可, 扩展性非常好, 不会更改现有代码 .