You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java计算器如何规避if-else/switch链并遵循开闭原则

符合SOLID开闭原则的计算器实现方案

要消除switch语句并遵循开闭原则,核心思路是将运算类型与具体实现解耦,让新增运算时无需修改原有核心代码。下面给出具体的Java实现方案:

1. 定义统一的运算接口

首先,让所有运算实现同一个接口,包含计算逻辑和描述文本的方法(满足打印需求):

public interface Operation {
    // 执行计算
    float calculate(float currentValue, float newValue);
    // 返回运算描述(用于打印)
    String getDescription(float currentValue, float newValue);
}

2. 实现具体运算类

为每个运算单独创建类,实现Operation接口,比如加法:

public class AdditionOperation implements Operation {
    @Override
    public float calculate(float currentValue, float newValue) {
        return currentValue + newValue;
    }

    @Override
    public String getDescription(float currentValue, float newValue) {
        return String.format("%.1f added to %.1f", currentValue, newValue);
    }
}

减法、乘法、除法以此类推,后续新增模运算时,只需要新增ModuloOperation类即可,完全不影响现有代码。

3. 改造运算枚举,绑定具体实现

把OperationType枚举改造为持有对应运算实例,通过枚举直接获取运算实现,彻底抛弃switch:

public enum OperationType {
    ADD(new AdditionOperation()),
    SUBTRACT(new SubtractionOperation()),
    MULTIPLY(new MultiplicationOperation()),
    DIVIDE(new DivisionOperation());
    // 新增模运算时,仅需添加这一行:MODULO(new ModuloOperation())

    private final Operation operation;

    OperationType(Operation operation) {
        this.operation = operation;
    }

    public Operation getOperation() {
        return operation;
    }
}

4. 重构Calculator类,移除switch逻辑

修改execute方法,直接通过枚举获取运算实例执行计算,同时记录运算过程用于打印:

import java.util.ArrayList;
import java.util.List;

public class Calculator {
    private float currentValue;
    private final List<OperationRecord> operationRecords = new ArrayList<>();

    // 内部类存储运算记录,方便后续打印
    private static class OperationRecord {
        private final Operation operation;
        private final float currentValue;
        private final float newValue;

        public OperationRecord(Operation operation, float currentValue, float newValue) {
            this.operation = operation;
            this.currentValue = currentValue;
            this.newValue = newValue;
        }

        public String getDescription() {
            return operation.getDescription(currentValue, newValue);
        }
    }

    public Calculator(float initialValue) {
        this.currentValue = initialValue;
    }

    public Calculator execute(OperationType operationType, float newValue) {
        Operation operation = operationType.getOperation();
        float result = operation.calculate(currentValue, newValue);
        // 记录运算过程
        operationRecords.add(new OperationRecord(operation, currentValue, newValue));
        currentValue = result;
        return this;
    }

    // 给打印类提供只读的记录列表
    public List<OperationRecord> getOperationRecords() {
        return new ArrayList<>(operationRecords);
    }

    public float getCurrentValue() {
        return currentValue;
    }
}

5. 适配PrintHandler类

调整打印逻辑,读取运算记录并输出:

public class PrintHandler {
    private final Calculator calculator;

    public PrintHandler(Calculator calculator) {
        this.calculator = calculator;
    }

    public void printResults() {
        calculator.getOperationRecords().forEach(record -> System.out.println(record.getDescription()));
        System.out.println("-----------");
        System.out.printf("Total: %.1f%n", calculator.getCurrentValue());
    }
}

效果验证

原App类的代码完全不用修改,运行后输出和之前一致。当需要新增模运算时:

  1. 创建ModuloOperation实现Operation接口
  2. 在OperationType枚举中添加MODULO(new ModuloOperation())
    无需修改Calculator、PrintHandler等任何现有核心代码,完美符合开闭原则。

方案优势

  • 彻底消除了switch/if-else语句,代码更简洁易维护
  • 新增运算仅需扩展类和枚举项,完全遵循对扩展开放、对修改关闭的原则
  • 运算逻辑与核心计算器逻辑解耦,每个运算类职责单一(符合单一职责原则)

内容的提问来源于stack exchange,提问作者Jwok

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:16:01