1. 模式介绍
简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
现实生活中, 工厂是负责生产产品的; 同样在设计模式中, 简单工厂模式我们可以理解为负责生产对象的一个类, 称为 "工厂类".
2. 解决的问题
将 "类实例化的操作" 与 "使用对象的操作" 分开, 让使用者不用知道具体参数就可以实例化出所需要的 "产品" 类, 从而避免了在客户端代码中显式指定, 实现了解耦.
3. 实际案例
需求: 实现一个计算器, 包含最基本的加减乘除操作.
需求分析:
首先, 加减乘除属于某种操作, 因此可以定义一个所有操作的超类 Operation 类.
其有一个抽象方法 getResult(), 需要子类进行实现, 具体内部实现策略由具体子类提供.
而 OperationFactory 根据 +,-,*,/ 操作的不同来生成具体的 Operation 子类.
- public abstract class Operation {
- protected double numA;
- protected double numB;
- public double getNumA() {
- return numA;
- }
- public void setNumA(double numA) {
- this.numA = numA;
- }
- public double getNumB() {
- return numB;
- }
- public void setNumB(double numB) {
- this.numB = numB;
- }
- protected abstract double getResult(double numA, double numB);
- }
OperationAdd 类继承 Operation 类, 表示加法操作.
- public class OperationAdd extends Operation {
- @Override
- protected double getResult(double numA, double numB) {
- return numA + numB;
- }
- }
同理, OperationMinus,OperationMultiply,OperationDivide 分别表示减法, 乘法, 除法操作.
- public class OperationMinus extends Operation {
- @Override
- protected double getResult(double numA, double numB) {
- return numA - numB;
- }
- }
- public class OperationMultiply extends Operation{
- @Override
- protected double getResult(double numA, double numB) {
- return numA * numB;
- }
- }
- public class OperationDivide extends Operation {
- @Override
- protected double getResult(double numA, double numB) {
- if (Double.compare(numB, 0) == 0) {
- throw new IllegalArgumentException("numB can not be zero!");
- }
- return numA / numB;
- }
- }
OperationFactory 是一个 Operation 工厂, 根据具体传入的操作符来返回对应的具体 Operation 子类.
- public class OperationFactory {
- public static Operation getOperation(String oper) {
- switch (oper) {
- case "+":
- return new OperationAdd();
- case "-":
- return new OperationMinus();
- case "*":
- return new OperationMultiply();
- case "/":
- return new OperationDivide();
- default:
- return null;
- }
- }
- }
如下, 根据实际传入的 operation 操作符的不同, 执行不同的运算.
- public class Main {
- public static void main(String[] args) {
- double numA = 8000;
- double numB = 1000;
- /**
- * 根据提供的 operation 的不同, 执行不同的运算
- */
- String oper = "+";
- double result;
- Operation operation;
- operation = OperationFactory.getOperation(oper);
- result = operation.getResult(numA, numB);
- System.out.println(result);
- oper = "-";
- operation = OperationFactory.getOperation(oper);
- result = operation.getResult(numA, numB);
- System.out.println(result);
- oper = "*";
- operation = OperationFactory.getOperation(oper);
- result = operation.getResult(numA, numB);
- System.out.println(result);
- oper = "/";
- operation = OperationFactory.getOperation(oper);
- result = operation.getResult(numA, numB);
- System.out.println(result);
- }
- }
- /**
- * 运行结果
- *
- 9000.0
- 7000.0
- 8000000.0
- 8.0
- */
4. 优点
将创建实例的工作与使用实例的工作分开, 使用者不必关心类对象如何创建, 实现了解耦;
把初始化实例时的工作放到工厂里进行, 使代码更容易维护. 更符合面向对象的原则 & 面向接口编程, 而不是面向实现编程.
5. 缺点
工厂类集中了所有实例 (产品) 的创建逻辑, 一旦这个工厂不能正常工作, 整个系统都会受到影响;
违背 "开放 - 关闭原则", 一旦添加新产品就不得不修改工厂类的逻辑, 这样就会造成工厂逻辑过于复杂.
简单工厂模式由于使用了静态工厂方法, 静态方法不能被继承和重写, 会造成工厂角色无法形成基于继承的等级结构.
6. 应用场景
在了解了优缺点后, 我们知道了简单工厂模式的应用场景:
客户如果只知道传入工厂类的参数, 对于如何创建对象的逻辑不关心时;
当工厂类负责创建的对象 (具体产品) 比较少时.
来源: https://www.cnblogs.com/yeyang/p/10295431.html