观察者模式与装饰器模式
❓ 面试官:观察者模式(Observer Pattern)是什么?你在项目中用过吗?
频率:🔥🔥🔥
💡 一句话总结(先抛结论): 观察者模式定义了一对多的依赖关系。当一个对象(被观察者)的状态发生改变时,所有依赖它的对象(观察者)都会收到通知并自动更新。Java 中的 java.util.Observer 和事件监听机制就是观察者模式的典型应用。
📝 详细原理解析:
1. 核心角色:
- Subject(被观察者):维护观察者列表,提供注册、删除、通知方法。
- Observer(观察者):定义更新接口,收到通知时执行相应逻辑。
2. 代码示例(简化版):
java
// 被观察者
public class OrderService {
private List<OrderObserver> observers = new ArrayList<>();
public void addObserver(OrderObserver observer) {
observers.add(observer);
}
public void createOrder(Order order) {
// 创建订单
System.out.println("订单创建成功");
// 通知所有观察者
for (OrderObserver observer : observers) {
observer.onOrderCreated(order);
}
}
}
// 观察者接口
public interface OrderObserver {
void onOrderCreated(Order order);
}
// 具体观察者
public class SmsObserver implements OrderObserver {
@Override
public void onOrderCreated(Order order) {
System.out.println("发送短信通知");
}
}🌟 实战应用场景(面试加分项): "在 Spring 框架中,观察者模式被大量使用。比如:
- 事件机制:
ApplicationEventPublisher发布事件,@EventListener监听事件。 - Spring 容器生命周期:
ApplicationListener监听容器启动、关闭事件。 - 业务场景:订单创建后,自动触发库存扣减、优惠券发放、积分增加等操作,用观察者模式实现解耦,代码非常优雅。"
❓ 面试官:装饰器模式(Decorator Pattern)是什么?它和代理模式有什么区别?
频率:🔥🔥🔥
💡 一句话总结(先抛结论): 装饰器模式是在不改变原有对象的基础上,动态地给对象添加新功能。它和代理模式的区别在于:装饰器模式关注增强功能,代理模式关注控制访问。
📝 详细对比与实战:
1. 装饰器模式示例:
java
// 基础组件
public interface Coffee {
String getDescription();
double getCost();
}
// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() { return "普通咖啡"; }
@Override
public double getCost() { return 10.0; }
}
// 装饰器
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}
// 具体装饰器:加牛奶
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return coffee.getDescription() + ", 加牛奶";
}
@Override
public double getCost() {
return coffee.getCost() + 2.0;
}
}
// 使用
Coffee coffee = new MilkDecorator(new SimpleCoffee());
// 结果:普通咖啡, 加牛奶,价格 12.02. 装饰器 vs 代理模式:
- 装饰器:增强功能,可以多层嵌套(咖啡+牛奶+糖),客户端可以控制装饰过程。
- 代理:控制访问,通常只有一层,客户端不知道代理的存在(透明代理)。
🌟 实战应用(加分项): "Java IO 流就是装饰器模式的经典应用。BufferedReader 装饰 FileReader,InputStreamReader 装饰 InputStream,可以灵活组合,实现功能叠加。"