用《设计模式》的角度优化 “枚举”

发布于:2025-03-05 ⋅ 阅读:(62) ⋅ 点赞:(0)

枚举应该都有用过,枚举主要的作用是为了方便用户查找和引用枚举。

案例一

下面的枚举逻辑很简单,就是通过枚举值返回不同的结果。

public enum OperationEnum {
    EQUAL_TO,
    CONTAINS,
    START_WITH,
    END_WITH;

    public String getOperationValue(String value) {
        if (this == EQUAL_TO) {
            return "'" + value + "'";
        } else if (this == START_WITH) {
            return "/" + value + ".*/";
        } else if (this == END_WITH) {
            return "/" + value + ".*/";
        } else {
            return "/.*" + value + ".*/";
        }
    }
}

学了《设计模式》之后,我们很容易看出这段代码的问题。
代码中getOperationValue里使用if...else...的结构,导致枚举值之间存在耦合关系。
举个例子来说,当我们要增加新的枚举值时需要修改这段if...else...代码。
那么明显它没有符合低耦合 高内聚的设计理念。

我们也都知道,抽象比具体 更稳定
那为了避免使用if...else...结构,我们将getOperationValue定义为抽象方法,如下

通过重载抽象方法进行解耦

enum OperationEnum {
    EQUAL_TO {
        @Override
        public String getOperationValue(String value) {
            return "'" + value + "'";
        }
    },
    CONTAINS {
        @Override
        public String getOperationValue(String value) {
            return "/.*" + value + ".*/";
        }
    },
    START_WITH {
        @Override
        public String getOperationValue(String value) {
            return "/" + value + ".*/";
        }
    },
    END_WITH {
        @Override
        public String getOperationValue(String value) {
            return "/.*" + value + "/";
        }
    };

	/**
	 * 定义抽象方法
	 */
    public abstract String getOperationValue(String value);
}

我们对比前后的代码,很明显,新增枚举时,带抽象方法重载的方式影响更小。

是否觉得上述代码已经足够好了?

利用接口的方式实现枚举

import java.util.function.Function;

public enum OperationEnum {
    EQUAL_TO((value) -> "'" + value + "'"),
    CONTAINS((value) -> "/.*" + value + ".*/"),
    START_WITH((value) -> "/" + value + ".*/"),
    END_WITH((value) -> "/.*" + value + "/");
    
    private final Function<String, String> function;

    OperationEnum(Function<String, String> function) {
        this.function = function;
    }

    public String getOperationValue(String value) {
        return function.apply(value);
    }
}

如果逻辑足够简单,从代码来说这种代码更简洁明了。
如果逻辑比较复杂,可以将lambda表达式用接口实现类代替,然后构造的时候传入对应的接口实现


网站公告

今日签到

点亮在社区的每一天
去签到