閑人野居
          好好學習,天天向上
          posts - 57,  comments - 137,  trackbacks - 0
          觀察者(Observer)模式
          ??? 用途:定義對象之間的一對多依賴關系,因此,當一個對象的狀態發生改變時,其所有依賴項都會得到通知,并自動更新。
          ??? 它是 OO 設計模式的皇后。該模式被人們廣泛應用(特別是在 GUI 應用程序中),并構成了 MVC 架構的關鍵部分。它處理復雜的問題,而在解決這類問題方面表現得相對較好。但是,從實現需要的努力和代碼理解的角度來說,它還是帶來了一些難以解決的難題。
          ??? 不足:觀察者(Observer)模式要求您先侵入系統中現有的類,然后才能支持該模式 —— 至少在 Java 語言中是這樣。
          ??? 而方面可以降低像觀察者(Observer)模式這種侵入性模式的負擔,使得模式參與者更靈活,因為不需要包含模式代碼。而且,模式本身可以變成抽象的基本方面,允許開發人員通過導入和應用它來實現重用,不必每次都要重新考慮模式。
          ??? 下面通過一個例子來說明:
          ??? 假設如下的情況:
          ??? AccountManager 對象能夠觀察 Account,這樣,在帳戶狀態改變時,它們可以向銷售人員發送一封電子郵件。
          ??? 代碼如下:


          public class Account {

          ??? private int state;
          ???? private String name;

          ??? public String getName() {
          ??????? return name;
          ??? }
          ??? public Account(String name) {
          ??????? super();
          ??????? this.name = name;
          ??? }
          ??? public int getState() {
          ??????? return state;
          ??? }

          ??? public void setState(int state) {
          ??????? this.state = state;
          ??? }
          ???? @Override
          ??? public String toString() {
          ??????? return name;
          ??? }
          }

          public class AccountManager {

          ??? public void sendEmail(Account account) {
          ???????? System.out.println("send Email:" + account);
          ??? }
          }

          來看一下java代碼是如何實現觀察者模式的

          Java 語言的觀察者
          雖然實現的差異很明顯,但在它們之間還是有一些相似之處。不論如何實現觀察者,代碼中都必須回答以下 4 個問題:
          ?? 1. 哪個對象是主體,哪個對象是觀察者?
          ?? 2. 什么時候主體應當向它的觀察者發送通知?
          ?? 3. 當接收到通知時,觀察者應該做什么?
          ?? 4. 觀察關系應當在什么時候開始,什么時候終止?

          角色定義
          ??? 首先從標記器接口來分配角色開始。Observer 接口只定義了一個方法:update(),它對應著 Subject 發送通知時執行的操作。 Subject 承擔著更多的職責。它的標記器接口定義了兩個方法,一個用來跟蹤觀察者,另一個用來通知事件的那些觀察者。


          public interface Observer {

          ??? public void update(Subject subject);
          }

          public interface Subject {? ?
          ??? public void addObserver(Observer o);
          ??? public void removeObserver(Observer o);
          ??? public void notifyObservers();
          } ?

          一旦定義了這些角色,就可以把它們應用到系統中對應的角色上。

          應用觀察者角色


          public class AccountManager implements Observer {

          ?? public void update(Subject subject) {
          ??????? sendEmail((Account) subject);
          ??? }
          }

          跟蹤和通知觀察者
          一旦這項工作完成,就可以轉移到Subject。在這里,要對 Account進行修改:

          ? private Set observers = new HashSet(); ?
          ? public void addObserver(Observer o) {
          ??? observers.add(o);
          ? }
          ? public void removeObserver(Observer o) {
          ??? observers.remove(o);
          ? }
          ? public void notifyObservers() {
          ??? for (Observer o : observers) {
          ????? o.update(this);
          ??? }
          ? }

          觸發事件
          ??? 現在已經把類調整到它們在模式中的角色上了。但是,還需要回過頭來,在對應的事件發生時觸發通知。
          ??? Account
          ??? public void setState(int state) {
          ??????? if (this.state != state) {
          ??????????? this.state = state;
          ??????????? notifyObservers();
          ??????? }
          ??? }

          啟動觀察關系

          public class ObserverClient {

          ??? public static void main(String[] args) {
          ??????? AccountManager manager = new AccountManager();
          ??????? AccountManager manager2 = new AccountManager();
          ??????? Account account = new Account("Account1");
          ??????? account.addObserver(manager);
          ??????? account.addObserver(manager2);
          ??????? account.setState(1);
          ??? }
          }


          AspectJ 觀察者

          定義抽象類來實現觀察者

          //采用java5的泛型來定義觀察對象和主體
          public abstract class AbstractSubjectObserver<Sub, Obv> {

          ?????? //不允許空item
          ??? protected static void iaxIfNull(Object item, String name) {
          ??????? if (null == item) {
          ??????????? throw new IllegalArgumentException("null " + name);
          ??????? }
          ??? }
          ?????? //用于保存所有的主體和觀察者之間的對象關系
          ??? private final HashMap<Sub, ArrayList<Obv>> fObservers = new HashMap<Sub, ArrayList<Obv>>();

          ??? protected AbstractSubjectObserver() {

          ??? }

          ??? public synchronized void addObserver(Sub subject, Obv observer) {
          ??????? iaxIfNull(subject, "subject");
          ??????? iaxIfNull(observer, "observer");
          ??????? getObservers(subject).add(observer);
          ??? }

          ??? public synchronized void removeObserver(
          ??????????? Sub subject,
          ??????????? Obv observer) {
          ??????? iaxIfNull(subject, "subject");
          ??????? iaxIfNull(observer, "observer");
          ??????? getObservers(subject).remove(observer);
          ??? }

          ??? public synchronized ArrayList<Obv> getObservers(Sub subject) {
          ??????? iaxIfNull(subject, "subject");
          ??????? ArrayList<Observer> result = fObservers.get(subject);
          ??????? if (null == result) {
          ??????????? result = new ArrayList<Observer>();
          ??????????? fObservers.put(subject, result);
          ??????? }
          ??????? return result;
          ??? }
          ??? //主體狀態改變,更新所有的觀察者對象
          ??? protected void subjectChanged(Sub subject) {
          ??????? iaxIfNull(subject, "subject");
          ??????? ArrayList<Observer> list = getObservers(subject);
          ??????? if (!list.isEmpty()) {
          ??????????? updateObservers(subject, Collections.unmodifiableList(list));
          ??????? }
          ??? }

          ?? //更新所有觀察者操作,調用具體的updateObserver
          ??? protected synchronized void updateObservers(
          ??????????? Subject subject,
          ??????????? List<Observer> observers) {
          ??????? iaxIfNull(subject, "subject");
          ??????? iaxIfNull(observers, "observers");
          ??????? for (Observer observer : observers) {
          ??????????? updateObserver(subject, observer);
          ??????? }
          ??? }
          ???? //需要子類實現,具體的更新操作
          ??? protected abstract void updateObserver(Subject subject, Observer observer);

          }


          定義方面:
          public abstract aspect SubjectObserver<Sub, Obv> extends
          ??????? AbstractSubjectObserver<Sub, Obv> {

          ??? //需要橫切的代碼,表示哪些需要觸發觀察者模式
          ??? protected abstract pointcut changing();

          ??? //在狀態改變后,觸發所有的觀察者
          ??? after(Sub subject) returning : target(subject) && changing() {
          ??????? subjectChanged(subject);
          ??? }
          }

          無需改動原有的實現,看一下客戶端如何啟動觀察關系
          public class ObserverClient {

          ??? public static void main(String[] args) {
          ??????? Account account=new Account("Account1");
          ??????? Client client=Client.aspectOf();
          ??????? client.addObserver(account,new AccountManager());
          ??????? client.addObserver(account,new AccountManager());
          ??????? account.setState(1);
          ??? }
          ??? static aspect Client extends SubjectObserver<Account, AccountManager> {

          ??????? protected pointcut changing() : execution(void? Account.setState(int));

          ??????? protected void updateObserver(Account account, AccountManager manager) {
          ??????????? manager.sendEmail(account);
          ??????? }
          ??? }
          }


          AspectJ 觀察者的分析
          ?? 易于理解:從參與者的視角來看,AOP 版本的觀察者更簡單
          ?? 重用:可以很容易的實現重用



          posted on 2006-11-17 16:55 布衣郎 閱讀(1422) 評論(0)  編輯  收藏 所屬分類: aop

          <2006年11月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          常用鏈接

          留言簿(12)

          隨筆分類(59)

          隨筆檔案(57)

          blog

          java

          uml

          搜索

          •  

          積分與排名

          • 積分 - 357330
          • 排名 - 155

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 株洲县| 宁阳县| 九寨沟县| 汉沽区| 象山县| 仪陇县| 临沧市| 白银市| 扶绥县| 凭祥市| 泰宁县| 徐汇区| 邯郸县| 中西区| 广州市| 孟连| 南郑县| 项城市| 剑川县| 峡江县| 荃湾区| 岳西县| 文登市| 合川市| 玉门市| 偏关县| 竹山县| 昂仁县| 涞源县| 扬中市| 宁陵县| 通山县| 栖霞市| 浦北县| 年辖:市辖区| 泾源县| 陕西省| 金坛市| 闻喜县| 谢通门县| 儋州市|