设计模式系列 - 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,如需转载请自行联系原作者

相关文章
|
7天前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
41 8
|
14天前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 构造函数模式
js设计模式【详解】—— 构造函数模式
18 6
|
20天前
|
设计模式 存储 算法
设计模式学习心得之五种创建者模式(2)
设计模式学习心得之五种创建者模式(2)
16 2
|
21天前
|
设计模式 搜索推荐
工厂方法模式-大话设计模式
工厂方法模式-大话设计模式
11 1
|
26天前
|
设计模式 算法
行为型设计模式之模板模式
行为型设计模式之模板模式
|
1月前
|
设计模式 新零售 Java
设计模式最佳套路5 —— 愉快地使用工厂方法模式
工厂模式一般配合策略模式一起使用,当系统中有多种产品(策略),且每种产品有多个实例时,此时适合使用工厂模式:每种产品对应的工厂提供该产品不同实例的创建功能,从而避免调用方和产品创建逻辑的耦合,完美符合迪米特法则(最少知道原则)。
42 6
|
1月前
|
设计模式 Java 关系型数据库
设计模式第2弹:工厂方法模式
type ComputerProduct struct{} // 实现工厂方法 func (computer ComputerProduct) GetInformation() string { return "电脑,官方称呼计算机,主要用于进行数据运算的一台机器。" }
30 4
|
20天前
|
设计模式 安全 Java
设计模式学习心得之五种创建者模式(1)
设计模式学习心得之五种创建者模式(1)
9 0
|
21天前
|
设计模式
简单工厂模式-大话设计模式
简单工厂模式-大话设计模式
10 0
|
27天前
|
设计模式 人工智能 自然语言处理
【设计模式】MVVM模式在AI大模型领域的创新应用
【设计模式】MVVM模式在AI大模型领域的创新应用
28 0