一、工厂方法模式概述
工厂方法模式(英语:Factory method pattern)是一种实现了“工厂”概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。工厂方法模式是简单工厂模式的进一步抽象和推广。
二、简单工厂模式 VS 工厂方法模式
在篇三中,我们说过简单工厂模式。
简单工厂模式:将对象的创建放在了一个工厂类中,当需要新增一个分支时,就需要修改工厂类。根据开闭原则,简单工厂模式违反了此原则。
工厂方法模式:在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给工厂子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
按照对象不同,分为不同的工厂,每一类对象都有一个自己对应的工厂产生,这些工厂之间使用同一接口方法关联,所以叫工厂方法模式。工厂方法模式将对象的创建过程放在工厂方法模式保持了简单工厂模式的优点,也克服了它的缺点。
但是,工厂方法模式也有缺点,那就是每新增一类对象,就需要增加一个生产对应对象的工厂类,增加了额外的工作量。当然,这个缺点可以克服,那就是使用反射,我们等下一次重构再说。
工厂方法模式的结构图如下:
三、工厂方法模式举例
我们还使用简单工厂模式中使用的内容,我们通过重构,看下他们的变化在哪。
抽象工厂接口:
package com.zhaodf.pattern.factoryMethodPattern; public interface OperationFactory{ Operation createOperation(double numberA, double numberB); }
加法工厂实现类:
package com.zhaodf.pattern.factoryMethodPattern; public class AddFactory implements OperationFactory{ public Operation createOperation(double numberA, double numberB) { return new AddOperation(numberA,numberB); } }
减法工厂实现类:
package com.zhaodf.pattern.factoryMethodPattern; public class SubFactory implements OperationFactory{ public Operation createOperation(double numberA, double numberB) { return new SubOperation(numberA,numberB); } }
操作类统一抽象接口:
package com.zhaodf.pattern.factoryMethodPattern; public interface Operation { double getResult(); }
加法操作类实现:
package com.zhaodf.pattern.factoryMethodPattern; public class AddOperation implements Operation { private double numberA; private double numberB; public AddOperation(double numberA, double numberB){ this.numberA = numberA; this.numberB = numberB; } public double getResult() { return this.numberA+this.numberB; } public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } }
减法操作类实现:
package com.zhaodf.pattern.factoryMethodPattern; public class SubOperation implements Operation{ private double numberA; private double numberB; public SubOperation(double numberA, double numberB){ this.numberA = numberA; this.numberB = numberB; } public double getResult() { return this.numberA - this.numberB; } public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } }
客户端调用代码:
package com.zhaodf.pattern.factoryMethodPattern; public class TestOperation { public static void main(String[] args){ double numberA = 1; double numberB = 2; OperationFactory operationFactory = new SubFactory(); Operation op = operationFactory.createOperation(numberA,numberB); System.out.println(op.getResult()); } }
四、总结
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。 将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。
工厂方法模式的结构角色:
- 一个抽象产品类,可以派生出多个具体产品类,如我们的加、减操作类。
- 一个抽象工厂类,可以派生出多个具体工厂类,如我们的加法工厂类,减法工厂类
- 每个具体工厂类只能创建一个具体产品类的实例,如加法工厂类只能创造加法类对象。
我们从例子中明白,工厂方法模式将简单工厂类中的工厂类的职能进行下沉,由对应的子工厂类去实现。但是不可否认的是,在客户端代码中,需要根据要求创建不同的工厂类,这也是工厂方式模式的一个缺点,后续我们讲到反射时,重新重构这里的代码。