行为型模式
medium设计模式行为型策略模式观察者模式模板方法责任链
策略模式(Strategy)
定义一组算法,把每个算法封装起来,使它们可以互相替换。
比喻:出行方式(开车、坐地铁、骑自行车)就是不同的"策略",目的相同(到达目的地),但实现方式不同。
// 策略接口
public interface SortStrategy {
void sort(int[] array);
}
// 具体策略
public class QuickSort implements SortStrategy {
public void sort(int[] array) { /* 快排 */ }
}
public class MergeSort implements SortStrategy {
public void sort(int[] array) { /* 归并 */ }
}
// 上下文:使用策略
public class Sorter {
private SortStrategy strategy;
public Sorter(SortStrategy strategy) {
this.strategy = strategy;
}
public void sort(int[] array) {
strategy.sort(array); // 委托给策略
}
}
// 使用:运行时切换策略
Sorter sorter = new Sorter(new QuickSort());
sorter.sort(data);
消除 if-else:当一段代码有大量的 if-else 或 switch 分支,且每个分支是不同的算法/行为时,策略模式是最佳重构方案。
观察者模式(Observer)
定义对象间的一对多依赖关系,当一个对象状态变化时,所有依赖它的对象都自动收到通知。
比喻:微信公众号。你关注了一个公众号(注册观察者),作者发文(状态变化),所有关注者都收到推送(通知)。
// 观察者接口
public interface Observer {
void update(String message);
}
// 被观察者
public class EventBus {
private List<Observer> observers = new ArrayList<>();
public void subscribe(Observer observer) {
observers.add(observer);
}
public void publish(String message) {
for (Observer observer : observers) {
observer.update(message); // 通知所有观察者
}
}
}
实际应用:事件驱动架构、消息队列、Spring 的 ApplicationEvent、Android 的 LiveData。
模板方法模式(Template Method)
在父类中定义算法的骨架,将某些步骤延迟到子类实现。
public abstract class AbstractClass {
// 模板方法(定义骨架,不可覆盖)
public final void templateMethod() {
step1(); // 固定步骤
step2(); // 由子类实现
step3(); // 固定步骤
}
private void step1() { /* 固定实现 */ }
protected abstract void step2(); // 子类实现
private void step3() { /* 固定实现 */ }
}
实际应用:Java 的 AbstractList,Servlet 的 HttpServlet(doGet/doPost),JUnit 的 setUp/tearDown。
责任链模式(Chain of Responsibility)
将请求沿着处理者链传递,每个处理者决定处理请求或传给下一个。
public abstract class Handler {
protected Handler next;
public Handler setNext(Handler next) {
this.next = next;
return next;
}
public void handle(Request request) {
if (canHandle(request)) {
doHandle(request);
} else if (next != null) {
next.handle(request);
}
}
protected abstract boolean canHandle(Request request);
protected abstract void doHandle(Request request);
}
// 构建链
Handler chain = new AuthHandler();
chain.setNext(new LogHandler())
.setNext(new BusinessHandler());
chain.handle(request); // 请求依次经过 Auth → Log → Business
实际应用:Servlet Filter 链、Spring Interceptor 链、Netty ChannelPipeline、审批流程。
各模式对比
| 模式 | 核心思想 | 适用场景 | 实际应用 |
|---|---|---|---|
| 策略 | 算法互相替换 | 多种算法/行为可选 | 排序策略、支付方式 |
| 观察者 | 一对多通知 | 事件驱动、状态变化通知 | EventBus、消息队列 |
| 模板方法 | 骨架固定,细节由子类实现 | 流程固定但步骤可变 | Servlet、JUnit |
| 责任链 | 请求沿链传递 | 多个处理者依次处理 | Filter 链、审批流 |
生产高频题
策略模式和工厂模式的区别?
工厂模式关注对象的创建,策略模式关注行为的替换。工厂根据条件创建不同对象;策略将不同的算法封装为可替换的策略对象。两者常配合使用:用工厂创建策略对象。
观察者模式的优缺点?
优点:松耦合(发布者不需要知道订阅者的具体类型),支持广播通信。缺点:如果观察者很多,通知可能耗时;循环依赖可能导致死循环;观察者的执行顺序不可控。