简单工厂和工厂方法模式
一 简单工厂
1.1 概述
简单工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在简单工厂模式中,当创建某个对象时,不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。简单工厂模式不是设计模式,像是一种编程习惯。
1.2 UML类图
1.3 简单代码案例--------创建加减乘除工厂并计算结果
1 创建一个抽象操作类(对应图中的抽象产品)
@Data
public abstract class BaseOperation {
/**
* 获取结果
*
* @param numberA 参数A
* @param numberB 参数B
* @return 结果
*/
public abstract double getResult(double numberA, double numberB);
}
2 创建加减乘除具体操作类(对应图中具体产品)并继承抽象操作类
/**
* 加法操作
*
* @author lhh
* @date 2024/6/29 10:11
*/
public class AddOperation extends BaseOperation {
/**
* 获取结果
* @param numberA 参数A
* @param numberB 参数B
* @return 结果
*/
@Override
public double getResult(double numberA, double numberB) {
return numberA + numberB;
}
}
/**
* 减法操作
*
* @author lhh
* @date 2024/6/29 10:11
*/
public class SubOperation extends BaseOperation {
/**
* 获取结果
*
* @param numberA 参数A
* @param numberB 参数B
* @return 结果
*/
@Override
public double getResult(double numberA, double numberB) {
return numberA - numberB;
}
}
/**
* 除法操作
*
* @author lhh
* @date 2024/6/29 10:11
*/
public class DivOperation extends BaseOperation {
/**
* 获取结果
* @param numberA 参数A
* @param numberB 参数B
* @return 结果
*/
@Override
public double getResult(double numberA, double numberB) {
if (numberB == 0) {
throw new RuntimeException("除数不能为0");
}
return numberA / numberB;
}
}
/**
* 乘法操作
*
* @author lhh
* @date 2024/6/29 10:11
*/
public class MulOperation extends BaseOperation {
/**
* 获取结果
* @param numberA 参数A
* @param numberB 参数B
* @return 结果
*/
@Override
public double getResult(double numberA, double numberB) {
return numberA * numberB;
}
}
3 创建工厂类,获取具体操作类的对象
/**
* 操作工厂
*
* @author lhh
* @date 2024/6/29 10:29
*/
public class OperationFactory {
/**
* 具体操作创建
*
* @param operate 操作符
* @return 对象
*/
public BaseOperation createOperation(OperationEnum operate) {
BaseOperation operation;
switch (operate) {
case ADD:
operation = new AddOperation();
break;
case SUB:
operation = new SubOperation();
break;
case MUL:
operation = new MulOperation();
break;
case DIV:
operation = new DivOperation();
break;
default:
return null;
}
return operation;
}
}
4 具体调用
/**
* 简单工厂模式测试
*/
@Test
public void simpleFactory() {
OperationFactory operationFactory = new OperationFactory();
// 加法
BaseOperation addOperation = operationFactory.createOperation(OperationEnum.ADD);
Assert.assertEquals(3, addOperation.getResult(2, 1), 0);
// 减法
BaseOperation subOperation = operationFactory.createOperation(OperationEnum.SUB);
Assert.assertEquals(1, subOperation.getResult(2, 1), 0);
// 乘法
BaseOperation mulOperation = operationFactory.createOperation(OperationEnum.MUL);
Assert.assertEquals(2, mulOperation.getResult(2, 1), 0);
// 除法
BaseOperation divOperation = operationFactory.createOperation(OperationEnum.DIV);
Assert.assertEquals(1, divOperation.getResult(2, 2), 0);
}
四 简单工厂模式缺陷
简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了开闭原则。
二 工厂方法
2.1 概述
定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。解决了简单工厂违背开闭原则的问题。
2.2 UML类图
2.3 简单工厂修改为工厂方法
修改简单工厂的工厂类。不再是通过一个工厂类来创建具体的操作类型对象,而是每种操作类型定义一个对应的工厂,通过每个操作类型对应的工厂来创建具体的操作类型,这些具体的工厂是抽象工厂的实现。
/**
* 工厂接口
*
* @author lhh
* @date 2024/7/7 16:26
*/
public interface Factory {
/**
* 创建操作工厂
*
* @return BaseOperation
*/
BaseOperation createOperation();
}
/**
* 加法工厂
*
* @author lhh
* @date 2024/7/7 16:20
*/
public class AddFactory implements Factory {
/**
* 创建操作类型
*
* @return BaseOperation
*/
@Override
public BaseOperation createOperation() {
return new AddOperation();
}
}
/**
* 除法工厂
*
* @author lhh
* @date 2024/7/7 16:20
*/
public class DivFactory implements Factory {
/**
* 创建操作类型
*
* @return BaseOperation
*/
@Override
public BaseOperation createOperation() {
return new DivOperation();
}
}
/**
* 乘法工厂
*
* @author lhh
* @date 2024/7/7 16:20
*/
public class MulFactory implements Factory {
/**
* 创建操作类型
*
* @return BaseOperation
*/
@Override
public BaseOperation createOperation() {
return new MulOperation();
}
}
/**
* 减法工厂
*
* @author lhh
* @date 2024/7/7 16:20
*/
public class SubFactory implements Factory {
/**
* 创建操作类型
*
* @return BaseOperation
*/
@Override
public BaseOperation createOperation() {
return new SubOperation();
}
}
具体调用
/**
* 工厂方法测试
*/
@Test
public void factoryMain() {
// 创建加法工厂
AddFactory addFactory = new AddFactory();
// 获取加法工厂的操作对象
BaseOperation operation = addFactory.createOperation();
// 调用操作对象的方法获取结果
Assert.assertEquals(3, operation.getResult(1,2),0);
}
2.4 工厂方法好处
如果之后再出现一种计算类型,只需再定义一个新的操作类型(继承基本操作类),然后再定义一个工厂类(实现抽象工厂),然后通过该工厂创建新的计算类型
的操作对象,无需修改工厂类。