1. 观察者模式 - 设计模式
观察者模式定义了一个一对多的对象关系 一个主体对象对应多个观察者对象 当主体对象发生改变时 所有它对应的观察者对象都会自动得到通知并更新
本文将给出一个相应的事例具体说明观察者模式是如果工作的 这个事例演示了一个当一个任务的信息改变时通知这个任务所涉及所有人员的事例 任务信息包括任务状态 任务所采用的处理流程和任务完成后的checklist[用来确保任务完成所有预定需要完成的功能列表和避免一些常见的错误]
先定义两个接口 主体对象接口和观察者对象接口
/** *//** * 主体对象接口定义了注册观察者 取消观察者和通知观察者方法 * */public interface ISubject { /** *//** * 为该主体对象注册一个观察者 */ public void registerObserver(IObserver observer); /** *//** * 从该主体对象中取消一个观察者的注册 */ public void removeObserver(IObserver observer); /** *//** * 通知所有观察者 */ public void notifyObserver();}
/** *//** * 观察者接口简单定义了一个用来更新观察者信息的接口 * 当主体对象被更新时 这个接口方法会被自动调用并更新信息 */public interface IObserver { /** *//** * 接口方法用来更新观察者的信息 */ public void remind(ITask taskSubject);}
这两个接口只定义了主题对象和观察者对象所需要的接口 但是没有实现任何任务相关的具体的方法和接口 下面会再定义一个任务接口来规定任务应该具备的功能 这样分开定义的好处在于 如果我们将不同的模块分解开来 如果一方需要更新 另一方不会受到影响
/** *//** * 这里定义了一个任务应该具有的功能 */public interface ITask { public void setStatus(String status); public String getStatus(); public void setProcess(String process); public String getProcess(); public void setCheckList(String checkList); public String getCheckList();}
然后我们创建具体的任务主体 这里我们会实现ISubejct ITask两个接口
import java util ArrayList;import java util List;public class TaskSubject implements ISubject ITask { // 在这里对观察者列表进行初始化 因为是静态初始化 所以保证在这个运行过程中只有一个实例得到初始化 static { _observers = new ArrayList(); } @Override public void notifyObserver() { // 调用观察者的方法通知并更新观察者信息 for(IObserver observer : _observers) { observer remind(this); } } @Override public void registerObserver(IObserver observer) { if(ntains(observer)) { System out println( is already registed! ); } // Register an observer _observers add(observer); System out println( is registed successfully! ); } @Override public void removeObserver(IObserver observer) { if(!ntains(observer)) { System out println( is never registed! ); } // Remove an observer _observers remove(observer); System out println( is removed successfully! ); } @Override public String getCheckList() { return this _checkList; } @Override public String getProcess() { return this _process; } @Override public String getStatus() { return this _status; } @Override public void setCheckList(String checkList) { this _checkList = checkList; } @Override public void setProcess(String process) { this _process = process; } @Override public void setStatus(String status) { this _status = status; } // 这里将观察者列表定义为一个静态的变量 这样可以保证自始至终只有一个变量列表 便于系统的维护 // 这里用到了泛型 这样在对这个列表进行操作的时候 无需再进行类型的转换 private static List _observers; private String _status; private String _process; private String _checkList;}
在这里我们没有给观察者定义接口 而是使用了一个抽象类 因为所有的观察者都必须从主体对象那里获取信息 而且获取信息的方法都是一样的 这样可以避免重复编码
/** *//** * 这个抽象类继承了Iobserver接口 所以我们必须实现remind方法 * 在remind方法中从主体对象中获取所有需要的信息 * 并调用sendEmail方法对观察者实时进行更新 */public abstract class TaskObserver implements IObserver { @Override public void remind(ITask taskSubject) { this _status = taskSubject getStatus(); this _process = taskSubject getProcess(); this _checkList = taskSubject getCheckList(); // 更新观察者对象 this sendEmail(); } public abstract void sendEmail(); // 工具类方法 减少编码数量 增加可读性 public void print(String msg) { System out println(msg); } // 在父类中定义参数 减少重复编码 protected String _status; protected String _process; protected String _checkList;}
然后定义任务受托人[assignee] 检查者 报告者 他们都继承TaskObserver类 这样减少了代码的重复 而且方便了代码的维护
public class Assignee extends TaskObserver { @Override public void sendEmail() { print( [Assignee] The current status is : ); print( [Assignee] The current process is : ); print( [Assignee] The current checklist is : ); } public String toString() { return Assignee ; }}public class Reviewer extends TaskObserver { @Override public void sendEmail() { print( [Reviewer] The current status is : ); print( [Reviewer] The current process is : ); print( [Reviewer] The current checklist is : ); } public String toString() { return Reviewer ; }}public class Reporter extends TaskObserver { @Override public void sendEmail() { print( [Reporter] The current status is : ); print( [Reporter] The current process is : ); print( [Reporter] The current checklist is : ); } public String toString() { return Reporter ; }}
然后我们需要编写一个类用来演示观察者模式 在这个类中会演示注册观察者 取消特定观察者 更改主体对象信息然后观察者自动得到通知并更新信息
public class TaskManager { public static void main(String[] args) { // Create subject TaskSubject taskSubject = new TaskSubject(); // Create observers IObserver assignee = new Assignee(); IObserver reviewer = new Reviewer(); IObserver reporter = new Reporter(); // 注册观察者[因为我们使用的是一个列表 所以在通知观察者的时候是按照添加的顺序通知的] taskSubject registerObserver(assignee); taskSubject registerObserver(reviewer); taskSubject registerObserver(reporter); // 更新主体对象的信息 taskSubject setStatus( Assigned ); taskSubject setProcess( No Process Attacted ); taskSubject setCheckList( CheckList Version ); // 通知所有观察者 taskSubject notifyObserver(); // 更新主体对象信息 taskSubject setStatus( In Progress ); taskSubject setProcess( Process Attached ); taskSubject setCheckList( CheckList Version Final Version ); // 取消报告者的注册 并通知剩余所有观察者 taskSubject removeObserver(reporter); taskSubject notifyObserver(); }}
输出的信息如下
lishixinzhi/Article/program/Java/gj/201311/27595
2. 观察者模式的实现方式
观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。
3. 什么是观察者模式`?
观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在这里先讲一下面向对象设计的一个重要原则——单一职责原则。因此系统的每个对象应该将重点放在问题域中的离散抽象上。因此理想的情况下,一个对象只做一件事情。这样在开发中也就带来了诸多的好处:提供了重用性和维护性,也是进行重构的良好的基础。
因此几乎所有的设计模式都是基于这个基本的设计原则来的。观察者模式的起源我觉得应该是在GUI和业务数据的处理上,因为现在绝大多数讲解观察者模式的例子都是这一题材。但是观察者模式的应用决不仅限于此一方面。
下面我们就来看看观察者模式的组成部分。
1) 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。
2) 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。
3) 具体目标角色(Concrete Subject):将有关状态存入各个Concrete Observer对象。当它的状态发生改变时, 向它的各个观察者发出通知。
4) 具体观察者角色(Concrete Observer):存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向Concrete Subject对象的引用。
4. 什么是观察者模式`?
观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在这里先讲一下面向对象设计的一个重要原则——单一职责原则。因此系统的每个对象应该将重点放在问题域中的离散抽象上。因此理想的情况下,一个对象只做一件事情。这样在开发中也就带来了诸多的好处:提供了重用性和维护性,也是进行重构的良好的基础。
因此几乎所有的设计模式都是基于这个基本的设计原则来的。观察者模式的起源我觉得应该是在GUI和业务数据的处理上,因为现在绝大多数讲解观察者模式的例子都是这一题材。但是观察者模式的应用决不仅限于此一方面。
下面我们就来看看观察者模式的组成部分。
1) 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。
2) 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。
3) 具体目标角色(Concrete Subject):将有关状态存入各个Concrete Observer对象。当它的状态发生改变时, 向它的各个观察者发出通知。
4) 具体观察者角色(Concrete Observer):存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向Concrete Subject对象的引用。
5. java中什么叫"观察者设计模式"?
才开始学习Java没有多久,看过了不少基础类的书籍,正尝试着做一些基础性的项目来整合零散的知识点。偶然之下在网上查资料时看到别人文章里提及"观察者设计模式",突然很诧异,没有听说过这种模式呢~故而在网上搜集了一些资料又在图书馆找了一下相关书籍来学习。突然觉得也来学学他人,做做笔记吧~例如:现在很多的购房者都在关注房子的价格变化,每当房子价格变化时,所有 购房者都可以观察得到,实际上以上的购房者都属于观察者,他们都在关注着房子的价格。。其实这就叫观察者设计模式。由java.util包中提供的Observable类和Observer接口便可以轻松实现观察者模式,需要被观察的类必须继承Observable类。Observable类的常用方法有:public void addObserver(Observer o) ; public void deleteObserver(Observero); public void update(Observable o,Object arg);protected void setChanged(); //被观察者状态发生改变public void notifyObservers(Object arg) //通知所有观察者状态已改变对观察者模式的第一感觉是,实现此模式应该可以大大简化代码,使相关功能的代码块语义更清晰. 具体还得在以后应用中慢慢体悟下附一个观察者模式的实现:package org.lxh.demoll.obserdemo;import java.util.Observable;
import java.util.Observer;
class House extends Observable{
private float price;
public House(float price){
this.price = price;
}
public void setPrice(float price){
super.setChanged();
super.notifyObservers(price);
this.price=price;
}
public String toString(){
return "房子价格为:" + this.price;
}
}
class HousePriceObserver implements Observer{
private String name;
public HousePriceObserver(String name){
this.name = name;
}
public void update(Observable obj,Object arg){
if(arg instanceof Float){
System.out.println(this.name+"观察到价格是否更改为:");
System.out.println(((Float) arg).floatValue());
}
}
}
public class ObserDemo01{
public static void main(String[] args){
House h = new House(1000000);
HousePriceObserver hpo1 = new HousePriceObserver("购房者A");
HousePriceObserver hpo2 = new HousePriceObserver("购房者B");
HousePriceObserver hpo3 = new HousePriceObserver("购房者C");
h.addObserver(hpo1);
h.addObserver(hpo2);
h.addObserver(hpo3);
System.out.println(h);
h.setPrice(666666);
System.out.println(h);
}
}
6. 什么是观察者模式`?
观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在这里先讲一下面向对象设计的一个重要原则——单一职责原则。因此系统的每个对象应该将重点放在问题域中的离散抽象上。因此理想的情况下,一个对象只做一件事情。这样在开发中也就带来了诸多的好处:提供了重用性和维护性,也是进行重构的良好的基础。因此几乎所有的设计模式都是基于这个基本的设计原则来的。观察者模式的起源我觉得应该是在GUI和业务数据的处理上,因为现在绝大多数讲解观察者模式的例子都是这一题材。但是观察者模式的应用决不仅限于此一方面。下面我们就来看看观察者模式的组成部分。1)抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。2)抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。3)具体目标角色(ConcreteSubject):将有关状态存入各个ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。4)具体观察者角色(ConcreteObserver):存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向ConcreteSubject对象的引用。