目前這篇觀察者是自己剛整理的,很多都來源於網上,自己目前沒有設計模式的書,自己過一段時間買完書,重新理解完,會回來整理的。
定義對象之間的一對多依賴,當一個對象狀態改變時,它的所有依賴都會收到通知並且自動更新狀態。
主題(Subject)是被觀察的對象,而其所有依賴者(Observer)稱爲觀察者。
觀察者模式所涉及的角色有:
● 抽象主題(Subject)角色:抽象主題角色把所有對觀察者對象的引用保存在一個聚集(比如ArrayList對象)裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽象被觀察者(Observable)角色。
● 具體主題(ConcreteSubject)角色:將有關狀態存入具體觀察者對象;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色又叫做具體被觀察者(Concrete Observable)角色。
● 抽象觀察者(Observer)角色:爲所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。
● 具體觀察者(ConcreteObserver)角色:存儲與主題的狀態自恰的狀態。具體觀察者角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態 像協調。如果需要,具體觀察者角色可以保持一個指向具體主題對象的引用。
模型
推模型
主題對象向觀察者推送主題的詳細信息,不管觀察者是否需要,推送的信息通常是主題對象的全部或部分數據。
拉模型
主題對象在通知觀察者的時候,只傳遞少量信息。如果觀察者需要更具體的信息,由觀察者主動到主題對象中獲取,相當於是觀察者從主題對象中拉數據。一般這種模型的實現中,會把主題對象自身通過update()方法傳遞給觀察者,這樣在觀察者需要獲取數據的時候,就可以通過這個引用來獲取了。
推模型
/**
* 抽象觀察者角色
*
*/
public interface Observer {
void update(String state);
String getName();
}
/**
* @desc 具體觀察者
* @date 2017年5月13日 下午5:11:52
*/
public class ConcreteObserver implements Observer {
private String name;
private String state;
public ConcreteObserver(String name) {
this.name = name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public void update(String state) {
// 更新觀察着狀態
this.state = state;
System.out.println(getName() + "觀察者狀態更新爲:" + state);
}
@Override
public String getName() {
return name;
}
}
import java.util.ArrayList;
import java.util.List;
/**
* 抽象主題角色類
*/
public abstract class Subject {
/**
* 保存觀察者的容器
*/
private List<Observer> list = new ArrayList<Observer>();
/**
* 註冊觀察者
*/
public void register(Observer o) {
list.add(o);
System.out.println("增加了一個觀察者:" + o.getName());
}
/**
* 移除觀察者
*
* @param o
*/
public void remove(Observer o) {
System.out.println("移除了一個觀察者:" + o.getName());
list.remove(o);
}
/**
* 通知觀察者
*
* @param newState
*/
public void nodifyObservers(String newState) {
for (Observer observer : list) {
observer.update(newState);
}
}
}
/**
* 具體主題角色
*/
public class ConcreteSubject extends Subject {
/**
* 狀態
*/
private String state;
public String getState() {
return state;
}
public void change(String newState) {
state = newState;
System.out.println("狀態變爲:" + newState);
System.out.println("開始通知觀察者...");
this.nodifyObservers(state);
}
}
/**
* @desc 測試觀察者模式
* @date 2017年5月13日 下午5:18:30
*/
public class MainTest {
public static void main(String[] args) {
Observer o1 = new ConcreteObserver("o1");
Observer o2 = new ConcreteObserver("o2");
Observer o3 = new ConcreteObserver("o3");
ConcreteSubject csj = new ConcreteSubject();
csj.register(o1);
csj.register(o2);
csj.register(o3);
csj.remove(o2);
csj.change("new State!");
}
}
拉模型
/**
* 抽象觀察者角色
*
*/
public interface Observer {
/**
* 傳入主題,獲取中的對象
* @param subject
*/
void update(Subject subject);
String getName();
}
/**
* @desc 具體觀察者
*/
public class ConcreteObserver implements Observer {
private String name;
private String state;
public ConcreteObserver(String name) {
this.name = name;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
@Override
public String getName() {
return name;
}
@Override
public void update(Subject subject) {
// 主動去主題裏拿數據
state = ((ConcreteSubject) subject).getState();
System.out.println(getName() + "觀察者狀態更新爲:" + state);
}
}
import java.util.ArrayList;
import java.util.List;
/**
* 抽象主題角色類
*
*/
public abstract class Subject {
/**
* 保存觀察者的容器
*/
private List<Observer> list = new ArrayList<Observer>();
/**
* 註冊觀察者
*/
public void register(Observer o) {
list.add(o);
System.out.println("增加了一個觀察者:" + o.getName());
}
/**
* 移除觀察者
*
* @param o
*/
public void remove(Observer o) {
System.out.println("移除了一個觀察者:" + o.getName());
list.remove(o);
}
/**
* 通知觀察者
*
* @param newState
*/
public void nodifyObservers() {
for (Observer observer : list) {
observer.update(this);
}
}
}
/**
* 具體主題角色
*
*/
public class ConcreteSubject extends Subject {
/**
* 狀態
*/
private String state;
public String getState() {
return state;
}
public void change(String newState) {
state = newState;
System.out.println("狀態變爲:" + newState);
System.out.println("開始通知觀察者...");
this.nodifyObservers();
}
}
/**
* @desc 測試觀察者模式(拉模式)
*/
public class MainTest {
public static void main(String[] args) {
Observer o1 = new ConcreteObserver("o1");
Observer o2 = new ConcreteObserver("o2");
Observer o3 = new ConcreteObserver("o3");
ConcreteSubject csj = new ConcreteSubject();
csj.register(o1);
csj.register(o2);
csj.register(o3);
csj.remove(o2);
csj.change("new State!");
}
}