观察者模式(ObserverPattern):观察者模式又称发布-订阅(Publish/Subscribe)模式,定义了一个中一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
UML图:
Subject:
package com.cnblog.clarck;
import java.util.ArrayList;
import java.util.List;
/**
* 主题/抽象通知者
*
* @author clarck
*
*/
public class Subject {
private List<Observer> observers = new ArrayList<Observer>();
/**
* 添加观察者
*
* @param observer
*/
public void attach(Observer observer) {
observers.add(observer);
}
/**
* 移除观察者
*
* @param observer
*/
public void detach(Observer observer) {
observers.remove(observer);
}
/**
* 通知
*/
public void notification() {
for (Observer observer : observers) {
observer.update();
}
}
}
Observer:
package com.cnblog.clarck;
/**
* 抽象观察者
*
* @author clarck
*
*/
public abstract class Observer {
public abstract void update();
}
ConcrateSubject:
package com.cnblog.clarck;
/**
* 具体主题/具体通知者
*
* @author clarck
*
*/
public class ConcrateSubject extends Subject {
private String mSubjectState;
public String getSubjectState() {
return mSubjectState;
}
public void setSubjectState(String mSubjectState) {
this.mSubjectState = mSubjectState;
}
}
ConcrateObserver:
package com.cnblog.clarck;
/**
* 具体观察者
*
* @author clarck
*
*/
public class ConcrateObserver extends Observer {
private String mName;
private String mObserverState;
private ConcrateSubject mSubject;
public ConcrateObserver(ConcrateSubject subject, String name) {
mSubject = subject;
mName = name;
}
@Override
public void update() {
mObserverState = mSubject.getSubjectState();
String format = String.format("观察者%s的新状态是%s", mName, mObserverState);
System.out.println(format);
}
public ConcrateSubject getmSubject() {
return mSubject;
}
public void setmSubject(ConcrateSubject mSubject) {
this.mSubject = mSubject;
}
}
Client:
package com.cnblog.clarck;
public class Client {
public static void main(String[] args) {
ConcrateSubject concrateSubject = new ConcrateSubject();
concrateSubject.attach(new ConcrateObserver(concrateSubject, "X"));
concrateSubject.attach(new ConcrateObserver(concrateSubject, "Y"));
concrateSubject.attach(new ConcrateObserver(concrateSubject, "Z"));
concrateSubject.setSubjectState("ABC");
concrateSubject.notification();
}
}