一.工厂方法构成
- 抽象工厂角色(简单工厂中不需要):工厂方法法模式的核心,与应用程序无关,任何在模式内创建对象的工厂类必须实现的接口;
- 具体工厂角色:实现抽象工厂角色的类,负责对象的具体创建的逻辑,应用程序调用具体执行的逻辑;
- 抽象产品:产品的超类型接口,也是工厂方法模式所接收到的创建对象的类型;
- 具体产品角色:实现了抽象产品定义的接口,具体产品与具体工厂相对应
类图
二.代码
简单工厂代码
class FactoryEasy {
public static void main(String[] args) {
Product a = Factory.getInstanceA();
Product b = Factory.getInstanceB();
}
}
abstract class Product {
}
class ProductA extends Product {
public ProductA() {
System.out.println("生产a产品");
}
}
class ProductB extends Product {
public ProductB() {
System.out.println("生产b产品");
}
}
class Factory{
public static Product getInstanceA () {
return new ProductA();
}
public static Product getInstanceB () {
return new ProductB();
}
}
工厂方法代码
class FactoryMethod {
public static void main(String[] args) {
FactoryA factoryA = new FactoryA();
Product instanceA = factoryA.getInstance();
FactoryB factoryB = new FactoryB();
Product instanceB = factoryB.getInstance();
}
}
abstract class Product {
}
class ProductA extends Product {
public ProductA() {
System.out.println("生产a产品");
}
}
class ProductB extends Product {
public ProductB() {
System.out.println("生产b产品");
}
}
interface Ifactory {
Product getInstance();
}
class FactoryA implements Ifactory {
@Override
public Product getInstance() {
return new ProductA();
}
}
class FactoryB implements Ifactory {
@Override
public Product getInstance() {
return new ProductB();
}
}
带泛型的工厂方法模式(推荐使用),缺点:不能很好的管理创建细节,如果其中每个对象的初始化一致,那么它将是最好的实现方式,但是往往我们需要工厂的时候,初始化各个类型对象的时候,要求的程序和步骤会不一致.
public class FactoryMethod {
public static void main(String[] args) {
Ifactory<Product> ifactory = new Factory<>();
Product a = ifactory.getInstance(ProductA.class);
Product b = ifactory.getInstance(ProductB.class);
}
}
abstract class Product {
}
class ProductA extends Product {
public ProductA() {
System.out.println("生产a产品");
}
}
class ProductB extends Product {
public ProductB() {
System.out.println("生产b产品");
}
}
interface Ifactory<T> {
T getInstance(Class<? extends T> aClass);
}
class Factory<T> implements Ifactory<T> {
@Override
public T getInstance(Class<? extends T> aClass) {
T t = null;
try {
t = aClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return t;
}
}
三.简单工厂vs工厂方法
- 简单工厂最大的缺点不能满足ocp(开闭原则),接口对外开放,实现对外隐藏;
- 简单工厂只有一个工厂类,而工厂方法模式有一组实现了相同接口的工厂类;
- 结构复杂度,简单工厂要占优,简单工厂只需要一个工厂类,而工厂方法需要抽象工厂角色和具体工厂角色,它的工厂类会随着产品类的增加而增加,这增加了结构的复杂度;
- 代码复杂度:代码复杂度与结构复杂度往往是具有互相排斥的属性,从工厂模式的角度来说,简单工厂的功能集成在一个工厂类中,这样它的接口简单,但是代码也会比较复杂,而工厂方法模式正好相反,每个工厂只需要负责一个对象的创建;
- 客户端编程难度:工厂方法模式虽然引入了抽象工厂角色,满足了开闭原则,但是客户端需要新建一个工厂,而简单工厂使用了静态方法.在客户点进行编程,者无疑是吸引人的优点;
- 管理难度:工厂方法模式满足了开闭原则,这使得它在扩展性上要远远优于简单工厂.
四.如何选择
- 简单工厂:产品类少,创建产品代码简单,产品的结构简单,这也往往是我们初期的选择,因为一个产品往往是从简单到复杂.
- 工厂方法模式:初始化对象复杂,产品类已经比较多.创建对象细节差异化.
- 工厂方法模式(泛型):创建对象细节相似,拥有同样的一个接口.
五.参考文献
大话设计模式