观察者模式(发布/订阅模式)
观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项
目中经常使用的模式,其定义如下:
Define a one-to-many dependency between objects so that when one object changes state,all its
dependents are notified and updated automatically.(定义对象间一种一对多的依赖关系,使得每
当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。)
步骤 【教科书式格式】
1.定义观察者接口 Observer.java
package cn.zdfy.xInterface;
//观察者
public interface Observer {
//监听到被观察者的状态变化就去更新了
public void update(String s);
}
2.定义具体的观察者 ConcreteObserver.java
package cn.zdfy.test;
import cn.zdfy.xInterface.Observer;
//具体观察者
public class ConcreteObserver implements Observer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void update(String s) {
System.out.println(this.name + "监听到张大佛爷_zhang大佬 ,正在"+s+",即将对他进行处理......");
}
}
3.定义被观察者抽象类 Subject.java
package cn.zdfy.xInterface;
import java.util.ArrayList;
import java.util.List;
// 被观察者
public abstract class Subject {
private List<Observer> obsList = new ArrayList<Observer>();
/**
* 添加一个观察者
*
* @param o
*/
public void addObserver(Observer o) {
this.obsList.add(o);
}
/**
* 删除一个观察者
*
* @param o
*/
public void removeObserver(Observer o) {
this.obsList.remove(o);
}
/**
* 通知所有观察者
*/
public void notifyObservers(String s) {
for (Observer o : this.obsList) {
o.update(s);
}
}
}
4.实现具体的被观察者 ConcreteSubject .java
package cn.zdfy.test;
import cn.zdfy.xInterface.Subject;
//具体的被观察者
public class ConcreteSubject extends Subject {
// 具体的业务
public void doSth(String s) {
super.notifyObservers(s);
}
}
5.测试类
package cn.zdfy.test;
public class test {
public static void main(String[] args) {
//创建一个被观察者
ConcreteSubject subject = new ConcreteSubject();
//创建观察者 obs1
ConcreteObserver obs1 = new ConcreteObserver();
obs1.setName("obs1");
//创建观察者 obs2
ConcreteObserver obs2 = new ConcreteObserver();
obs2.setName("obs2");
subject.addObserver(obs1); //添加观察者obs1
subject.addObserver(obs2); //添加观察者obs2
subject.doSth("吃饭");
try {
Thread.sleep(1000);
System.out.println("等待 1s 去睡觉 ==============================================");
subject.doSth("睡觉");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("//===================================移除obs1观察者后========================================//");
subject.removeObserver(obs1);
try {
Thread.sleep(1000);
System.out.println("等待 1s 去撸码 ==============================================");
subject.doSth("撸码");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
6.测试结果
obs1监听到张大佛爷_zhang大佬 ,正在吃饭,即将对他进行处理......
obs2监听到张大佛爷_zhang大佬 ,正在吃饭,即将对他进行处理......
等待 1s 去睡觉 ==============================================
obs1监听到张大佛爷_zhang大佬 ,正在睡觉,即将对他进行处理......
obs2监听到张大佛爷_zhang大佬 ,正在睡觉,即将对他进行处理......
//===================================移除obs1观察者后========================================//
等待 1s 去撸码 ==============================================
obs2监听到张大佛爷_zhang大佬 ,正在撸码,即将对他进行处理......