大家好,今天咱们来聊聊Java里的枚举、策略模式和函数式接口这三个玩意儿怎么搞到一起,搞出一个高内聚低耦合的设计。听起来是不是有点高大上?别急,咱们慢慢来,保证你能听懂,还能用得上。
首先,咱们得知道什么是枚举。枚举,说白了就是一组固定的常量。比如你有个需求,要表示一周的七天,那你就可以用枚举来定义:
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
这样,你在代码里就可以直接用Day.MONDAY来表示星期一,不用再写一堆public static final int MONDAY = 1;这样的代码了。枚举的好处就是类型安全,编译器会帮你检查,避免你写错。
接下来,咱们说说策略模式。策略模式是一种行为设计模式,它允许你定义一系列算法,把它们封装起来,并且使它们可以互相替换。说白了,就是你有一堆不同的实现方式,但你不想在代码里写一堆if-else或者switch-case来判断用哪个实现。策略模式就是为了解决这个问题。
举个例子,假设你有个需求,要根据不同的用户类型来计算折扣。你可以定义一个DiscountStrategy接口:
public interface DiscountStrategy {
double applyDiscount(double price);
}
然后,你可以为每种用户类型实现一个具体的策略:
public class RegularCustomerDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price * 0.9; // 普通用户打9折
}
}
public class VIPCustomerDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double price) {
return price * 0.8; // VIP用户打8折
}
}
这样,你在代码里就可以根据用户类型来选择合适的策略,而不需要写一堆if-else。
好了,现在咱们有了枚举和策略模式,接下来就是函数式接口。函数式接口是Java 8引入的一个新特性,它就是一个只有一个抽象方法的接口。Java 8里有很多内置的函数式接口,比如Consumer、Supplier、Function等等。你可以用Lambda表达式或者方法引用来实现这些接口。
那么,怎么把枚举、策略模式和函数式接口结合起来呢?咱们来看个例子。
假设你有个需求,要根据不同的操作类型来执行不同的操作。你可以定义一个枚举,每个枚举值都对应一个操作:
public enum Operation {
ADD((x, y) -> x + y),
SUBTRACT((x, y) -> x - y),
MULTIPLY((x, y) -> x * y),
DIVIDE((x, y) -> x / y);
private final BiFunction<Double, Double, Double> operation;
Operation(BiFunction<Double, Double, Double> operation) {
this.operation = operation;
}
public double apply(double x, double y) {
return operation.apply(x, y);
}
}
这里,我们用了BiFunction这个函数式接口,它接受两个参数,返回一个结果。每个枚举值都对应一个BiFunction的实现,比如ADD对应的是(x, y) -> x + y,SUBTRACT对应的是(x, y) -> x - y,以此类推。
这样,你在代码里就可以这样用:
double result = Operation.ADD.apply(2, 3); // 结果是5
double result2 = Operation.MULTIPLY.apply(2, 3); // 结果是6
看到没?这样一来,代码就变得非常简洁,而且高内聚低耦合。每个操作的具体实现都封装在枚举里,外面只需要调用apply方法就行了。
再举个例子,假设你有个需求,要根据不同的日志级别来记录日志。你可以定义一个枚举,每个枚举值都对应一个日志记录策略:
public enum LogLevel {
INFO(message -> System.out.println("INFO: " + message)),
WARN(message -> System.out.println("WARN: " + message)),
ERROR(message -> System.err.println("ERROR: " + message));
private final Consumer<String> logStrategy;
LogLevel(Consumer<String> logStrategy) {
this.logStrategy = logStrategy;
}
public void log(String message) {
logStrategy.accept(message);
}
}
这里,我们用了Consumer这个函数式接口,它接受一个参数,没有返回值。每个枚举值都对应一个Consumer的实现,比如INFO对应的是message -> System.out.println("INFO: " + message),WARN对应的是message -> System.out.println("WARN: " + message),ERROR对应的是message -> System.err.println("ERROR: " + message)。
这样,你在代码里就可以这样用:
LogLevel.INFO.log("This is an info message."); // 输出:INFO: This is an info message.
LogLevel.ERROR.log("This is an error message."); // 输出:ERROR: This is an error message.
这样一来,日志记录的策略就封装在枚举里,外面只需要调用log方法就行了,代码非常简洁。
总结一下,枚举、策略模式和函数式接口的结合,可以让你的代码更加高内聚低耦合。枚举帮你定义一组固定的常量,策略模式帮你封装不同的实现,函数式接口帮你简化代码。三者结合,威力无穷。
好了,今天就聊到这里。如果你觉得这篇文章对你有帮助,别忘了点赞、转发、关注三连!咱们下期再见!