本文目录
观察者模式 - 设计模式
观察者模式定义了一个一对多的对象关系 一个主体对象对应多个观察者对象 当主体对象发生改变时 所有它对应的观察者对象都会自动得到通知并更新
本文将给出一个相应的事例具体说明观察者模式是如果工作的 这个事例演示了一个当一个任务的信息改变时通知这个任务所涉及所有人员的事例 任务信息包括任务状态 任务所采用的处理流程和任务完成后的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《IObserver》(); } @Override public void notifyObserver() { // 调用观察者的方法通知并更新观察者信息 for(IObserver observer : _observers) { observer remind(this); } } @Override public void registerObserver(IObserver observer) { if(ntains(observer)) { System out println( 《 + observer + 》 is already registed! ); } // Register an observer _observers add(observer); System out println( 《 + observer + 》 is registed successfully! ); } @Override public void removeObserver(IObserver observer) { if(!ntains(observer)) { System out println( 《 + observer + 》 is never registed! ); } // Remove an observer _observers remove(observer); System out println( 《 + observer + 》 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《IObserver》 _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;}
然后定义任务受托人 检查者 报告者 他们都继承TaskObserver类 这样减少了代码的重复 而且方便了代码的维护
public class Assignee extends TaskObserver { @Override public void sendEmail() { print( The current checklist is : 《 + this _checkList + 》 ); } public String toString() { return Reporter ; }}
然后我们需要编写一个类用来演示观察者模式 在这个类中会演示注册观察者 取消特定观察者 更改主体对象信息然后观察者自动得到通知并更新信息
public class TaskManager { public static void main(String 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
php 命令链模式和观察者模式的区别
个人觉得命令链模式跟观察者模式,虽然都是设计模式。但是两者很不一样。命令链模式是一系列像链式一样的操作。而观察者模式,是事件监听一样,在某个操作前,操作中,或操作后,触发一个其他的动作,来处理相应的逻辑。
请问观察者模式一般用在哪里呢好像在项目中没用到过 - PHP进阶讨论
个人认为:观察者模式只是单例模式的升级版,区别在于:单例模式在本类内部实现,获取类的实例,而观察者模式则要在另建观察类或观察方法来实现,获取类的实例,而在获取这个类的实例的时候,观察类或观察方法就要对类的实例根据情况进行调整。