Java设计模式Lambda重构实战指南
Java设计模式Lambda化重构实战
随着Java 8引入Lambda表达式和函数式编程特性,许多传统设计模式可以用更简洁的方式实现。本文将探讨四种常见设计模式的Lambda化重构方案。
1. 策略模式Lambda化
概念解析
策略模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。传统实现需要定义策略接口和多个实现类。
传统实现示例
interface DiscountStrategy {
double applyDiscount(double amount);
}
class ChristmasDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double amount) {
return amount * 0.8;
}
}
class BlackFridayDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double amount) {
return amount * 0.7;
}
}
class ShoppingCart {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double checkout(double amount) {
return strategy.applyDiscount(amount);
}
}
Lambda重构
class ShoppingCart {
private UnaryOperator<Double> strategy;
public void setStrategy(UnaryOperator<Double> strategy) {
this.strategy = strategy;
}
public double checkout(double amount) {
return strategy.apply(amount);
}
}
// 使用示例
cart.setStrategy(amount -> amount * 0.8); // 圣诞折扣
cart.setStrategy(amount -> amount * 0.7); // 黑色星期五折扣
实践建议
- 当策略逻辑简单时,优先使用Lambda表达式
- 如果策略需要维护复杂状态,仍建议使用传统类实现
- 考虑使用
java.util.function
包中的标准函数式接口
2. 观察者模式简化
概念解析
观察者模式定义了对象之间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知。
传统实现示例
interface Observer {
void update(String event);
}
class EventSource {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void notifyObservers(String event) {
for (Observer observer : observers) {
observer.update(event);
}
}
}
Lambda重构
class EventSource {
private List<Consumer<String>> observers = new ArrayList<>();
public void addObserver(Consumer<String> observer) {
observers.add(observer);
}
public void notifyObservers(String event) {
observers.forEach(observer -> observer.accept(event));
}
}
// 使用示例
source.addObserver(event -> System.out.println("Received event: " + event));
实践建议
- 对于简单的事件处理,Lambda更简洁
- 需要多个回调方法时,仍需要接口定义
- 考虑使用Java 9+的
Flow
API实现响应式流
3. 命令模式替代方案
概念解析
命令模式将请求封装为对象,从而允许参数化客户端与不同请求。
传统实现示例
interface Command {
void execute();
}
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
Lambda重构
class RemoteControl {
private Runnable command;
public void setCommand(Runnable command) {
this.command = command;
}
public void pressButton() {
command.run();
}
}
// 使用示例
Light light = new Light();
control.setCommand(light::turnOn);
实践建议
- 简单命令可使用方法引用或Lambda
- 需要支持undo操作时,仍需传统实现
- 考虑组合多个函数式接口处理复杂命令
4. 模板方法模式重构
概念解析
模板方法模式定义算法骨架,将某些步骤延迟到子类实现。
传统实现示例
abstract class Game {
protected abstract void initialize();
protected abstract void startPlay();
protected abstract void endPlay();
public final void play() {
initialize();
startPlay();
endPlay();
}
}
class Cricket extends Game {
@Override
protected void initialize() { /* 实现 */ }
@Override
protected void startPlay() { /* 实现 */ }
@Override
protected void endPlay() { /* 实现 */ }
}
Lambda重构
class Game {
private final Runnable initialize;
private final Runnable startPlay;
private final Runnable endPlay;
public Game(Runnable initialize, Runnable startPlay, Runnable endPlay) {
this.initialize = initialize;
this.startPlay = startPlay;
this.endPlay = endPlay;
}
public final void play() {
initialize.run();
startPlay.run();
endPlay.run();
}
}
// 使用示例
Game cricket = new Game(
() -> System.out.println("Cricket Game Initialized"),
() -> System.out.println("Cricket Game Started"),
() -> System.out.println("Cricket Game Finished")
);
实践建议
- 简单算法步骤适合Lambda实现
- 复杂模板方法仍需抽象类
- 考虑使用函数组合实现更灵活的模板
总结对比
最佳实践指南:
- 评估模式复杂度:简单逻辑优先Lambda
- 考虑状态管理:有状态实现更适合传统方式
- 团队熟悉度:平衡简洁性与可读性
- 性能考量:Lambda通常不会带来显著性能开销
- 测试便利性:Lambda可能增加单元测试复杂度
通过合理运用Lambda表达式,可以在保持设计模式核心思想的同时,大幅减少样板代码,提高开发效率。