`
newleague
  • 浏览: 1473663 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

观察者模式-设计模式-笔记(一)

阅读更多

出版者+订阅者==观察者模式

 

报纸的订阅

 

出版者改称为”主题“(Subject),订阅者改称为”观察者“(Observer)

 

 

观察者模式定义了一系列对象之间的一对多关系。

 

当一个对象改变状态,其他依赖者都会收到通知。

 

主题:

这样或许不行,只是我必须因此门户大开,让你们全都可以进来取得你们需要的状态,这样太危险了。我不能让你们进来里面大肆挖掘我的各种数据

 

观察者:

为何由你主动送数据过来,而不是让我们主动去向你索取数据?

你 何不提供一些公开的getter方法,让我们”拉“走我们需要的状态?

 

 

 

 

观察者模式定义了对象间的一对多依赖关系,让一个或多个观察者对象观察一个主题对象。当主题对象的状态发生变化时,系统能通知所有的依赖于此对象的观察者对象,从而使得观察者对象能够自动更新。

在观察者模式中,被观察的对象常常也被称为目标或主题(Subject),依赖的对象被称为观察者(Observer)。

下面以一个简单的示例来示范观察者模式,程序先提供一个观察者接口:

程序清单:codes\09\9.3\Observer\Observer.java

public interface Observer
{
void update(Observable o , Object arg);
}

上面Observer接口是一个观察者接口,程序中所有观察者都应该实现该接口。在该接口的update()方法中包含了一个Observable类型的参数,该参数代表被观察对象,也就是前面介绍的目标或主题。此处的Observable是一个抽象基类,程序中被观察者应该继承该抽象基类。

Observable类的代码如下:

程序清单:codes\09\9.3\Observer\Observable.java

public abstract class Observable
{
//用一个List来保存该对象上所有绑定的事件监听器
List<Observer> observers = 
new ArrayList<Observer>();
//定义一个方法,用于从该主题上注册观察者
public void registObserver(Observer o)
{
observers.add(o);
}
//定义一个方法,用于从该主题中删除观察者
public void removeObserver(Observer o)
{
observers.add(o);
}
//通知该主题上注册的所有观察者
public void notifyObservers(Object value)
{
//遍历注册到该被观察者上的所有观察者
for (Iterator it = observers.iterator(); 
it.hasNext(); )
{
Observer o = (Observer)it.next();
//显示每个观察者的update方法
o.update(this , value);
}
}
}

该Observable抽象类是所有被观察者的基类,它主要提供了registObserver()方法用于注册一个新的观察者;并提供了一个removeObserver()方法用于删除一个已注册的观察者;当具体被观察对象的状态发生改变时,具体被观察对象会调用notifyObservers方法来通知所有观察者。

下面提供一个具体的被观察者类:Product,该产品有两个属性,它继承了Observable抽象基类。程序如下:

程序清单:codes\09\9.3\Observer\Product.java

public class Product extends Observable
{
//定义两个属性
private String name;
private double price;
//无参数的构造器
public Product(){}
public Product(String name , double price)
{
this.name = name;
this.price = price;
}
public String getName()
{
return name;
}
//当程序调用name的setter方法来修改Product的name属性时
//程序自然触发该对象上注册的所有观察者
public void setName(String name)
{
this.name = name;
notifyObservers(name);
}
public double getPrice()
{
return price;
}
//当程序调用price的setter方法来修改Product的price属性时
//程序自然触发该对象上注册的所有观察者
public void setPrice(double price)
{
this.price = price;
notifyObservers(price);
}
}

正如程序中两行粗体字代码所示,当程序调用Product对象的setName()、setPrice()方法来改变Product的name、price属性时,这两个方法将自动触发Observable基类的notifyObservers方法。

 

接下来程序提供两个观察者,一个用于观察Product对象的name属性,另一个用于观察Product对象的price属性。

程序清单:codes\09\9.3\Observer\NameObserver.java

public class NameObserver implements Observer
{
//实现观察者必须实现的update方法
public void update(Observable o , Object arg)
{
if (arg instanceof String )
{
//产品名称改变值在name中
String name = (String)arg;
//启动一个JFrame窗口来显示被观察对象的状态改变
JFrame f = new JFrame("观察者");
JLabel l = new JLabel("名称改变为:" + name);
f.add(l);
f.pack();
f.setVisible(true);
System.out.println("名称观察者:" +
o + "物品名称已经改变为: " + name);
}
}
}

程序清单:codes\09\9.3\Observer\PriceObserver.java

public class PriceObserver implements Observer
{
//实现观察者必须实现的update方法
public void update(Observable o , Object arg)
{ 
if(arg instanceof Double)
{
System.out.println("价格观察者:" +
o + "物品价格已经改变为: " + arg);
}
}
}

接着主程序创建一个Product对象(被观察的目标对象),然后向该被观察对象上注册两个观察者对象,当主程序调用Product对象的setter方法来改变该对象的状态时,注册在Product对象上的两个观察者将被触发。主程序代码如下:

程序清单:codes\09\9.3\Observer\Test.java

public class Test
{
public static void main(String[] args) 
{
//创建一个被观察者对象
Product p = new Product("电视机" , 176);
//创建两个观察者对象
NameObserver no = new NameObserver();
PriceObserver po = new PriceObserver();
//向被观察对象上注册两个观察者对象
p.registObserver(no);
p.registObserver(po);
//程序调用setter方法来改变Product的name和price属性
p.setName("书桌");
p.setPrice(345f);
}
}

运行上面程序,我们将可看到当Product的属性值发生改变时,注册在该Product上的NameObserver和PriceObserver将被触发。

纵观上面介绍的观察者模式,我们发现观察者模式通常包含如下4个角色:

被观察者的抽象基类:它通常会持有多个观察者对象的引用。Java提供了java.util.Observable基类来代表被观察者的抽象基类,所以实际开发中无须自己开发这个角色。

观察者接口:该接口是所有被观察对象应该实现的接口,通常它只包含一个抽象方法update()。Java同样提供了java.util.Observer接口来代表观察者接口,实际开发中也无须开发该角色。

被观察者实现类:该类继承Observable基类。

观察者实现类:实现Observer接口,实现update抽象方法。

理解了上面观察者模式的实现思路之后,可能有读者会感到疑惑:观察者模式的实现方式与Java事件机制的底层实现何其相似啊?实际上,我们完全可以把观察者接口理解成事件监听接口,而被观察者对象也可当成事件源来处理——换个角度来思考:监听,观察,这两个词语之间有本质的区别吗?Java事件机制的底层实现,本身就是通过观察者模式来实现的。

除此之外,观察者模式在Java EE应用中也有广泛应用,主题/订阅模式下的JMS(Java Message Service,Java消息服务)本身就是观察者模式的应用。图9.12显示了主题/订阅模式下JMS的示意图。

 
图9.12  主题/订阅模式下JMS的示意图

从图9.12中可以看出,当Topic主题收到发布者(Publisher)发布的消息时,注册到该主题的所有订阅者(Subscriber)都可收到该消息。实际上,Java EE把这个Topic设计成一个被观察者,而所有订阅者都注册到该被观察者,当发布者发布消息时,该消息将会引起Topic主题的改变,这种改变将会触发注册到该Topic上的所有观察者。

 

 

分享到:
评论

相关推荐

    HeadFirst 设计模式学习笔记2--观察者模式 demo

    HeadFirst 设计模式学习笔记2--观察者模式 demo http://blog.csdn.net/laszloyu/archive/2010/05/12/5581769.aspx

    设计模式-观察者模式(读书笔记)

    NULL 博文链接:https://mountain-king.iteye.com/blog/720810

    观察者设计模式笔记

    031114_【第11章:Java常用类库】_观察者设计模式笔记

    观察者模式笔记1

    观察者模式笔记1

    尚硅谷设计模式源码笔记课件.zip

    行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...

    设计模式笔记(包含所有设计模式)个人总结提炼笔记

    设计模式是一种解决软件设计问题的经验总结,是在软件开发过程中经过反复验证的最佳实践。设计模式提供了一套通用的解决方案,可以帮助开发人员更好地组织和设计代码,提高代码的可读性、可维护性和可扩展性。 设计...

    设计模式经典样例笔记与代码Swift.zip

    设计模式经典样例笔记与代码Swift.zip 基础 [x] 类间的关系 [x] 设计原则 创建型 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定...

    PHP设计模式大全 学习笔记

    在PHP学习中,收集了一些常用的编程方法和思想,集中详细的记录了9种设计模式的设计思路和用法。比如:工厂模式,单例模式,注册模式,适配器模式,观察者模式等

    JAVA23种设计模式及快捷记忆

    设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。工厂模式、抽象工厂模式、...

    软件体系结构与设计模式课堂笔记.docx

    3.设计模式Design Pattern:创建型模式(厂模式Factory、抽象工厂模式Abstract Factory、单例模式Singleton、建造者模式Builder、原型模式Prototype和对象池模式Object Pool Pattern)、结构型模式(适配器模式、...

    关于自己学习设计模式的笔记整理

    该文档是自己在学习设计模式时整理的常用设计模式pdf文档,包括源码,包括装饰模式,代理模式,责任链模式,命令模式,解释器模式,迭代器模式,备忘录模式,观察者模式,工厂模式,建造者模式,适配器模式,桥梁...

    设计模式学习笔记

    2.1观察者模式(不依赖jdk) 博文链接:https://biaowen.iteye.com/blog/505950

    java-design-patterns:Java 设计模式学习笔记

    Java Design PatternsJava 设计模式学习笔记,简单易懂,每个模式都有相应的代码示列,帮助学习理解。在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式...

    java-patterns:Java 23种基本的设计模式整料整理学习,责任链模式过滤器,工厂模式BeanFactory,观察者模式ContextListen等。结合Spring源码理解学习

    describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...

    稳稳当当学java之设计模式(12).md

    本人的笔记,关于java基础中设计模式的内容 包括 1.作业回顾 2.内部类 2.1局部内部类 2.2静态内部类 2.3匿名内部类 3.设计模式 3.1单例模式 3.2代理模式 3.3观察者模式 3.4模板模式 4.练习

    java设计模式(收集整理,学习笔记)

    是我在学习设计模式时整理的,其中一些是我自己学习,很多来自网络.希望对模式有兴趣的朋友有帮助,我会很高兴.

    PHP常用的三种设计模式汇总

    接下来我们一起来学习PHP中最常用的三种设计模式:单例设计模式、工厂设计模式和观察者设计模式。 单例设计模式 所谓单例模式,即在应用程序中最多只有该类的一个实例存在,一旦创建,就会一直存在于内存中! 单例...

    asp.net知识库

    深入剖析ASP.NET组件设计]一书第三章关于ASP.NET运行原理讲述的补白 asp.net 运行机制初探(httpModule加载) 利用反射来查看对象中的私有变量 关于反射中创建类型实例的两种方法 ASP.Net应用程序的多进程模型 NET委托...

    左程云leetcode-hjLearningNotes:hj学习笔记

    第一部分:设计模式 & UML 简单工厂 工厂方法模式 抽象工厂模式 策略模式 责任链模式 命令模式 模板方法模式 适配器模式 代理模式 外观模式 组合模式 装饰模式 享元模式 桥接模式 Builder模式 状态模式 解释器模式 ...

Global site tag (gtag.js) - Google Analytics