定義: 定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。 結構:(書中圖,侵刪) 一個抽象的觀察者介面,擁有一個更新方法 若幹個具體的觀察者類 一個抽象的subject類,包含一個抽象觀察者的集合,並擁有 ...
定義:
定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。
結構:(書中圖,侵刪)
一個抽象的觀察者介面,擁有一個更新方法 若幹個具體的觀察者類 一個抽象的subject類,包含一個抽象觀察者的集合,並擁有增加、刪除觀察者的方法,以及一個通知的方法 若幹個具體subject類實例:
舉個看球賽的例子吧。 假設比賽在主場比。 subject就是球賽賽況;具體的subject分為現場看、電視上看。 然後觀察者分為主場球迷,客場球迷。 抽象觀察者介面(球迷介面):package designpattern.observer; public interface Fans { public void react(String result); }具體球迷類: 主場球迷:
package designpattern.observer; public class HomeFans implements Fans { @Override public void react(String result) { System.out.print("主場球迷:"); if (result.equals("win")) { System.out.println("Yes! 我們贏啦,主場就是牛批!!!"); } else { System.out.println("輸了,哎..."); } } }客場球迷:
package designpattern.observer; public class AwayFans implements Fans { @Override public void react(String result) { System.out.print("客場球迷:"); if (result.equals("win")) { System.out.println("輸了,哎..."); } else { System.out.println("Yes! 客場都贏啦,牛批!!!"); } } }抽象subject介面(比賽介面):
package designpattern.observer; import java.util.ArrayList; import java.util.List; public interface Match { List<Fans> fansList = new ArrayList<>();// 這一句 void addFans(Fans fans); void removeFans(Fans fans); void notifyResult(String result); }註釋的那一句說明一下: 書中這句就是寫在介面里的,但是寫在這裡就是一個全局的,所有子類都共用這同一個list 但我自己感覺各個子類所需要通知的觀察者應該是不一定一樣的,所以我是改到了子類中 但我後來寫總結的時候回看定義,發現,總結寫的就是“一對多的依賴關係”,既然不是多對多,那自然觀察者就是統一調配的 只不過還是感覺有點怪怪的,往集合里添加刪除觀察者的方法是不是改成靜態方法會好一點? 不然,必須要實例化一個子類的對象才能調用。 現場看比賽:
package designpattern.observer; import java.util.ArrayList; import java.util.List; public class MatchOnTheSpot implements Match { // List<Fans> fansList = new ArrayList<>(); @Override public void addFans(Fans fans) { fansList.add(fans); } @Override public void removeFans(Fans fans) { fansList.remove(fans); } @Override public void notifyResult(String result) { for (Fans fans : fansList) { fans.react(result); } } }電視看比賽:
package designpattern.observer; import java.util.ArrayList; import java.util.List; public class MatchOnTheTV implements Match { // List<Fans> fansList = new ArrayList<>(); @Override public void addFans(Fans fans) { fansList.add(fans); } @Override public void removeFans(Fans fans) { fansList.remove(fans); } @Override public void notifyResult(String result) { for (Fans fans : fansList) { fans.react(result); } } }此例中,兩個子類的代碼完全相同,可以把介面改成抽象類,然後把方法寫到父類中,我這裡就不改了。 客戶端:
package designpattern.observer; public class Client { public static void main(String[] args) { HomeFans homeFans = new HomeFans(); AwayFans awayFans = new AwayFans(); // 現場看 Match match = new MatchOnTheSpot(); match.addFans(homeFans); match.addFans(awayFans); System.out.println("主場贏啦~"); match.notifyResult("win"); System.out.println("==========================="); // 電視上看 match = new MatchOnTheTV(); System.out.println("主場輸啦~"); match.notifyResult("lose"); } }結果輸出:
主場贏啦~ 主場球迷:Yes! 我們贏啦,主場就是牛批!!! 客場球迷:輸了,哎... =========================== 主場輸啦~ 主場球迷:輸了,哎... 客場球迷:Yes! 客場都贏啦,牛批!!!