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


    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代碼是如何實現(xiàn)觀察者模式的

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

    角色定義
    ??? 首先從標記器接口來分配角色開始。Observer 接口只定義了一個方法:update(),它對應著 Subject 發(fā)送通知時執(zhí)行的操作。 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();
    } ?

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

    應用觀察者角色


    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);
    ??? }
    ? }

    觸發(fā)事件
    ??? 現(xiàn)在已經(jīng)把類調整到它們在模式中的角色上了。但是,還需要回過頭來,在對應的事件發(fā)生時觸發(fā)通知。
    ??? 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 觀察者

    定義抽象類來實現(xiàn)觀察者

    //采用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;
    ??? }
    ??? //主體狀態(tài)改變,更新所有的觀察者對象
    ??? 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);
    ??????? }
    ??? }
    ???? //需要子類實現(xiàn),具體的更新操作
    ??? protected abstract void updateObserver(Subject subject, Observer observer);

    }


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

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

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

    無需改動原有的實現(xiàn),看一下客戶端如何啟動觀察關系
    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 版本的觀察者更簡單
    ?? 重用:可以很容易的實現(xiàn)重用



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

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

    常用鏈接

    留言簿(12)

    隨筆分類(59)

    隨筆檔案(57)

    blog

    java

    uml

    搜索

    •  

    積分與排名

    • 積分 - 358005
    • 排名 - 156

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: xvideos永久免费入口| 亚洲一区二区观看播放| 国产黄片不卡免费| 亚洲国产中文字幕在线观看 | 日本红怡院亚洲红怡院最新| a免费毛片在线播放| 亚洲午夜av影院| aa级女人大片喷水视频免费| 亚洲gv猛男gv无码男同短文| 免费无码一区二区三区蜜桃| 亚洲国产精品久久久久久| 8x网站免费入口在线观看| 亚洲精品熟女国产| 91精品成人免费国产片| 2020国产精品亚洲综合网| 在线观看免费宅男视频| 免费看一级高潮毛片| 亚洲精品成人无限看| 亚洲视频免费播放| 亚洲性无码一区二区三区| 亚洲第一区在线观看| 叮咚影视在线观看免费完整版| 亚洲高清免费在线观看| 日韩一级视频免费观看| jizz日本免费| 99人中文字幕亚洲区| 日韩电影免费在线观看视频| h片在线观看免费| 久久久无码精品亚洲日韩京东传媒| 免费av欧美国产在钱| 免费看美女午夜大片| 亚洲黄网站wwwwww| 日本免费人成视频播放| 免费无码一区二区三区蜜桃 | 美女被爆羞羞网站免费| 国产亚洲3p无码一区二区| 欧美日韩国产免费一区二区三区| 特a级免费高清黄色片 | 亚洲色大网站WWW永久网站| AV在线亚洲男人的天堂| 久久www免费人成看片|