将观察者和被观察者代码解耦
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。观察者模式(Observer Design Pattern)也被称为发布订阅模式。
- 被依赖的对象叫作被观察者
Observable
- 依赖的对象叫作观察者
Observer
注册成功后执行特定操作的例子
public class UserController {
private UserService userService; // 依赖注入
private PromotionService promotionService; // 依赖注入
public Long register(String telephone, String password) {
//省略输入参数的校验代码
//省略userService.register()异常的try-catch代码
long userId = userService.register(telephone, password);
// 注册成功,发放优惠券
promotionService.issueNewUserExperienceCash(userId);
return userId;
}
}
将两个功能耦合在一起,违反了单一职责原则
如果没有扩展和修改的需求,现在的代码实现是可以接受的。如果非得用观察者模式,就需要引入更多的类和更加复杂的代码结构,反倒是一种过度设计。
注册接口做了两件事情,注册和发放体验金,违反单一职责原则
-
如果需求频繁变动,频繁地修改
register()
函数中的代码,违反开闭原则。比如,用户注册成功之后,不再发放体验金,而是改为发放优惠券,
并且还要给用户发送一封“欢迎注册成功”的站内信。 -
如果注册成功之后需要执行的后续操作越来越多,那
register()
函数的逻辑会变得越来越复杂,也就影响到代码的可读性和可维护性。
利用观察者模式重构
// 观察者,被观察者状态变更时,得到通知,执行操作
public interface RegObserver {
void handleRegSuccess(long userId);
}
public class RegPromotionObserver implements RegObserver {
private PromotionService promotionService; // 依赖注入
@Override
public void handleRegSuccess(long userId) {
promotionService.issueNewUserExperienceCash(userId);
}
}
public class RegNotificationObserver implements RegObserver {
private NotificationService notificationService;
@Override
public void handleRegSuccess(long userId) {
notificationService.sendInboxMessage(userId, "Welcome...");
}
}
public class UserController {
private UserService userService; // 依赖注入
// 多个观察者
private List<RegObserver> regObservers = new ArrayList<>();
// 一次性设置好,之后也不可能动态的修改
public void setRegObservers(List<RegObserver> observers) {
regObservers.addAll(observers);
}
public Long register(String telephone, String password) {
//省略输入参数的校验代码
//省略userService.register()异常的try-catch代码
long userId = userService.register(telephone, password);
// 注册成功,依次通知各个观察者
for (RegObserver observer : regObservers) {
observer.handleRegSuccess(userId);
}
return userId;
}
}