一、概念
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在自身的状态发生改变时则会通知所有观察者对象,让它们能更新自身的状态。因为这个特点又名:发布-订阅模式。
二、类图及基本代码
//抽象主题类
public abstract class Subject {
private List<Observer> observers=new ArrayList<>();
//添加观察者
public void Attach(Observer observer){
observers.add(observer);
}
//移除观察者
public void Detach(Observer observer){
observers.remove(observer);
}
//通知
public void Notify(){
//主题发出通知后,订阅该主题的观察者们开始更新自身状态
for (Observer observer : observers) {
observer.Update();
}
}
}
//抽象观察者
public abstract class Observer {
public abstract void Update();//更新状态
}
//具体主题
public class ConcreteSubject extends Subject{
//主题状态
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
//具体观察者
public class ConcreteObserver extends Observer {
private String observerState;
private String name;
private ConcreteSubject concreteSubject;
public ConcreteObserver(ConcreteSubject subject, String name) {
this.name = name;
this.concreteSubject = subject;
}
@Override
public void Update() {
//得到所订阅的主题的状态,然后根据该状态来进行自己的状态更新
observerState = concreteSubject.getSubjectState();
System.out.println("观察者 "+ name +"现在状态为: "+observerState);
}
public ConcreteSubject getConcreteSubject() {
return concreteSubject;
}
public void setConcreteSubject(ConcreteSubject concreteSubject) {
this.concreteSubject = concreteSubject;
}
}
//客户端
public class Show {
public static void main(String[] args) {
ConcreteSubject subject=new ConcreteSubject();
subject.Attach(new ConcreteObserver(subject, "X"));
subject.Attach(new ConcreteObserver(subject, "Y"));
subject.Attach(new ConcreteObserver(subject, "Z"));
subject.setSubjectState("ABC");
subject.Notify();
}
}
结果:
三、实例之老板回公司
//主题接口
public interface Subject {
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
String getAction();
void setAction(String action);
}
//老板---具体主题
public class Boss implements Subject {
private String action;
private List<Observer> observers = new ArrayList<>();
@Override
public void Attach(Observer observer) {
observers.add(observer);
}
@Override
public void Detach(Observer observer) {
observers.remove(observer);
}
@Override
public void Notify() {
for (Observer observer : observers) {
observer.Update();
}
}
@Override
public String getAction() {
return action;
}
@Override
public void setAction(String action) {
this.action = action;
}
}
//抽象观察者
public abstract class Observer {
protected String name;
protected Subject subject;
public Observer(String name,Subject subject){
this.name=name;
this.subject=subject;
}
public abstract void Update();
}
//看球赛的职员---具体观察者
class NBAObserver extends Observer{
public NBAObserver(String name, Subject subject) {
super(name, subject);
}
@Override
public void Update() {
System.out.println(subject.getAction()+name+"关闭NBA直播,继续工作");
}
}
//看股票的职员---具体观察者
public class StockObserver extends Observer{
public StockObserver(String name, Subject subject) {
super(name, subject);
}
@Override
public void Update() {
System.out.println(subject.getAction()+name+"关闭股票行情继续工作");
}
}
//客户端
public class Show {
public static void main(String[] args) {
Boss boss=new Boss();
StockObserver stockObserver=new StockObserver("小A", boss);
NBAObserver nbaObserver=new NBAObserver("小B", boss);
boss.Attach(stockObserver);
boss.Attach(nbaObserver);
boss.Detach(stockObserver);//小A没有接收到通知
boss.setAction("Boss回来了");
boss.Notify();
}
}
结果:
四、总结
(1)、观察者模式适用于一个主题对象的改变要同时改变其他观察者对象,且不知道具体有多少个观察者对象要改变状态。
Never frown, even when you are sad, because you never know who is falling in love with your smile.