源码git地址 https://github.com/dlovetco/designMode
我们之前学过一个简单工厂模式 ,它的特点是把switch操作从客户端拿到了工厂类(只有一个工厂)中。而我们在这里所要讲的工厂模式可以理解为为每个种类的对象建立相应的工厂类。我们还是以计算机的加减乘除为例。
简单工厂方式
public class Main {
public static void main(String[] args) {
CalculateMode plus = CalculateFactory.getCalculate("+");
CalculateMode minus = CalculateFactory.getCalculate("-");
if (plus != null) {
System.out.println(plus.calculate(1, 2));
}
if (minus != null) {
System.out.println(minus.calculate(1, 2));
}
}
}
/**
* 计算器工厂
*/
class CalculateFactory {
public static CalculateMode getCalculate(String type) {
switch (type) {
case "+":
return new Plus();
case "-":
return new Minus();
default:
return null;
}
}
}
/**
* 计算模式
*/
interface CalculateMode {
int calculate(int num1, int num2);
}
/**
* 加法
*/
class Plus implements CalculateMode {
@Override
public int calculate(int num1, int num2) {
return num1 + num2;
}
}
/**
* 减法
*/
class Minus implements CalculateMode {
@Override
public int calculate(int num1, int num2) {
return num1 - num2;
}
}
这里先复习一下简单工厂 大家最好自己码一下
工厂方式
class Main {
public static void main(String[] args) {
Factory plusFactory = new PlusFactory();//定义一个加法工厂
CalculateMode plus = plusFactory.getCalculate();
System.out.println(plus.calculate(1, 2));
Factory minusFactory = new MinusFactory();//定义一个减法工厂
CalculateMode minus = minusFactory.getCalculate();
System.out.println(minus.calculate(1, 2));
}
}
/**
* 抽象工厂
*/
interface Factory {
CalculateMode getCalculate();
}
class PlusFactory implements Factory {
@Override
public CalculateMode getCalculate() {
return new Plus();
}
}
class MinusFactory implements Factory {
@Override
public CalculateMode getCalculate() {
return new Minus();
}
}
/**
* 计算模式
*/
interface CalculateMode {
int calculate(int num1, int num2);
}
class Plus implements CalculateMode {
@Override
public int calculate(int num1, int num2) {
return num1 + num2;
}
}
class Minus implements CalculateMode {
@Override
public int calculate(int num1, int num2) {
return num1 - num2;
}
}
工厂模式的uml图及其代码如下所示
@startuml
interface Factory
interface CalculateMode
Factory <|.. PlusFactory
Plus <-- PlusFactory
class PlusFactory{
}
Factory <|.. MinusFactory
Minus <-- MinusFactory
class MinusFactory{
}
CalculateMode <|.. Plus
class Plus{
}
CalculateMode <|.. Minus
class Minus{
}
@enduml
通过上面的工厂模式代码 我们确实能够感受到同样的一个计算器的加减乘除,采用工厂模式比采用简单工厂模式的代码量要多很多。那么两个模式相比到底有哪些优劣点呢?
简单工厂模式
优点
- 工厂类中包含了一个switch判断,可以直接根据客户端的选择来生成一个对应的实例化对象。对于客户端来说把switch判断逻辑完全可以抛出去。
缺点
- 如果要新增一个乘方运算,我们要做的事情是:
- 在简单工厂类里面新增一个case分支(或者其他的逻辑判断代码),此处违反了开放-封闭原则
- 新增加一个乘方运算类实现CalculateMode接口
- 在实例化对象的时候如果要实例化5个加法对象则我们需要这么写
CalculateMode cal1= CalculateFactory.getCalculate("+");
CalculateMode cal2= CalculateFactory.getCalculate("+");
CalculateMode cal3= CalculateFactory.getCalculate("+");
CalculateMode cal4= CalculateFactory.getCalculate("+");
CalculateMode cal5= CalculateFactory.getCalculate("+");
如果我们要把他全部换成减法则需要修改每一句话,把+改成-,这无疑是不好的。即上面实例化多个对象的时候有太多重复。
工厂模式:
定义了一个用于创建对象的接口让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类中。
优点
- 使用依赖倒转原则,在增加乘方运算时不需要改动原来的代码。只需要增加一个乘方类实现CalculateMode和一个乘方工厂实现Factory,完全的符合开放-封闭原则。
- 在实例化5个加法的时候我们只需这么写
Factory Factory = new PlusFactory();//定义一个加法工厂
CalculateMode cal1= Factory .getCalculate();
CalculateMode cal2= Factory .getCalculate();
CalculateMode cal3= Factory .getCalculate();
CalculateMode cal4= Factory .getCalculate();
CalculateMode cal5= Factory .getCalculate();
如果一旦我们需要把加法全部改成减法,我们只需要修改第一句话
Factory Factory = new MinusFactory();//定义一个减法工厂
这其实也就是依赖倒转的好处。
缺点
- 虽然解决了开放-封闭原则,但是又出现了老问题。我们把生成什么对象的逻辑判断又移交给了客户端(即main方法)。