用AOP实现观察者模式

观察者(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


定义方面:
public abstract aspect SubjectObserver

无需改动原有的实现,看一下客户端如何启动观察关系
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

AspectJ 观察者的分析
   易于理解:从参与者的视角来看,AOP 版本的观察者更简单
   重用:可以很容易的实现重用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值