设计模式系列 - Observer模式

本文详细介绍了观察者模式的概念及其在软件开发中的应用。通过具体的代码示例解释了被观察者和观察者的角色,并展示了如何实现对象间的依赖关系,以便在状态发生变化时能够自动更新。

GoF阐述:Observer模式的意图是“定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。从这段话里我们可以得到两个信息,如下: 

1, 被观察者(顾名思义是被观察的对象,如果该对象发生某些变化则通知观察者执行对应的操作) 
2, 观察者(具体执行操作的对象,有多个) 

举例说明:在快乐男生比赛过程其实就是观察者的一个体现,可以这样说吉杰是一个被观察者,而杨二,包小柏,还有巫启贤就是3个观察者,被观察者操作(唱歌)时,观察者们就开始操作(评分),被观察者唱歌就是通知观察者们进行评分。 

代码样例:

被观察对象:需要完成三件事情,添加观察者、删除观察者、通知观察者

Observed.java


  1. package com.alibaba.designpattern.observer; 
  2.  
  3. public interface Observed { 
  4.     void addObserver(Viewer observer); 
  5.  
  6.     void removeObserver(Viewer observer); 
  7.  
  8.     void notifyObservers(Message message); 

ConcreteObserved.java


  1. package com.alibaba.designpattern.observer; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5.  
  6. public class ConcreteObserved implements Observed{ 
  7.     private List<Viewer> viewers = new ArrayList<Viewer>(); //存在问题:无序,应该使用set
  8.     @Override 
  9.     public void addObserver(Viewer observer) { 
  10.         viewers.add(observer); //存在问题:1、未判断observer是否为空,2、该方法未同步,多线程下存在问题
  11.     } 
  12.  
  13.     @Override 
  14.     public void notifyObservers(Message message) { 
  15.         for(Viewer viewer : viewers){ 
  16.             viewer.getMessage(message); 
  17.         } 
  18.     } 
  19.  
  20.     @Override 
  21.     public void removeObserver(Viewer observer) { 
  22.         viewers.remove(observer); //存在问题:1、未判断observer是否为空,2、该方法未同步,多线程下存在问题
  23.     } 
  24.  

 

观察者:取得被观察对象的通知信息

Viewer.java


  1. public interface Viewer { 
  2.     void getMessage(Message message); 

ConcreteViewer.java


  1. package com.alibaba.designpattern.observer; 
  2.  
  3. public class ConcreteViewer implements Viewer { 
  4.  
  5.     @Override 
  6.     public void getMessage(Message message) { 
  7.         System.out.println(message.getSubject() + "\t" + message.getBody() 
  8.                 + "\t" + message.getVerify()); 
  9.     } 

通知信息:被观察的内容的封装

Message.java


  1. package com.alibaba.designpattern.observer; 
  2.  
  3. import java.io.Serializable; 
  4.  
  5. public interface Message extends Serializable { 
  6.     Object getSubject(); 
  7.  
  8.     Object getBody(); 
  9.  
  10.     Object getVerify(); 

TextMessage.java


  1. package com.alibaba.designpattern.observer; 
  2.  
  3. public class TextMessage implements Message { 
  4.     private String subject; 
  5.     private String body; 
  6.     private String verify; 
  7.  
  8.     private static final long serialVersionUID = -542794246119749159L; 
  9.  
  10.     public TextMessage(String subject) { 
  11.         super(); 
  12.         this.subject = subject; 
  13.     } 
  14.  
  15.     public TextMessage(String subject, String body, String verify) { 
  16.         super(); 
  17.         this.subject = subject; 
  18.         this.body = body; 
  19.         this.verify = verify; 
  20.     } 
  21.  
  22.     @Override 
  23.     public String getBody() { 
  24.         return this.body; 
  25.     } 
  26.  
  27.     @Override 
  28.     public String getSubject() { 
  29.         return this.subject; 
  30.     } 
  31.  
  32.     @Override 
  33.     public String getVerify() { 
  34.         return this.verify; 
  35.     } 
  36.  

单元测试


  1. @Test 
  2.     public void testNotifyObservers() { 
  3.         Observed observed = new ConcreteObserved(); 
  4.         Viewer viewer1 = new ConcreteViewer(); 
  5.         Viewer viewer2 = new ConcreteViewer(); 
  6.         Viewer viewer3 = new ConcreteViewer(); 
  7.          
  8.         observed.addObserver(viewer1); 
  9.         observed.addObserver(viewer2); 
  10.         observed.addObserver(viewer3); 
  11.          
  12.         observed.notifyObservers(new TextMessage("开会","年中技术大会","andy")); 
  13.         observed.removeObserver(viewer1); 
  14.         observed.notifyObservers(new TextMessage("开会","部门大会","keju")); 
  15.     } 

 

  • 运行结果

  1. 开会  年中技术大会  andy 
  2. 开会  年中技术大会  andy 
  3. 开会  年中技术大会  andy 
  4. 开会  部门大会    keju 
  5. 开会  部门大会    keju 

 


本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/530451,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值