关键字: 设计模式
观察者(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 语言的观察者 虽然实现的差异很明显,但在它们之间还是有一些相似之处。不论如何实现观察者,代码中都必须回答以下 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 版本的观察者更简单 重用:可以很容易的实现重用 |