浅析JDK Observer设计模式

合集下载

观察者设计模式

观察者设计模式

观察者(Observer)模式1. 观察者模式介绍观察者模式是对象行为模式,又叫做发布-定义模式、模型-视图模式、源-监听器模式或从属者模式。

观察者模式定会以了一种一对多的依赖关系,让多个观察者同事监听一个主题对象,这个主题在状态发生变化是,会通知所有观察者对象,使他们能够自动跟新自己。

2.观察者模式的结构●抽象主题(Subject)角色:主题角色把所有对观察者对象的引用保存在一个聚集(List)中,每个主题都可以有任何数量的观察者。

抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察着角色,一般用一个抽象类或者一个接口实现●抽象观察者(Observer)角色:为所有具体观察者定义一个接口,在得到主题的通知时更新自己。

这个接口又叫做更新借口。

抽象观察者角色一般用一个抽象类或一个接口实现。

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

具体主题角色又叫做具体被观察着角色。

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

具体观察者角色实现抽象观察者角色所要求更新接口,以便使本身的状态与主题的状态相协调3. 使用观察者模式关闭winform颜色Winform使用观察者模式改变窗体背景颜色,效果图如下:点击窗体1、窗体2,将显示窗体1和窗体2,点击红色、蓝色,窗体1和窗体2同事改变相应的颜色,如同系统皮肤实现。

以下是具体的实现:这个抽象接口定义了3个方法子类必须实现的操作,add()用来添加一个观察者对象,remove用来删除一个已经登记过的观察者对象;而change()用来通知各个观察者更新他们自己。

现在抽象主题、抽象观察者都已存在,剩下就该创建具体主题和具体观察者了。

具体主题实现了抽象主题Iobservable接口的一个类,他给出了以上的三种方法的具体实现,如下,只需实现此接口即可。

java设计模式在实际项目的应用

java设计模式在实际项目的应用

java设计模式在实际项目的应用
Java设计模式在实际项目中的应用非常广泛,它们可以帮助我们解决一些常见的问题,提高代码的可重用性、可维护性和可扩展性。

以下是一些常见的Java设计模式及其在实际项目中的应用场景:
单例模式(Singleton):在需要创建大量对象,且只需要一个实例的情况下,可以使用单例模式。

例如,数据库连接池、线程池等。

工厂模式(Factory):在需要创建对象,但不希望在代码中直接指定具体类的情况下,可以使用工厂模式。

例如,解析JSON数据的类库,需要根据输入的数据动态创建不同的对象。

观察者模式(Observer):在需要实现事件驱动编程的情况下,可以使用观察者模式。

例如,在GUI编程中,当某个组件的状态发生变化时,需要通知其他组件进行相应的更新。

装饰器模式(Decorator):在需要对一个对象进行动态地添加或删除功能的情况下,可以使用装饰器模式。

例如,在Web开发中,可以对请求或响应进行拦截、修改或增强。

策略模式(Strategy):在需要根据不同的场景或条件选择不同的算法或行为的情况下,可以使用策略模式。

例如,在排序算法中,可以根据不同的需求选择不同的排序算法。

适配器模式(Adapter):在需要将一个类的接口转换成客户端所期望的另一个接口的情况下,可以使用适配器模式。

例如,在数据库访问中,可以将不同的数据库访问技术适配成统一的接口。

门面模式(Facade):在需要提供一个简洁的接口简化复杂系统操作的情况下,可以使用门面模式。

例如,在Web开发中,可以提供一个门面类来简化对数据库、缓存等系统的操作。

Observer模式在数据结构中的具体应用方案

Observer模式在数据结构中的具体应用方案

Observer模式在数据结构中的具体应用方案Observer模式是一种行为型模式,同样也是最常用的模式之一。

在软件开发中,Observer模式被广泛应用于各种类型的事件处理和时间驱动的系统中。

本文将介绍Observer模式在数据结构中的具体应用方案。

1. 什么是Observer模式?Observer模式是一种特定类型的软件设计模式,它定义了一种一对多的关系,当源对象发生变化时,它的所有依赖都会被通知并自动更新。

Observer模式也被称为发布订阅模式。

Observer模式主要包括以下几个角色:- 抽象主题(Subject):它定义了一个接口,用于添加、删除和通知所有的Observer对象。

- 具体主题(ConcreteSubject):它实现了抽象主题接口,同时存储了当前状态,并通知Observer对象有关状态的变化。

- 抽象观察者(Observer):它定义了一个更新接口,使得具体观察者在得到通知时能够更新自身状态。

- 具体观察者(ConcreteObserver):它实现了抽象观察者接口,并保持和一个具体主题对象的引用,以便于接受通知并更新自身状态。

2. Observer模式在数据结构中的应用方案在数据结构中,Observer模式可用于实现各种数据结构的自动同步机制。

例如,在一个图形化用户界面中,如果用户在一个控件中修改了数据,这些更改需要被同步到系统的其他部分。

为了实现这种同步,可以使用Observer模式。

下面是一个Observer模式在数据结构中的具体应用方案。

2.1. 具体应用场景假设有一个存储用户列表的数据结构,其中每个用户都包含一个ID、名称和电子邮件地址。

该数据结构包含了添加、删除和查找用户的方法。

此外,假设用户列表将被多个不同的组件使用,包括图形化用户界面、命令行界面和其他可视化界面。

在这种情况下,我们可以使用Observer模式使得这些组件可以自动同步用户列表。

具体来说,我们可以定义一个抽象主题接口UserList,其中包含添加、删除和查找用户的方法。

设计模式~观察者模式

设计模式~观察者模式

设计模式~观察者模式观察者模式是对象的⾏为模式,⼜叫做发布-订阅模式(Publicsh/Subscribe)、模型-视图模式(Model/View)、源-监听器模式(Source/Listener)或从属者模式(Dependent)。

观察者模式定义了⼀种⼀对多的依赖关系,让多个观察者对象同时监听某⼀个主题对象。

这个主题对象在状态上发⽣变化时,会通知所有观察者对象,使得它们能够⾃动更新⾃⼰。

观察者模式的结构涉及如下⾓⾊:抽象主题⾓⾊(Subject): 主题⾓⾊把所有对观察者对象的引⽤保存在⼀个聚集(⽐如Vector对象)⾥,每个主题都可以有任何数量的观察者。

抽象主题提供⼀个接⼝,可以增加和删除观察者对象,主题⾓⾊⼜叫做抽象被观察者⾓⾊(Observable),⼀般⽤⼀个抽象类或者⼀个接⼝实现。

抽象观察者⾓⾊(Observer): 为所有的具体观察者定义⼀个接⼝,在得到主题的通知时更新⾃⼰。

这个接⼝叫做更新接⼝。

具体主题⾓⾊(ConcreteSubject): 将有关状态存⼊具体观察者对象,在具体主题的内部状态改变时,给所有登记过的观察者发出通知。

具体观察者⾓⾊(ConcreteObserver): 存储与主题的状态⾃恰的状态。

具体观察者⾓⾊实现抽象观察者⾓⾊所要求的更新接⼝,以便使本⾝的状态与主题的状态相协调。

在类图中,从具体主题⾓⾊指向抽象观察者⾓⾊的合成关系,代表具体主题对象可以含有任意多个对抽象观察者对象的引⽤。

代码清单:Subjectpublic interface Subject {//调⽤这个⽅法登记⼀个新的观察者对象public void attach(Observer observer);//调⽤这个⽅法删除⼀个已经登记过的观察者对象public void detach(Observer observer);//调⽤这个⽅法通知所有登记过的观察者对象void notifyObersers();}ConcreteSubjectpublic class ConcreteSubject implements Subject {private Vector observersVector = new Vector();//登记新的观察者对象@Overridepublic void attach(Observer observer) {// TODO Auto-generated method stubobserversVector.addElement(observer);}//删除登记过的观察者对象@Overridepublic void detach(Observer observer) {// TODO Auto-generated method stubobserversVector.removeElement(observer);}//通知所有登记过的观察者对象@Overridepublic void notifyObersers() {// TODO Auto-generated method stubEnumeration enumeration = observers();while(enumeration.hasMoreElements()){((Observer)enumeration.nextElement()).update();}}//给出观察者聚集的Enumeration对象public Enumeration observers(){return ((Vector)observersVector.clone()).elements();}}Observerpublic interface Observer {void update();}ConcreteObserverpublic class ConcreteObserver implements Observer {//调⽤这个⽅法会更新⾃⼰@Overridepublic void update() {System.out.println("I am notified.");}}另⼀种实现⽅案在上⼀个实现中,管理聚集的⽅法是由抽象主题声明并由具体主题实现的。

5_JAVA设计模式第五课:Observer模式在J2EE中的实现

5_JAVA设计模式第五课:Observer模式在J2EE中的实现

引言:设计模式是经验的文档化。

它是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。

更通俗的来说,它是一个问题/解决方案对。

一旦我们掌握了设计模式,就等于拥有了一支强有力的专家队伍。

它甚至能够使面向对象的新手利用前人的经验找出职责明确的类和对象,从而获得优雅的解决方案。

由于设计模式也是重构的目标,如果在设计的初期适当地引入设计模式,可以减少重构的工作量。

但是,我们也不能陷入模式的陷阱,为了使用模式而去套模式,那样会陷入形式主义。

我们在使用模式的时候,一定要注意模式的意图(intent),而不要过多的去关注模式的实现细节,因为这些实现细节在特定情况下,可能会发生一些改变。

不要顽固地认为设计模式一书中的类图或实现代码就代表了模式本身。

下面,我们来讨论一下为什么要在分布式、多层系统中使用Observer模式。

多层体系结构(multi-tier architecture):三层体系结构是多层体系结构中最简单的一种,它一般包括:1.表示层(presentation)-窗口、报表-2.业务逻辑层(business logic)-管理业务过程的任务和规则。

它又可以细分为领域对象层(代表领域概念)和服务层(提供数据库交互、安全性、打印报表)。

3.存储层(storage)-持久化存储机制。

如数据库服务器等。

图一:三层体系结构而Java 2平台企业版(J2EE)是一种利用Java 2平台来简化诸多与多级企业解决方案的开发、部署和管理相关的复杂问题的体系结构。

它是开放的、基于标准的平台,用以开发、部署和管理N层结构、面向Web的,以服务器为中心的企业级应用。

为了支持领域对象的复用,并且使领域对象的接口变更所带来的影响最小化。

我们将领域层(模型)和表示层(视图)相分离。

采用模型-视图模式的意义在于:1.支持聚合度更高的模型定义,使模型的定义可以集中在领域过程的定义,而不是图形界面上。

2.允许将模型和用户界面并行开发。

设计模式之1 observer模式

设计模式之1 observer模式

设计模式总章:设计模式就是把简单的问题复杂化,带来的好处是系统的可扩展性。

用了设计模式以后:复杂度增加开发成本增加维护成本降低设计模式的基本原则是,添加,而不是修改。

1.什么叫分析?(确定需求是什么)分析就是要知道我要做什么。

确定系统实现什么样的功能。

2.什么叫设计?(实现需求)设计就是我要怎么实现。

设计就是多种实现的手段当中选取一个。

实现某个功能是使用什么样的方式。

用一个接口来封装一系列共同具有的特点。

各个监听类都去实现这个接口。

在被监听的类上加上addxxxlistener方法。

awt当中的事件:事件源可以是,buttion,textField,textArea事件是:ActionEvent相对应的监听器是actionlistener。

通过配置文件来管理observer。

配置文件:文件名:observer.properties文件的内容:observers=com.bjsxt.dp.observer.Dad,com.bjsxt.dp.observer.GrandFather,com.bjsxt.dp.obser ver.Dog访问当前配置的文件的main方法:package com.bjsxt.dp.observer;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.Properties;//事件类class WakenUpEvent {privatelong time;private String loc;private Child source;//事件方法public WakenUpEvent(long time, String loc, Child source) { super();this.time = time;this.loc = loc;this.source = source;}publiclong getTime() {return time;}publicvoid setTime(long time) {this.time = time;}public StringgetLoc() {return loc;}publicvoid setLoc(String loc) {this.loc = loc;}public Child getSource() {return source;}publicvoid setSource(Child source) {this.source = source;}}//被监听类。

设计模式之观察者模式(Observer)详解及代码示例

设计模式之观察者模式(Observer)详解及代码示例

设计模式之观察者模式(Observer)详解及代码⽰例⼀、模式的定义与特点 观察者(Observer)模式的定义:观察者模式⼜被称为发布-订阅/模型-视图模式,属于⾏为型设计模式的⼀种,是⼀个在项⽬中经常使⽤的模式。

指多个对象间存在⼀对多的依赖关系,当⼀个对象的状态发⽣改变时,所有依赖于它的对象都得到通知并被⾃动更新。

⼆、观察者模式优缺点 观察者模式是⼀种对象⾏为型模式,其主要优点如下:降低了⽬标与观察者之间的耦合关系,两者之间是抽象耦合关系。

⽬标与观察者之间建⽴了⼀套触发机制。

它的主要缺点如下:⽬标与观察者之间的依赖关系并没有完全解除,⽽且有可能出现循环引⽤。

当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。

三、观察者模式的实现 实现观察者模式时要注意具体⽬标对象和具体观察者对象之间不能直接调⽤,否则将使两者之间紧密耦合起来,这违反了⾯向对象的设计原则。

观察者模式的主要⾓⾊如下。

抽象主题(Subject)⾓⾊:也叫抽象⽬标类,它提供了⼀个⽤于保存观察者对象的聚集类和增加、删除观察者对象的⽅法,以及通知所有观察者的抽象⽅法。

具体主题(Concrete Subject)⾓⾊:也叫具体⽬标类,它实现抽象⽬标中的通知⽅法,当具体主题的内部状态发⽣改变时,通知所有注册过的观察者对象。

抽象观察者(Observer)⾓⾊:它是⼀个抽象类或接⼝,它包含了⼀个更新⾃⼰的抽象⽅法,当接到具体主题的更改通知时被调⽤。

具体观察者(Concrete Observer)⾓⾊:实现抽象观察者中定义的抽象⽅法,以便在得到⽬标的更改通知时更新⾃⾝的状态。

观察者模式的结构图如图所⽰: 代码如下:public class ObserverPattern{public static void main(String[] args){Subject subject=new ConcreteSubject();Observer obs1=new ConcreteObserver1();Observer obs2=new ConcreteObserver2();subject.add(obs1);subject.add(obs2);subject.notifyObserver();}}//抽象⽬标abstract class Subject{protected List<Observer> observers=new ArrayList<Observer>();//增加观察者⽅法public void add(Observer observer){observers.add(observer);}//删除观察者⽅法public void remove(Observer observer){observers.remove(observer);}public abstract void notifyObserver(); //通知观察者⽅法}//具体⽬标class ConcreteSubject extends Subject{public void notifyObserver(){System.out.println("具体⽬标发⽣改变...");System.out.println("--------------");for(Object obs:observers){((Observer)obs).response();}}}//抽象观察者interface Observer{void response(); //反应}//具体观察者1class ConcreteObserver1 implements Observer{public void response(){System.out.println("具体观察者1作出反应!");}}//具体观察者1class ConcreteObserver2 implements Observer{public void response(){System.out.println("具体观察者2作出反应!");}} 测试结果为:具体⽬标发⽣改变...--------------具体观察者1作出反应!具体观察者2作出反应!四、观察者模式的应⽤实例 接下来再看⼀个关于上下课打铃,⽼师同学上下课的⽰例:public class BellEventTest{public static void main(String[] args){BellEventSource bell=new BellEventSource(); //铃(事件源)bell.addPersonListener(new TeachEventListener()); //注册监听器(⽼师) bell.addPersonListener(new StuEventListener()); //注册监听器(学⽣)bell.ring(true); //打上课铃声System.out.println("------------");bell.ring(false); //打下课铃声}}//铃声事件类:⽤于封装事件源及⼀些与事件相关的参数// EventObject: The root class from which all event state objects shall be derived. class RingEvent extends EventObject{private static final long serialVersionUID=1L;private boolean sound; //true表⽰上课铃声,false表⽰下课铃声public RingEvent(Object source,boolean sound){super(source);this.sound=sound;}public void setSound(boolean sound){this.sound=sound;}public boolean getSound(){return this.sound;}}//⽬标类:事件源,铃class BellEventSource{private List<BellEventListener> listener; //监听器容器public BellEventSource(){listener=new ArrayList<BellEventListener>();}//给事件源绑定监听器public void addPersonListener(BellEventListener ren){listener.add(ren);}//事件触发器:敲钟,当铃声sound的值发⽣变化时,触发事件。

设计模式培训-observer

设计模式培训-observer

public class WeatherData { // 实例变量在前面已经声明了 …… public void measurementsChanged ( ) { float temp = getTemperature ( ); float humidity = getHumidity ( ); float pressure = getPressure ( );
天气数据分析:WeatherData类
这三个方法分别返回最近的天气测量值,包 括气温,湿度和气压值. 我们不必关心这些变量是怎么设置的,对象 WeatherData知道如何从气象站获取更新的 信息.
WeatherData getTemperature ( ) getHumidity ( ) getPressure ( ) measurementChanged ( ) // other methods
Observer
数据变化时,通知Observer对象
2 2
int
这个对象不是Observer,因此 在Subject的数据发生变化时 它将不会得到任何通知.
2
Observer Objects
观察者模式的定义
观察者模式定义了对象之间一对多的依赖关系,使得一个对象改 变状态时,它的所有依赖的对象都能自动得到通知和更新.
WeatherData实现Subject±¤f
实现接口(包括Subject,Observers,DisplayElement接口)
public interface public void public void public void } Subject { registerObserver (Observer o); removeObserver (Observer o); notifyObservers ( );

java

java
Observer (观察者)设计模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
JUnit
是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework)。Junit测试是程序员测试,即所谓白盒测试,因为程序员知道被测试的软件如何(How)完成功能和完成什么样(What)的功能。Junit是一套框架,继承TestCase类,就可以用Junit进行自动测试了
JSTL(JSP Standard TaБайду номын сангаас Library ,JSP标准标签库)
是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。JSTL只能运行在支持JSP1.2和Servlet2.3规范的容器上,如tomcat 4.x。在JSP 2.0中也是作为标准支持的。
黑盒测试
也称功能测试,它是通过测试来检测每个功能是否都能正常使用。在测试中,把程序看作一个不能打开的黑盒子,在完全不考虑程序内部结构和内部特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数据而产生正确的输出信息。黑盒测试着眼于程序外部结构,不考虑内部逻辑结构,主要针对软件界面和软件功能进行测试。
白盒测试
也称结构测试或逻辑驱动测试,它是按照程序内部的结构测试程序,通过测试来检测产品内部动作是否按照设计规格说明书的规定正常进行,检验程序中的每条通路是否都能按预定要求正确工作。 这一方法是把测试对象看作一个打开的盒子,测试人员依据程序内部逻辑结构相关信息,设计或选择测试用例,对程序所有逻辑路径进行测试,通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。

JDK自带的观察者模式

JDK自带的观察者模式

JDK⾃带的观察者模式《》《》《》《》1、概述观察者模式⼜称为发布/订阅(Publish/Subscribe)模式observer模式简介observer模型,⼜被称作listener模式。

这⾥统⼀⽤observer来称呼。

设计模式⾥对其结构的描述:意图:⼀个对象变化,通知其他被依赖的对象。

适⽤性:两种对象subject与observers,相对相互独⽴,有单向依赖关系,observer依赖subject。

不知道具体有多少observer对象被通知。

采⽤这种⽅式,主要针对接⼝编程,抽象。

有可能⼀对多,也有可能是多对⼀,多对多。

观察者设计模式涉及到两种⾓⾊:主题(Subject、被观察者、通知者、Publish,发布者)和观察者(Observer)(1)Subject模块Subjec模块有3个主要操作addObserver():注册添加观察者(申请订阅)deleteObserver():删除观察者(取消订阅)notifyObserver():主题状态发⽣变化时通知所有的观察者对象(2)Oserver模块Oserver模块有1个核⼼操作update(),当主题Subject状态改变时,将调⽤每个观察者的update()⽅法,更新通知。

两种实现:推与拉推模式的结构:推模式Subject主动向Observer推送消息,不管对⽅是否需要,推送的信息通常是⽬标对象的全部或部分数据,相当于⼴播通信。

拉模型Subject在通知Observer时只传递少量信息,如果观察者需要更具体的信息,再由Observer主动去拉取数据。

这样的模型实现中会把Subject⾃⾝通过update⽅法传⼊到Observer。

⼀、介绍⼀下JDK⾃带的观察者模式subject -> java.util.Observable(类)void addObserver(Observer o)如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者。

Java设计模式之观察者模式(发布-订阅模式)

Java设计模式之观察者模式(发布-订阅模式)

Java设计模式之观察者模式(发布-订阅模式)1.初步认识在对象之间定义了⼀对多的依赖,这样⼀来,当⼀个对象改变状态,依赖它的对象会收到通知并⾃动更新观察者模式的结构图:2.介绍观察者设计模式涉及到两种⾓⾊:主题(Subject)和观察者(Observer)(1)Subject模块(被观察者)Subject模块有三个功能registerObserver(Observer onserver):注册添加观察者(申请订阅)unregisterObserver(Observer onserver):取消注册的观察者(取消订阅)notifyObserverUpdate (String notifyChange):主题模块发⽣改变,通知相应观察者(2)Observer模块Observer⾥⾯有⼀个更新操作update操作,当Subject被观察者状态改变时,将调⽤每个观察的update()⽅法,更新相应通知。

3.简单例⼦(1)被观察者接⼝package wyl.observer.dao;public interface Subject {/*** 注册观察者*/void registerObserver(Observer observer);/*** 取消对观察者的注册*/void unregisterObserver(Observer observer);/*** 通知观察者当前状态已更新*/void notifyObserverUpdate(String notifyChange);}(2)被观察者接⼝实现类package wyl.observer.impl;import wyl.observer.dao.Observer;import wyl.observer.dao.Subject;import java.util.ArrayList;import java.util.List;public class SubjectImpl implements Subject {// 存放观察者List<Observer> observerList = new ArrayList<>();String status = "";@Overridepublic void registerObserver(Observer observer) {observerList.add(observer);}@Overridepublic void unregisterObserver(Observer observer) {if (observerList != null && observerList.contains(observer)) { observerList.remove(observer);}}@Overridepublic void notifyObserverUpdate(String notifyChange) {for (int i = 0; i < observerList.size(); i++) {Observer observer = observerList.get(i);observer.update(notifyChange);}}}(3)观察者接⼝package wyl.observer.dao;public interface Observer {/*** 被观察者发⽣变化,更新通知*/void update(String status);}(4)被观察者接⼝实现类package wyl.observer.impl;import wyl.observer.dao.Observer;public class ObserverImpl implements Observer {public String name;public ObserverImpl(String name) { = name;}@Overridepublic void update(String status) {System.out.println(name + " : " +status);}}(5)测试被观察者发⽣改变,观察者被通知package wyl.observer;import wyl.observer.dao.Observer;import wyl.observer.dao.Subject;import wyl.observer.impl.ObserverImpl;import wyl.observer.impl.SubjectImpl;public class test {public static void main(String[] args) {// 创建主题(被观察者)Subject subject = new SubjectImpl();//创建观察者Observer observer1 = new ObserverImpl("jack");Observer observer2 = new ObserverImpl("rose");Observer observer3 = new ObserverImpl("mary");//将观察者注册到被观察者中,等待被通知subject.registerObserver(observer1);subject.registerObserver(observer2);subject.registerObserver(observer3);//更新主题(被观察者)的数据,通知注册进来的观察者//subject.notifyObserverUpdate("subject当前发⽣了改变");subject.notifyObserverUpdate("subject去订阅了新的书籍,包括《java从⼊门到精通》《java整洁之道》《数据库》"); }}测试结果1:jack : subject当前发⽣了改变rose : subject当前发⽣了改变mary : subject当前发⽣了改变测试结果2:jack : subject去订阅了新的书籍,包括《java从⼊门到精通》《java整洁之道》《数据库》rose : subject去订阅了新的书籍,包括《java从⼊门到精通》《java整洁之道》《数据库》mary : subject去订阅了新的书籍,包括《java从⼊门到精通》《java整洁之道》《数据库》}。

JAVA观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)

JAVA观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)

本章我们讨论一个除前面的单例以及代理模式之外,一个WEB项目中有可能用到的设计模式,即观察者模式。

说起观察者模式,LZ还是非常激动的,当初这算是第一个让LZ感受到设计模式强大的家伙。

当初LZ要做一个小型WEB项目,要上传给服务器文件,一个需求就是要显示上传进度,LZ就是用这个模式解决了当时的问题,那时LZ接触JAVA刚几个月,比葫芦画瓢的用了观察者模式。

现在谈及观察者模式,能用到的地方就相对较多了,通常意义上如果一个对象状态的改变需要通知很多对这个对象关注的一系列对象,就可以使用观察者模式。

下面LZ先给出观察者模式标准版的定义,引自百度百科。

定义:观察者模式(有时又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式)是软件设计模式的一种。

在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。

这通常透过呼叫各观察者所提供的方法来实现。

此种模式通常被用来实作事件处理系统。

上面的定义当中,主要有这样几个意思,首先是有一个目标的物件,通俗点讲就是一个类,它管理了所有依赖于它的观察者物件,或者通俗点说是观察者类,并在它自己状态发生变化时,主动发出通知。

简单点概括成通俗的话来说,就是一个类管理着所有依赖于它的观察者类,并且它状态变化时会主动给这些依赖它的类发出通知。

那么我们针对上面的描述给出观察者模式的类图,百度百科没有给出观察者模式的类图,这里LZ自己使用工具给各位画一个。

可以看到,我们的被观察者类Observable只关联了一个Observer的列表,然后在自己状态变化时,使用notifyObservers方法通知这些Observer,具体这些Observer都是什么,被观察者是不关心也不需要知道的。

上面就将观察者和被观察者二者的耦合度降到很低了,而我们具体的观察者是必须要知道自己观察的是谁,所以它依赖于被观察者。

下面LZ给写出一个很简单的观察者模式,来使用JAVA代码简单诠释一下上面的类图。

设计模式入门(三):Observer模式

设计模式入门(三):Observer模式

设计模式⼊门(三):Observer模式观察者模式,⼜称为发布订阅模式,属于⾏为模式。

定义⼀对多的依赖关系,观察者和被观察者,订阅者发发布者的⽐喻都很形象。

java中对该模式有原⽣实现,这⾥贴上删除注释的代码public interface Observer {void update(Observable o, Object arg);}public class Observable {private boolean changed = false;private Vector<Observer> obs;public Observable() {obs = new Vector<>();}public synchronized void addObserver(Observer o) {if (o == null)throw new NullPointerException();if (!obs.contains(o)) {obs.addElement(o);}}public synchronized void deleteObserver(Observer o) {obs.removeElement(o);}public void notifyObservers() {notifyObservers(null);}public void notifyObservers(Object arg) {Object[] arrLocal;synchronized (this) {if (!changed)return;arrLocal = obs.toArray();clearChanged();}for (int i = arrLocal.length-1; i>=0; i--)((Observer)arrLocal[i]).update(this, arg);}public synchronized void deleteObservers() {obs.removeAllElements();}protected synchronized void setChanged() {changed = true;}protected synchronized void clearChanged() {changed = false;}public synchronized boolean hasChanged() {return changed;}public synchronized int countObservers() {return obs.size();}}实际上需要关注的只有⼏个⽅法,Observer 的 update ⽤来给 Observable 调⽤,也就是发送消息通知他。

观察者架构模式

观察者架构模式
模型以及构成
观察者架构模式一般呈现出以下模型:
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,通力根1保过据护管生高线产中敷工资设艺料技高试术中卷0资不配料仅置试可技卷以术要解是求决指,吊机对顶组电层在气配进设置行备不继进规电行范保空高护载中高与资中带料资负试料荷卷试下问卷高题总中2体2资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况1卷中下安,与全要过,加度并强工且看作尽护下可1都关能可于地以管缩正路小常高故工中障作资高;料中对试资于卷料继连试电接卷保管破护口坏进处范行理围整高,核中或对资者定料对值试某,卷些审弯异核扁常与度高校固中对定资图盒料纸位试,置卷编.工保写况护复进层杂行防设自腐备动跨与处接装理地置,线高尤弯中其曲资要半料避径试免标卷错高调误等试高,方中要案资求,料技编试术写5、卷交重电保底要气护。设设装管备备置线4高、调动敷中电试作设资气高,技料课中并3术试、件资且中卷管中料拒包试路调试绝含验敷试卷动线方设技作槽案技术,、以术来管及避架系免等统不多启必项动要方高式案中,;资为对料解整试决套卷高启突中动然语过停文程机电中。气高因课中此件资,中料电管试力壁卷高薄电中、气资接设料口备试不进卷严行保等调护问试装题工置,作调合并试理且技利进术用行,管过要线关求敷运电设行力技高保术中护。资装线料置缆试做敷卷到设技准原术确则指灵:导活在。。分对对线于于盒调差处试动,过保当程护不中装同高置电中高压资中回料资路试料交卷试叉技卷时术调,问试应题技采,术用作是金为指属调发隔试电板人机进员一行,变隔需压开要器处在组理事在;前发同掌生一握内线图部槽 纸故内资障,料时强、,电设需回备要路制进须造行同厂外时家部切出电断具源习高高题中中电资资源料料,试试线卷卷缆试切敷验除设报从完告而毕与采,相用要关高进技中行术资检资料查料试和,卷检并主测且要处了保理解护。现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。

【Unity与23种设计模式】观察者模式(Observer)

【Unity与23种设计模式】观察者模式(Observer)

【Unity与23种设计模式】观察者模式(Observer)GoF中定义:“在对象之间定义⼀个⼀对多的连接⽅法,当⼀个对象变换状态时,其他关联的对象都会⾃动收到通知。

”现实中,社交⽹络就是个例⼦。

以前的报社,每次出新刊的时候,报刊便会将新刊⼀本⼀本的送到订阅报刊⼈的⼿中于是,每次出新刊,报社都得送到每个⼈的⼿中⽽如今的微博,便是应⽤了观察者模式当想关注某个⼈时,只需要点击关注便可订阅当关注的⼈更新微博时,只需要更新到微博平台订阅的⼈就可以接收到更新的消息⽽不需要被关注的那个⼈向每个订阅者发送消息C#中的事件系统(Event)便是使⽤的观察者模式Unity中的所有事件(如UI点击事件)也是应⽤的观察者模式//事件接⼝public abstract class Subject {List<Observer> m_Observers = new List<Observer>();public void Attach(Observer theObserver) {m_Observers.Add(theObserver);}public void Detach(Observer theObserver) {m_Observers.Remove(theObserver);}public void Notify() {foreach (Observer theObserver in m_Observers)theObserver.Update();}}//实现事件public class ConcreteSubject : Subject {string m_SubjectState;public void SetState(string state) {m_SubjectState = state;Notify();}public string GetState() {return m_SubjectState;}}//观察者接⼝public abstract class Observer {public abstract void Update();}//实现观察者public class ConcreteObserver : Observer {string m_SubjectState;ConcreteSubject m_Subject = null;public ConcreteObserver(ConcreteSubject theSubject){m_Subject = theSubject;}public override void Update(){Debug.Log("ConcreteSubject.Update");}}//测试类public class TestObserver {private void UnitTest() {ConcreteSubject theSubject = new ConcreteSubject();ConcreteObserver theObserver = new ConcreteObserver(theSubject); theSubject.Attach(theObserver);theSubject.SetState("Subject状态1");}}观察者模式的设计原理是,先设置⼀个主题(Subject)让这个主题发布时可同时通知关⼼这个主题的观察者/订阅者并且主题不必理会观察者/订阅者接下来会执⾏哪些操作观察者模式的主要功能和优点:将“主题发⽣”与“功能执⾏”这两个操作解除绑定⽂章整理⾃书籍《设计模式与游戏完美开发》菜升达著。

Java设计模式(三)——观察者模式和监听器

Java设计模式(三)——观察者模式和监听器

Java设计模式(三)——观察者模式和监听器为了实现多个模块之间的联动,最好的⽅法是使⽤观察者模式。

⽹上介绍的资料也⽐较多,今天我就从另⼀个⽅⾯谈谈⾃⼰对观察者模式的理解。

从JDK提供的⽀持库⾥,我们能够找到四个对象:Observable、Observer、EventListener、EventObject。

先模拟⼀个后台处理过程:import java.util.Observable;public class Subject extends Observable {private int value;public int getValue() {return value;}private void progress() {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}value = i;setChanged(); // 值发⽣改变notifyObservers(); // 调⽤所有注册的观察者}}public void onStart() {progress();}}稍微对上⾯的代码做⼀些解释,顺便介绍⼀下Observable这个类:顾名思义“能够被观察的对象”,⽤户能够继承它并增加⾃⼰的定义,它提供了⼏个⽅法。

addObserver(Observer o):注册观察者,这个⽅法的内部其实就是提供了⼀个队列。

将多有观察者储存在队列中,当有事件发⽣的时候遍历这个队列。

hasChanged()与setChanged():当事件发⽣时,需要调⽤setChanged()⽅法,此时hasChanged()返回true否则返回false。

notifyObservers()与notifyObservers(Object arg):通知所有观察者可以获取各⾃需要的变量或只推送某个对象。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

浅析JDK Observer设计模式
Java中JDK自带的JDK Observer设计模式的实现是一个范例,有助于我们在设计模式的思维上有所突破。

目前设计模式的介绍性文章越来越多,但设计模式的研究性文章仍然比较欠缺,这着实让人觉得有点遗憾。

本文旨在抛砖引玉。

1.JDK Observer设计模式概要
JDK Observer设计模式在GOF里属于行为设计模式。

JDK里提供的observer设计模式的实现由java.util.Observable类和java.util.Observer接口组成。

从名字上可以清楚的看出两者在Observer设计模式中分别扮演的角色:Observer是观察者角色,Observable是被观察目标(subject)角色。

Observable是一个封装subject基本功能的类,比如注册observer(attach功能),注销observer(detatch功能)等。

这些功能是任何一个扮演observerable角色的类都需要实现的,从这一点上来讲,JDK里将这些通用功能专门封装在一个类里,显得合情合理。

通常情况下,我们的类只要从Observerable类派生就可以称为observerable角色类,使用非常简单。

2.使用JDK Observer设计模式存在的困难
但我们不得不注意到,在项目实际开发当中,情况往往要复杂得多。

java不支持多继承特性在很多时候是阻碍我们使用JDK Observer设计模式的绊脚石。

比如说,我们设计的一个类已经是某个类的派生类,在这种情况下同时想让它扮演Observerable角色将变得麻烦。

如何实现“多继承”的效果是摆在我们面前的一大难题。

下面我们首先分析一下Observable 类。

3.JDK Observable类“触发通知”的原理
Observable必须“有变化”才能触发通知observer这一任务,这是它的本质体现。

查看源码便可知一二。

Observerable部分源码如下:
//……省略……
private boolean changed=false;
//……省略……
public void notifyObservers(Object arg)
{
//……省略……
Object[]arrLocal;
synchronized(this)
{
//……省略……
if(!changed)return;
arrLocal=obs.toArray();
clearChanged();
}
//……省略……
protected synchronized void setChanged()
{
changed=true;
}
protected synchronized void clearChanged()
{
changed=false;
}
正如粗的斜体标注部分所示,在notifyObservers(Object arg)方法里if(!changed)return;语句告诉我们,若changed属性值为false,将直接返回,根本不会触发通知操作。

并且我们注意到changed属性被初始化为false,这将意味着如果我们不主动设置changed属性为true,将不会有任何变化,也就是说根本起不到“通知”作用。

因此,设置changed属性的值是我们应用jdk observer设计模式的关键所在。

那么如何才能设置changed属性呢?从源码可以看出,唯一的入口是通过setChanged()。

下面我们分析一下changed属性及相关的方法setChanged()和clearChanged()。

4.Observable类的分析
Observable#changed属性的初始值为false,这很容易理解,不再详细陈述。

细心的读者可能会注意到跟changed属性有关的两个方法setChanged()和clearChanged(),它们的修饰符都是protected.想强调的是,是protected,而不是public.但这样是否有其必要性和合理性?答案是肯定的。

在前面的分析中,我已经提到,setChanged()方法是设置changed 的唯一入口,它的修饰符定义为protected,就意味着通过定义Observable的对象,再设置changed属性将变得不可能。

从这个意义上说,要想应用observer设计模式,必须继承Observable类方可。

关于这一点,下文还会提及。

但是,为什么不能定义成public?这似乎难以理解。

因为定义成public,我们不就可以很方便地设置changed属性的值吗?为了弄清楚这个问题,我们还是看一下Observable里的相关的代码:
//……省略……
public void notifyObservers(Object arg)
{
//……省略……
for(int i=arrLocal.length-1;i>=0;i--)
((Observer)arrLocal[i])。

update(this,arg);
}
这段代码表达的意思是说找出所有已注册的Observer,再逐个进行“通知”,通过调用Observer#update(Observable,Object)方法进行通知。

我们看到,update第一个参数是this,我们同时还必须注意到,这段代码是Observable类里的代码。

这就相当于是在一再强调,发出“通知”的,必须是observable自己(Observable类或者其派生类),其它任何类都不行。

这就意味着我们的observable类继承Observable类是必要的,因为如果不继承,而采用组合的话,将无法保证能传递好this.换句话说,采用组合的方式使用Observable类,将变得几乎没有任何意义。

同时,修饰符定义为protected,可以确保是在Obsrvable里进行触发通知的,不会在其它任何地方进行通知,这显得内敛性很强。

如果将setChanged()修饰符定义为public,将无法保证正确“传递this”的硬性要求,这不符合“只有observalbe 才能直接或间接通知observer”这一observable设计模式的硬性要求。

由此我们可见一斑,jdk的很多理念的思想性是多么的强。

5.解决使用observer设计模式存在的困难
借助adapter设计模式(详见本人发表的adapter设计模式相关文章)和java支持多接口特性基本可以解决“多继承”问题。

基本思想是结合继承/实现和组合来达到效果。

在上面的分析中,我们已经知道,Observable类必须继承使用,不能组合使用,因此我们只需要将
需扮演成observerable角色的类装扮成adapter角色,将该类原继承的类装扮成adaptee角色即可。

示例代码如下:
//欲充当observable角色的类的原来的代码:
public class MyObject extends BaseObject
{
public MyObject()
{
public void method1(){}
}
}
//充当observable角色后的代码:
public class MyObject extends Observable
{
private BaseObject baseObject=null;
public MyObject(BaseObject baseObject)
{
this.baseObject=baseObject;
}
}
6.JDK Observer注意事项:
如果上例中的BaseObject也用到需要传递“this”的方法,那么上面的组合使用方法将有可能失效。

这种情况是最糟糕的情况。

此时可以考虑在BaseObject类这些“瓶颈”地方尽量采用接口代替类(包括抽象类)来解决。

那么JDK Observer设计模式就介绍到这里,但是很多的设计模式的思路还是要举一反三
慢慢提高。

本文由兰州中研白癜风研究院(/)网站负责人阿牧整理分享,转载请注明!。

相关文档
最新文档