zoukankan      html  css  js  c++  java
  • 设计模式之观察者设计模式

    观察者模式定义:

          它是对象的行为模式,它有叫做发布/订阅模式(redis中有这样的概念),模型/视图模式,源/监听器模式或从属模式。它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当这个主题发生改变时,会通知所有他的观察者对象,使之跟随改变更新。

          为什么会有这种设计模式呢?在一个软件生态中,对象之间依赖当一个改变时会有相应的其它对象发生改变。能完成这个问题的方案有很多,但是为了使系统能够易于复用,应选择耦合度较低的方案,减少对象之间的耦合有利于系统的复用,但是同时也应该使这些低耦合对象之间维持行动协调一致,保证高度协作。所以观察者设计模式就出现了。

       它的类图如下图所示:

    从类图中可观察到一下几个概念:

           Subject(抽象主题)角色:首先它是一个interface,它维护的一个集合保存所有的观察者,并且提供增加和删除观察者对象和通知所有观察者对象的方法。一般他有被称为Observable(自jdk.1.0 本身库中包含这个类后面会说到)角色,一般用接口或抽象类来表示。

           Observer(抽象观察者)角色:为所有具体观察者定义一个接口,在得到一个主题时通知更新自己,也叫作更新接口。他通常使用接口或抽象类实现。可看到它通常只包含一个方法(update()).

           ConcreteSubject(具体主题)角色:将有关状态存入具体观察者对象,在具体主题发生改变是,给所有登记过的具体观察者发送通知。

          ConcreteObserver(具体观察者)角色:存储与主题状态相关的自状态。

    简单实现,代码如下:

       Subject接口:

    1 package com.obserable;
    2 public interface Subject {
    3       void addObserver(Observer observer);
    4       void delObserver(Observer observer);
    5       void notifyall();
    6 }

    SubjectImpl实现类:

     1 package com.obserable;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 import java.util.List;
     6 
     7 public class SubjectImpl implements Subject {
     8       private List<Observer> list = new ArrayList<Observer>();
     9     @Override
    10     public void addObserver(Observer observer) {
    11         // TODO Auto-generated method stub
    12      list.add(observer);
    13     }
    14 
    15     @Override
    16     public void delObserver(Observer observer) {
    17         // TODO Auto-generated method stub
    18   list.remove(observer);
    19     }
    20 
    21     @Override
    22     public void notifyall() {
    23         Iterator<Observer> iter = list.iterator();
    24         while(iter.hasNext()){
    25             iter.next().update();
    26         }
    27     }
    28 
    29 }

    Observer接口:

    1 package com.obserable;
    2 
    3 public interface Observer {
    4     void update();
    5 }

    ObserverImpl实现类:

     1 package com.obserable;
     2 
     3 public class ObserverImpl implements Observer{
     4      private String name;
     5      
     6     public ObserverImpl(String name) {
     7         super();
     8         this.name = name;
     9     }
    10 
    11     @Override
    12     public void update() {
    13         System.out.println(name+"I am notify");
    14     }
    15 
    16 }

    测试类:

     1 package com.obserable;
     2 
     3 public class Test {
     4     public static void main(String[] args) {
     5         Subject sub = new SubjectImpl();
     6         sub.addObserver(new ObserverImpl("王五"));
     7         sub.addObserver(new ObserverImpl("王五1"));
     8         sub.addObserver(new ObserverImpl("王五2"));
     9         sub.notifyall();
    10     }
    11 
    12 
    13 }

    结果:

    王五I am notify
    王五1I am notify
    王五2I am notify

    还可以使用抽象类来实现Subject,Observer不变;

     1 package com.obserable;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 import java.util.List;
     6 
     7 public abstract class AbstractSubjct {
     8 
     9     private List<Observer> list = new ArrayList<Observer>();
    10     public void addObserver(Observer observer) {
    11    list.add(observer);
    12     }
    13 
    14     public void delObserver(Observer observer) {
    15         // TODO Auto-generated method stub
    16 list.remove(observer);
    17     }
    18     public void notifyall() {
    19         Iterator<Observer> iter = list.iterator();
    20         while(iter.hasNext()){
    21             iter.next().update();
    22         }
    23     }
    24 
    25 
    26 }

    抽象类的实现类:

     1 package com.obserable;
     2 
     3 public class JtSubject extends AbstractSubjct{
     4   private String state;
     5   
     6   public void change(String state){
     7       this.state=state;
     8       notifyall();
     9   }
    10 }

    Observer不变。

    测试类:

     1 package com.obserable;
     2 
     3 public class AbsTest {
     4      public static void main(String[] args) {
     5          JtSubject as = new JtSubject();
     6         as.addObserver(new ObserverImpl("王五"));
     7         as.addObserver(new ObserverImpl("王五1"));
     8         as.addObserver(new ObserverImpl("王五2"));
     9         as.change("hello");
    10     }
    11 }

    结果:

    王五I am notify
    王五1I am notify
    王五2I am notify

    因为此模式在实际应用中广泛,所以自jdk1.0就纳入的本身库。

    Observer接口,等同于上述的Observer,只有一个update方法。

     1  * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
     2 package java.util;
     3 
     4 /**
     5  * A class can implement the <code>Observer</code> interface when it
     6  * wants to be informed of changes in observable objects.
     7  *
     8  * @author  Chris Warth
     9  * @see     java.util.Observable
    10  * @since   JDK1.0
    11  */
    12 public interface Observer {
    13     /**
    14      * This method is called whenever the observed object is changed. An
    15      * application calls an <tt>Observable</tt> object's
    16      * <code>notifyObservers</code> method to have all the object's
    17      * observers notified of the change.
    18      *
    19      * @param   o     the observable object.
    20      * @param   arg   an argument passed to the <code>notifyObservers</code>
    21      *                 method.
    22      */
    23     void update(Observable o, Object arg);
    24 }

    再看jdk中Observable类,他是一个可实例化类。

     1  * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
     2 
     3 package java.util;
     4 public class Observable {
     5     private boolean changed = false;
     6     private Vector<Observer> obs;
     7 
     8     /** Construct an Observable with zero Observers. */
     9 
    10     public Observable() {
    11         obs = new Vector<>();
    12     }
    13 
    14   
    15     public synchronized void addObserver(Observer o) {
    16         if (o == null)
    17             throw new NullPointerException();
    18         if (!obs.contains(o)) {
    19             obs.addElement(o);
    20         }
    21     }
    22 
    23   
    24     public synchronized void deleteObserver(Observer o) {
    25         obs.removeElement(o);
    26     }
    27 
    28   
    29     public void notifyObservers() {
    30         notifyObservers(null);
    31     }
    32 
    33  
    34     public void notifyObservers(Object arg) {
    35      
    36         Object[] arrLocal;
    37 
    38         synchronized (this) {
    39          
    40             if (!changed)
    41                 return;
    42             arrLocal = obs.toArray();
    43             clearChanged();
    44         }
    45 
    46         for (int i = arrLocal.length-1; i>=0; i--)
    47             ((Observer)arrLocal[i]).update(this, arg);
    48     }
    49 
    50    
    51     public synchronized void deleteObservers() {
    52         obs.removeAllElements();
    53     }
    54 
    55     protected synchronized void setChanged() {
    56         changed = true;
    57     }
    58 
    59     protected synchronized void clearChanged() {
    60         changed = false;
    61     }
    62 
    63     public synchronized boolean hasChanged() {
    64         return changed;
    65     }
    66 
    67     public synchronized int countObservers() {
    68         return obs.size();
    69     }
    70 }

    可以看到它是线程安全的,方法是有synchronizednchronized修饰的,而且维护的Observer集合使用的Vector。

    使用方法和上述一样。

  • 相关阅读:
    解决IE6浏览器下position:fixed固定定位问题
    CSS中overflow:hidden在ie6、ie7无效不能隐藏解决办法
    liunx 中删除export设置的环境变量
    文件操作
    集合操作
    三级菜单
    字典操作
    字符串操作
    购物车程序
    列表操作
  • 原文地址:https://www.cnblogs.com/swfzzz/p/12049162.html
Copyright © 2011-2022 走看看