简单工厂模式是最简单的模式了,也是我们打开教材的第一个模式.

一, 简单工厂模式的定义.

简单工厂模式是这样的:

建立1个工厂类, 这个类有1个静态方法, 根据条件(参数)的不同返回不同的同1个类族的对象.

也就是工厂的产品是对象.

但是这种些对象可以属于不同的类,

但是它们的类通常是属于同一超类或实现同一 接口的子类.

比如:   1个工厂类F,  它有1个静态方法getObj(有参数)

getObj可以返回类A1的对象a1, 也可以返回类A2 的对象a2. 但是通常A1 和 A2属于同1个类A.

二, 简单工厂模式的意义.

这里先写个总结. 后面再举例子详细解释

意义就是.

根据上面的例子

1. 当你让程序猿修改类A1, 不会暴露A2的代码. 方便项目管理

2. 当你想添加业务时, 只需要增加子类A3, 不用修改上层A的代码.  方便扩展

(项目中上层类可能用jar包发布, 或者你没有权限)

三, 例子

这个例子很简单, 就是做1个简单的计算器, 只有加法和剪发. 界面大概是这样的:

简单工厂(SimpleFactory)模式简介-编程之家

简单来讲, 就是让User输入2个integer,  然后按button + 就是显示和, 按button "-" 就显示差

3.1 不使用任何模式

当然, 业务和界面代码分开是最基本的要求.

有些人是这样写的:

业务类: Operator1

public class Operation1 {private int i;private int j;public Operation1(int i, int j){this.i = i;this.j = j;}private int add(){return i + j;}private int del(){return i - j;}public int getResult(String symbol){switch(symbol){case "+": return add();case "-": return del();}return 0;}
}

界面代码是这样的:

private void BtnClicked_btnDel(){int i = Integer.parseInt(tb_i.getText());int j = Integer.parseInt(tb_j.getText());lblResult.setText("" + new Operation1(i,j).getResult("-"));}
}
private void BtnClicked_btnAdd(){int i = Integer.parseInt(tb_i.getText());int j = Integer.parseInt(tb_j.getText());lblResult.setText("" + new Operation1(i,j).getResult("+"));}
}

上面的写法是可行的. 但是扩展性不好.

假如我想增加1个button "*" 乘法,  那么我们必须修改类Operation1 添加1个方法mul(),(以及getResult())

这就导致两个问题.

1.暴露了加法和减法是如何实现的.

2. 有可能Operation类不能修改.

3.2 使用简单工厂(SimpleFactory)模式

定义1个抽象超类 Operation

public abstract class Operation {private int i;private int j;public int getI(){return i;}public int getJ(){return j;}public Operation(int i, int j){this.i = i;this.j = j;}public abstract int getResult();
}

那么它的子类就必须重写getResult方法.

定义加法类. OperationAdd

public class OperationAdd extends Operation{public OperationAdd(int i, int j) {super(i, j);// TODO Auto-generated constructor stub}@Overridepublic int getResult(){return this.getI() + this.getJ();}
}

减法类OperationDel

public class OperationDel extends Operation{public OperationDel(int i, int j) {super(i, j);// TODO Auto-generated constructor stub}@Overridepublic int getResult(){return this.getI() - this.getJ();}
}

好了, 这是再定义1个工厂类, 这个工厂的产品就是Operation的子类对象.

public class OperationFactory {public static Operation getOperationObj(int i, int j, String symbol){switch(symbol){case "+": return new OperationAdd(i, j);case "-": return new OperationDel(i, j);}return null;}
}

客户端关键代码:

private void BtnClicked_btnDel(){int i = Integer.parseInt(tb_i.getText());int j = Integer.parseInt(tb_j.getText());Operation oper = OperationFactory.getOperationObj(i,j,"-");lblResult.setText("" + oper.getResult());}

UML:

简单工厂(SimpleFactory)模式简介-编程之家

咋一看, 这里用到4个类, 分别是1个超类, 1个加法类, 1个减法类, 一个工厂类. 貌似更加复杂啦.

但是, 实际上它的可扩展性更好.

首先, 修改减法类, 不会暴露加法类.

其次, 很方便地增加乘法功能.   只需增加1个乘法类, 及修改工厂类.    即使其他3个类用jar包发布也没关系, 根本没必要修改它们.

四, 开放-封闭原则(open-closed principle)

有人问,  貌似在方法1里Operation1类里增加1个乘法方法不是更加方便吗?

方法2里需要增加1个新的类啊.

先不考虑你能不能修改基类的问题.

就如数据库表设计一样,   范式越高, 表就被分割得越多.

增加业务的话,  增加表是优于修改旧表(增加列)的.

设计模式同样,  如果要增加功能,   增加1个类, 比修改旧类要好.

因为这符合开放封闭原则.

所谓开放-封闭原则就是, 对扩展开放, 对修改封闭.

程序猿在做prj时, 往往做到大半时,  遇到User改需求了,   虽然需求改动看起来很小, 实际上对程序影响很大,  甚至要重新翻工.

发生这种痛苦的事情就是在程序设计时对扩展性考虑得不足.

在理想状态下, 我们做设计时, 尽量做到客户无论怎样修改或添加需求.

我们原来的代码(基类)都不用修改, 只需增加新的代码(新的子类)就ok了,  也就是让新代码去完成新的功能.

这就是所谓的开放-封闭原则.   在java设计模式中, 无论是哪个模式, 实际上都是为了实现这个原则而存在的.

简单工厂(SimpleFactory)模式简介-编程之家《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读