观察者模式的定义:
在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。一般情况下,被依赖的对象叫做被观察者,依赖的对象观察者。
Demo_01演示:(模板代码)
/**
* 抽象主题,也就是被观察者的角色
*/
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(Message message);
}
/**
* 抽象观察者
*/
public interface Observer {
void update(Message message);
}
/**
* 具体的观察者
*/
public class ConcreteObserverOne implements Observer{
@Override
public void update(Message message) {
//获取消息通知,执行自己的逻辑
}
}
/**
* 具体的观察者
*/
public class ConcreteObserverTwo implements Observer{
@Override
public void update(Message message) {
//获取消息通知,执行自己逻辑
}
}
/**
* 具体被观察者
*/
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(Message message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
public class Demo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
subject.registerObserver(new ConcreteObserverOne());
subject.registerObserver(new ConcreteObserverTwo());
subject.notifyObservers(new Message());
}
}
Demo_02演示:(同步阻塞的实现方式)
需求:假设我们在开发一个 P2P 投资理财系统,用户注册成功之后,我们会给用户发放投资体验金,并且还要给用户发送一封“欢迎注册成功”的站内信。
/**
* 抽象观察者
*/
public interface RegObserver {
void handleRegSuccess(long userId);
}
/**
* 用于向用户发送登陆成功的提示
*/
public class RegNotificationObserver implements RegObserver {
private NotificationService notificationService;
@Override
public void handleRegSuccess(long userId) {
notificationService.sendInboxMessage(userId, "Welcome...");
}
}
/**
* 用于向用户发送体验金
*/
public class RegPromotionObserver implements RegObserver {
private PromotionService promotionService; // 依赖注入
@Override
public void handleRegSuccess(long userId) {
promotionService.issueNewUserExperienceCash(userId);
}
}
/**
* 被观察者
*/
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;
}
}
Demo_03演示:(异步非阻塞的实现方式)
第一种:在每个 handleRegSuccess() 函数中创建一个新的线程执行代码逻辑;第二种:在 UserController 的 register() 函数中使用线程池来执行每个观察者的 handleRegSuccess() 函数。
/**
* 第一种实现方式,其他类代码不变,就没有再重复罗列
* 用于向用户发送体验金
*/
public class RegPromotionObserver implements RegObserver {
private PromotionService promotionService; // 依赖注入
@Override
public void handleRegSuccess(final long userId) {
new Thread(new Runnable() {
@Override
public void run() {
promotionService.issueNewUserExperienceCash(userId);
}
}).start();
}
}
/**
* 被观察者
* 第二种实现方式
*/
public class UserController {
private UserService userService;// 依赖注入
private List<RegObserver> regObservers = new ArrayList<>();
private Executor executor;
// 一次性设置好,之后也不可能动态的修改
public void setRegObservers(List<RegObserver> observers) {
regObservers.addAll(observers);
}
public Long register(String telephone, String password) {
//省略输入参数的校验代码
// 省略userService.register()异常的try-catch代码
final long userId = userService.register(telephone, password);
for (final RegObserver observer : regObservers) {
executor.execute(new Runnable() {
@Override
public void run() {
observer.handleRegSuccess(userId);
}
});
}
return userId;
}
}