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+的FlowAPI实现响应式流

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实现
  • 复杂模板方法仍需抽象类
  • 考虑使用函数组合实现更灵活的模板

总结对比

图1

最佳实践指南

  1. 评估模式复杂度:简单逻辑优先Lambda
  2. 考虑状态管理:有状态实现更适合传统方式
  3. 团队熟悉度:平衡简洁性与可读性
  4. 性能考量:Lambda通常不会带来显著性能开销
  5. 测试便利性:Lambda可能增加单元测试复杂度

通过合理运用Lambda表达式,可以在保持设计模式核心思想的同时,大幅减少样板代码,提高开发效率。

添加新评论