观察者模式
文章目录
原理
- 思想:当对象间存在一对多关系时,可以使用观察者模式。当一个对象被修改时,会自动通知依赖它的对象。
- 如何使用:一个对象(被观察者)的状态发生改变,所有的依赖对象(观察者)都将得到通知,进行广播通知。
- 优点:观察者和被观察者是抽象耦合的;需要建立一套触发机制。
- 注意点: Java中内置了观察者模式的支持类。
基于SpringBoot的案例
思路:创建多个Listener(观察者),一个事件(被观察者)。当事件发布时候,触发Listener。示例代码如下: //被观察者 @Component public class User { public void say(){ System.out.println(“Hello AOP~”); } }
//观察者
@Component
public class UserListener {
@EventListener
@Async
public void listenUser0(User user) throws InterruptedException {
System.out.println("观察者0,观察到了User:"+user);
//测试异步观察
Thread.sleep(1000);
}
@EventListener
@Async
public void listenUser1(User user){
System.out.println("观察者1,观察到了User:"+user);
}
}
//测试
@SpringBootApplication
@PropertySource(value = {"classpath:db.properties"})
@EnableAsync
public class SpringDemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringDemoApplication.class, args);
User user = new User();
context.publishEvent(user);
}
}
结果如下:
基于Java的案例
思路:通过继承Observable类创建TestSubject类,设定当数据改变时,先后调用setChanged()和notifyObservers()方法来进行广播。通过实现Observer接口来创建两个观察者ObserverOne和ObserverTwo两个观察者来订阅TestSubject。示例代码如下:
//被观察者
public class TestSubject extends Observable {
private Integer id;
private String msg;
public TestSubject(Integer id, String msg){
this.id=id;
this.msg=msg;
}
public void setData(Integer id, String msg){
this.id=id;
this.msg=msg;
//调用setChanged(),否则调动同步方法不会被执行
this.setChanged();
//同步
this.notifyObservers(this);
}
}
//以下是两个观察者
public class ObserverOne implements Observer {
public ObserverOne(TestSubject subject){
//调阅主题
subject.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("我是观察者0,被观察者(类型)为:"+o.getClass().getName());
System.out.println("同步传递参数为:"+arg);
}
}
public class ObserverTwo implements Observer {
public ObserverTwo(TestSubject subject){
subject.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
System.out.println("我是观察者1,被观察者(类型)为:"+o.getClass().getName());
System.out.println("同步传递参数为:"+arg);
}
}
//测试
public class BasicTest {
public static void main(String[] args){
TestSubject originalMsg = new TestSubject(1, "originalMsg");
new ObserverOne(originalMsg);
new ObserverTwo(originalMsg);
originalMsg.setData(2,"updatedMsg");
}
}
结果如下:
结语
观察者模式即订阅思想,被订阅方需要广播更新,订阅方需要对更新做出处理。
文章作者 P1n93r
上次更新 2020-09-02