標籤:
觀察者模式 Observer(行為型模式)
1.概述
觀察者模式:定義對象之間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象皆得到通知並被自動更新。
例1:開車的司機作為觀察者,路上的紅綠燈作為觀察目標,當紅綠燈的顏色狀態發生改變時,司機得到通知,並更新自己的行為。
例2:一個能夠顯示商品資訊的頁面,當資料庫的關於商品的資訊發生改變時,頁面的資訊也會發生相應的改變。
2.結構圖
3.代碼
代碼簡述:玩魔獸爭霸這類遊戲時,隊友遭到敵人攻擊,地圖上會有紅色標記提示,其他隊友作為觀察者,更新自己的狀態,前去支援。
1 import java.util.ArrayList; 2 3 /* 4 * 抽象觀察目標類 5 */ 6 public abstract class Subject { 7 8 //儲存所有具體的觀察者 9 protected ArrayList<Observer> players = new ArrayList<Observer>(); 10 public Subject() {11 12 }13 14 //加入方法 15 public void attach(Observer obs) { 16 System.out.println(obs.getName() + "加入"); 17 players.add(obs); 18 } 19 20 //退出方法 21 public void detach(Observer obs) { 22 System.out.println(obs.getName() + "退出"); 23 players.remove(obs); 24 } 25 26 //聲明抽象通知方法 27 public abstract void notify(String name); 28 29 }
1 /* 2 * 具體觀察目標類 3 */ 4 public class ConcreteSubject extends Subject { 5 6 public ConcreteSubject() { 7 // TODO Auto-generated constructor stub 8 } 9 10 @Override11 public void notify(String name) {12 //遍曆觀察者集合,調用每一個觀察者(自己除外)的更新方法 13 for(Object obs : players) { 14 if (!((Observer)obs).getName().equalsIgnoreCase(name)) { 15 ((Observer)obs).update(); 16 } 17 } 18 19 }20 21 }
1 /* 2 * 抽象觀察者 3 */ 4 interface Observer { 5 6 public String getName(); 7 public void setName(String name); 8 public void update(); 9 public void beAttacked(Subject s); 10 11 }
1 /* 2 * 具體觀察者 3 */ 4 public class ConcreteObserver implements Observer { 5 6 private String name; 7 public ConcreteObserver(String name) { 8 this.name = name; 9 }10 @Override11 public String getName() {12 return this.name; 13 }14 @Override15 public void setName(String name) {16 this.name = name; 17 18 }19 20 //更新自己的狀態21 @Override22 public void update() {23 System.out.println(name+"前去支援");24 25 }26 27 @Override28 public void beAttacked(Subject s) {29 System.out.println(name+"遭到攻擊");30 s.notify(this.name);31 32 }33 34 }
1 public class Test { 2 3 public static void main(String[] args) { 4 ConcreteSubject s = new ConcreteSubject() ; 5 6 Observer o1,o2,o3 ; 7 o1 = new ConcreteObserver("A隊員"); 8 o2 = new ConcreteObserver("B隊員"); 9 o3 = new ConcreteObserver("C隊員");10 11 s.attach(o1);12 s.attach(o2);13 s.attach(o3);14 15 o1.beAttacked(s);16 17 }18 19 }
4.適用情境
(1)一個對象的改變將導致一個或多個其他對象也發生改變,而並不知道具體有多少對象將發生改變,也不知道這些對象是誰。
(2)一個抽象模型有兩個方面,其中一個方面依賴於另一個方面,將這兩個方面封裝在獨立的對象中使它們可以各自獨立地改變和複用。讓耦合的雙方都依賴於抽象,而不是依賴於具體。從而使各自的變化都不會影響到另一邊的變化。
設計模式(13)---觀察者模式