分享

什么时候使用观察者模式

 liang1234_ 2017-10-26 发布于安徽

1)        当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

2)        当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。

3)        当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。

其实观察者模式同前面讲过的桥梁、策略有着共同的使用环境:将变化独立封装起来,以达到最大的重用和解耦。观察者与后两者不同的地方在于,观察者模式中的目标和观察者的变化不是独立的,而是有着某些联系。

 

典型用例:hibernate

 

 

下面通过一个例子来说明:
    假设如下的情况:
    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);
    }
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多