设计模式----简单工厂和工厂方法模式

81 阅读4分钟

简单工厂和工厂方法模式

一 简单工厂

1.1 概述

​ 简单工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在简单工厂模式中,当创建某个对象时,不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。简单工厂模式不是设计模式,像是一种编程习惯。

1.2 UML类图

简单工厂UML图.jpg

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类图

工厂方法UML图.jpg

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 工厂方法好处

如果之后再出现一种计算类型,只需再定义一个新的操作类型(继承基本操作类),然后再定义一个工厂类(实现抽象工厂),然后通过该工厂创建新的计算类型

的操作对象,无需修改工厂类。