观察者模式

转自:http://blog.csdn.net/lansuiyun/article/details/11396815

观察者模式又名发布-订阅模式,定义了对象之间的一对多依赖,多个对象同时监听一个对象,当被监听对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新,被监听对象称为主题suject,监听对象称为观察者observer。

观察者模式结构如下(网上找的图):


简单来说,observer必须实现update方法,来接收suject状态变化时的通知及更新。suject维护一个observer列表,在状态变化时会逐个的调用observer的update方法来通知、更新observer,为此,suject须提供注册(添加observer到列表)、删除、通知更新三个方法。

观察者模式又分为两种模式:push和pull。push是指suject在状态变化时将所有的状态信息都发给observer,pull则是suject通知observer更新时,observer获取自己感兴趣的状态。

两种模式在实现上的区别:push模式下,observer的update方法接收的是状态信息,而pull模式下,update方法接收的是suject对象,这种情况下,suject须提供状态信息的get方法,让observer可以获取自己感兴趣的信息。

两种模式的优劣:push模式要求suject必须了解observer需要的状态,pull则是observer按需获取;push模式下observer的update方法的参数是具体的状态信息,发生变化时必须要重写update方法,pull模式则是将suject对象本身传给update,是最大的参数集合。

push模式具体实现:

  • suject超类
    [java]  view plain copy
    1. package observer.push;  
    2.   
    3. import java.util.LinkedList;  
    4. import java.util.List;  
    5.   
    6. /** 
    7.  * 推模式主题超类,能够注册、删除、数据变动时通知关注者 
    8.  * @author sky 
    9.  * 
    10.  */  
    11. public abstract class Subject {  
    12.     /** 
    13.      * 观察者名单 
    14.      */  
    15.     private List<Observer> list = new LinkedList<>();  
    16.     /** 
    17.      * 注册观察者 
    18.      * @param o 观察者 
    19.      */  
    20.     public void addObserver(Observer o){  
    21.         list.add(o);  
    22.     }  
    23.     /** 
    24.      * 删除观察者 
    25.      * @param o 观察者 
    26.      */  
    27.     public void deleteObserver(Observer o){  
    28.         int i = list.indexOf(o);  
    29.         if (i>-1) {  
    30.             list.remove(i);  
    31.         }  
    32.     }  
    33.     /** 
    34.      * 通知观察者 
    35.      */  
    36.     public void notifyObservers(String state){  
    37.         for (Observer o:list) {  
    38.             o.update(state);  
    39.         }  
    40.     }  
    41. }  
  • observer接口
    [java]  view plain copy
    1. package observer.push;  
    2. /** 
    3.  * 推模式观察者接口 
    4.  * @author sky 
    5.  * 
    6.  */  
    7. public interface Observer {  
    8.       
    9.     public void update(String state);  
    10.   
    11. }  
  • suject具体实现类
    [java]  view plain copy
    1. package observer.push;  
    2.   
    3. public class ConcreteSubject extends Subject {  
    4.     /** 
    5.      * 状态 
    6.      */  
    7.     public String state;  
    8.     /** 
    9.      * 状态是否改变的标志 
    10.      */  
    11.     public boolean isChanged = false;  
    12.       
    13.     /** 
    14.      * 状态改变后,通知观察者 
    15.      */  
    16.     public void change(){  
    17.         if (isChanged) {  
    18.             this.notifyObservers(state);  
    19.         }  
    20.     }  
    21.   
    22.     public String getState() {  
    23.         return state;  
    24.     }  
    25.   
    26.     public void setState(String state) {  
    27.         this.state = state;  
    28.         isChanged = true;  
    29.     }  
    30.   
    31.     public boolean isChanged() {  
    32.         return isChanged;  
    33.     }  
    34.   
    35.     public void setChanged(boolean isChanged) {  
    36.         this.isChanged = isChanged;  
    37.     }  
    38.       
    39.       
    40.   
    41. }  


  • observ具体实现类
    [java]  view plain copy
    1. package observer.push;  
    2. /** 
    3.  * 推模式观察者实现类 
    4.  * @author sky 
    5.  * 
    6.  */  
    7. public class ConcreteObserver implements Observer {  
    8.       
    9.     public String name;  
    10.       
    11.     public ConcreteObserver(String n){  
    12.         name=n;  
    13.     }  
    14.   
    15.     @Override  
    16.     public void update(String state) {  
    17.         System.out.println(name+" update new state:"+state);  
    18.           
    19.     }  
    20.   
    21. }  
  • 测试类:
    [java]  view plain copy
    1. package observer.push;  
    2.   
    3. public class Test {  
    4.   
    5.     /** 
    6.      * @param args 
    7.      */  
    8.     public static void main(String[] args) {  
    9.         ConcreteSubject subject = new ConcreteSubject();  
    10.         Observer o1 = new ConcreteObserver("张山");  
    11.         Observer o2 = new ConcreteObserver("李四");  
    12.         subject.addObserver(o1);  
    13.         subject.addObserver(o2);  
    14.         System.out.println("准备:");  
    15.         subject.setState("上班了");  
    16.         subject.change();  
    17.         subject.setState("下班了");  
    18.         subject.change();  
    19.     }  
    20.   
    21. }  

  • 输出:
    [java]  view plain copy
    1. 准备:  
    2. 张山 update new state:上班了  
    3. 李四 update new state:上班了  
    4. 张山 update new state:下班了  
    5. 李四 update new state:下班了  

pull模式实现:

  • suject超类
    [java]  view plain copy
    1. package observer.pull;  
    2.   
    3. import java.util.LinkedList;  
    4. import java.util.List;  
    5.   
    6. /** 
    7.  * 拉模式主题超类,能够注册、删除、数据变动时通知关注者 
    8.  * @author sky 
    9.  * 
    10.  */  
    11. public abstract class Subject {  
    12.     /** 
    13.      * 观察者名单 
    14.      */  
    15.     private List<Observer> list = new LinkedList<>();  
    16.     /** 
    17.      * 注册观察者 
    18.      * @param o 观察者 
    19.      */  
    20.     public void addObserver(Observer o){  
    21.         list.add(o);  
    22.     }  
    23.     /** 
    24.      * 删除观察者 
    25.      * @param o 观察者 
    26.      */  
    27.     public void deleteObserver(Observer o){  
    28.         int i = list.indexOf(o);  
    29.         if (i>-1) {  
    30.             list.remove(i);  
    31.         }  
    32.     }  
    33.     /** 
    34.      * 通知观察者 
    35.      */  
    36.     public void notifyObservers(){  
    37.         for (Observer o:list) {  
    38.             o.update(this);  
    39.         }  
    40.     }  
    41. }  


  • observer接口
    [java]  view plain copy
    1. package observer.pull;  
    2. /** 
    3.  * 拉模式观察者接口 
    4.  * @author sky 
    5.  * 
    6.  */  
    7. public interface Observer {  
    8.       
    9.     public void update(Subject s);  
    10.   
    11. }  


  • suject具体实现类
    [java]  view plain copy
    1. package observer.pull;  
    2.   
    3. public class ConcreteSubject extends Subject {  
    4.     /** 
    5.      * 状态 
    6.      */  
    7.     public String state;  
    8.     /** 
    9.      * 状态是否改变的标志 
    10.      */  
    11.     public boolean isChanged = false;  
    12.       
    13.     /** 
    14.      * 状态改变后,通知观察者 
    15.      */  
    16.     public void change(){  
    17.         if (isChanged) {  
    18.             this.notifyObservers();  
    19.         }  
    20.     }  
    21.   
    22.     public String getState() {  
    23.         return state;  
    24.     }  
    25.   
    26.     public void setState(String state) {  
    27.         this.state = state;  
    28.         isChanged = true;  
    29.     }  
    30.   
    31.     public boolean isChanged() {  
    32.         return isChanged;  
    33.     }  
    34.   
    35.     public void setChanged(boolean isChanged) {  
    36.         this.isChanged = isChanged;  
    37.     }  
    38.       
    39.       
    40.   
    41. }  


  • observer具体实现类
    [java]  view plain copy
    1. package observer.pull;  
    2. /** 
    3.  * 拉模式观察者实现类 
    4.  * @author sky 
    5.  * 
    6.  */  
    7. public class ConcreteObserver implements Observer {  
    8.       
    9.     public String name;  
    10.       
    11.     public ConcreteObserver(String n){  
    12.         name=n;  
    13.     }  
    14.   
    15.     @Override  
    16.     public void update(Subject s) {  
    17.         String state = ((ConcreteSubject)s).getState();  
    18.         System.out.println(name+" update new state:"+state);  
    19.           
    20.     }  
    21.   
    22.   
    23. }  


  • 测试类
    [java]  view plain copy
    1. package observer.pull;  
    2.   
    3. public class Test {  
    4.   
    5.     /** 
    6.      * @param args 
    7.      */  
    8.     public static void main(String[] args) {  
    9.         ConcreteSubject subject = new ConcreteSubject();  
    10.         Observer o1 = new ConcreteObserver("张山");  
    11.         Observer o2 = new ConcreteObserver("李四");  
    12.         subject.addObserver(o1);  
    13.         subject.addObserver(o2);  
    14.         System.out.println("pull模式准备:");  
    15.         subject.setState("上班了");  
    16.         subject.change();  
    17.         subject.setState("下班了");  
    18.         subject.change();  
    19.     }  
    20.   
    21. }  


  • 输出
    [java]  view plain copy
    1. pull模式准备:  
    2. 张山 update new state:上班了  
    3. 李四 update new state:上班了  
    4. 张山 update new state:下
通过 集合 + 接口 来实现,于是才形成了解耦合
定义对象间的一种一对多的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都得到通知并被自动更新。

观察者模式其实就是为了解偶,如果按你所说的直接通知的话,那你就需要获得该对像的引用,如果那天你的程序需要实现别外一种订阅(非用户)那就就需要更改代码了,这就违背了开-闭原则,利用观察者模式的话就只需实现监听器接口,并加入即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值