<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    閑人野居
    好好學習,天天向上
    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

    搜索

    •  

    積分與排名

    • 積分 - 357268
    • 排名 - 155

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 黄+色+性+人免费| 免费无码H肉动漫在线观看麻豆| 亚洲精品成人久久久| 亚洲最大无码中文字幕| 成人免费福利视频| 亚洲神级电影国语版| 成熟女人特级毛片www免费| baoyu116.永久免费视频| 久久久久国产精品免费免费不卡| 亚洲欧洲精品成人久久奇米网| 无码AV动漫精品一区二区免费| 国产女高清在线看免费观看| 男女猛烈xx00免费视频试看| 99精品免费观看| 亚洲国产成人久久综合一区| 欧洲乱码伦视频免费国产 | 最近国语视频在线观看免费播放| 日日噜噜噜噜夜夜爽亚洲精品| 中文字幕乱码系列免费| 亚洲av永久无码精品表情包| 国产精品成人亚洲| 亚洲色婷婷综合开心网| 久久久久免费精品国产| 亚洲日韩乱码久久久久久| 男女啪啪永久免费观看网站| 黄色免费网址大全| 亚洲一区影音先锋色资源| www.xxxx.com日本免费| 久久精品国产亚洲AV麻豆王友容 | 中文字幕精品亚洲无线码一区| 免费看一区二区三区四区| 亚洲福利视频网址| 香蕉视频在线观看免费国产婷婷 | 自拍偷自拍亚洲精品情侣| **真实毛片免费观看 | 精选影视免费在线 | 免费成人在线观看| 亚洲精品乱码久久久久久V| 亚洲人成电影网站国产精品 | 国产黄片不卡免费| 亚洲国产高清视频在线观看|