观察者模式和java委托
观察者模式与java委托
- 所谓观察者模式,指的某个状态信息的改变,会影响其他一系列的操作,这时就可以将这些操作抽象化,同时创建一个类统一的管理和执行这些操作。把这些抽象出来的操作称为观察者类,而管理这些操作的类称为通知者类,通知者类维护着一个观察者类的集合,可以追加和删除观察者,同时可遍历通知所有观察者类执行操作。

- 观察者模式的不足:虽然观察者模式提取出了抽象类,让类与类之间不互相依赖,共同依赖于抽象接口,这符合依赖倒转原则,但他们仍然依赖着抽象接口,而且有些时候不能提取出抽象的观察者(比如引用jar包)。
- java委托机制与观察者模式:委托机制的实现不再需要提取观察者抽象类,观察者和通知者互不依赖。java利用反射即可实现,代码实例如下:
事件类
package com.suski.delegate;
import java.lang.reflect.Method;
public class Event {
private Object object;
private String methodName;
private Object[] params;
private Class[] paramTypes;
public Event(Object object,String method,Object...args)
{
this.object = object;
this.methodName = method;
this.params = args;
contractParamTypes(this.params);
}
private void contractParamTypes(Object[] params)
{
this.paramTypes = new Class[params.length];
for (int i=0;i<params.length;i++)
{
this.paramTypes[i] = params[i].getClass();
}
}
public void invoke() throws Exception
{
Method method = object.getClass().getMethod(this.methodName, this.paramTypes);//判断是否存在这个函数
if (null == method)
{
return;
}
method.invoke(this.object, this.params);//利用反射机制调用函数
}
}
事件管理类
package com.suski.delegate; import java.util.ArrayList;
import java.util.List; public class EventHandler { private List<Event> objects; public EventHandler()
{
objects = new ArrayList<Event>();
} public void addEvent(Object object, String methodName, Object...args)
{
objects.add(new Event(object, methodName, args));
} public void notifyX() throws Exception
{
for (Event event : objects)
{
event.invoke();
}
}
}
通知者抽象类
package com.suski.delegate;
public abstract class Notifier {
private EventHandler eventHandler = new EventHandler();
public EventHandler getEventHandler()
{
return eventHandler;
}
public void setEventHandler(EventHandler eventHandler)
{
this.eventHandler = eventHandler;
}
public abstract void addListener(Object object,String methodName, Object...args);
public abstract void notifyX();
}
通知者具体实现类
package com.suski.delegate;
public class ConcreteNotifier extends Notifier{
@Override
public void addListener(Object object, String methodName, Object... args) {
this.getEventHandler().addEvent(object, methodName, args);
}
@Override
public void notifyX() {
try {
this.getEventHandler().notifyX();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
具体的观察者类,不再需要抽象观察者
package com.suski.delegate;
import java.util.Date;
public class WatchingTVListener {
public WatchingTVListener()
{
System.out.println("watching TV");
}
public void stopWatchingTV(Date date)
{
System.out.println("stop watching" + date);
}
}
package com.suski.delegate;
import java.util.Date;
public class PlayingGameListener {
public PlayingGameListener()
{
System.out.println("playing");
}
public void stopPlayingGame(Date date)
{
System.out.println("stop playing" + date);
}
}
测试方法
package com.suski.delegate;
import java.util.Date;
public class Test {
public static void main (String[] args)
{
Notifier goodNotifier = new ConcreteNotifier();
PlayingGameListener playingGameListener = new PlayingGameListener();
WatchingTVListener watchingTVListener = new WatchingTVListener();
goodNotifier.addListener(playingGameListener, "stopPlayingGame", new Date());
goodNotifier.addListener(watchingTVListener, "stopWatchingTV", new Date());
goodNotifier.notifyX();
}
}
观察者模式和java委托的更多相关文章
- 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别
在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...
- C#学习笔记(十七):委托、事件、观察者模式、匿名委托和lambert表达式
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- java委托
上文讲过观察者模式,尽管已经用了依赖倒转原则,但是"抽象通知者"还是依赖"抽象观察者",也就是说万一没有了抽象观察者这样的接口,通知的功能就完不成了.另一方面, ...
- 新手码农浅谈观察者模式(java语言简单实现)
一:什么是观察者模式: 官方定义:定义对象间一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 举个例子,很多人都会订阅天气预报,当气象台获得明天的天气情况( ...
- 观察者模式及Java实现例子
http://www.cnblogs.com/mengdd/archive/2013/02/07/2908929.html 观察者模式 观察者模式 Observer 观察者模式定义了一种一对多的依赖关 ...
- 设计模式之观察者模式(Java)
设计模式(Design pattern)是什么?它是一套由四人组(The Gang of Four, [1]的作者)总结出来的软件设计框架.其目的是为了提高代码的可重用性,增强系统的可维护性和代码的易 ...
- JAVA委托事件处理机制
1)事件:用户对程序的某一种功能性操作. Java中的事件主要有两种: 1.组件类事件 componentEvent.ContainerEvent.WindowEvent.FocusEvent.Pai ...
- 转:java 委托
委托模式是软件设计模式中的一项基本技巧.在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理.委托模式是一项基本技巧,许多其他的模式,如状态模式.策略模式.访问者模式 ...
- C# ~ 从 委托事件 到 观察者模式 - Observer
委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分: 参考 [1]. 初识事件 到 自定义事件: [2]. 从类型不安全的委托 到 类型安全的事件: [3]. 函数指针 ...
随机推荐
- 使用Unity5.1进行VR开发的配置(最新的未必是最好的!!!)
随着Unity5.1的发布,之前的Oculus Rift和Gear VR 开发流程发生了巨大的变化,这也算是小白鼠们必须付出的代价了~ 那么Unity5.1和Oculus的整合究竟发生了哪些变化,对开 ...
- S-T平面图
给定一个平面图和一个源点S.汇点T都在图中无边界的区域上,这样的图叫S-T平面图 我们把图中每一个独立的面看做一个点,对于每条边e,将它两侧的面连一条边,其中靠近S的一段与S相连,与T相连的一段与T相 ...
- Redis的List链表类型命令
List是一个链表结构,主要功能是push.pop.获取一个范围的所有值等等,操作中key理解为链表的名字.list类型其实就是一个每个子元素都是string类型的双向链表.我们可以通过push.po ...
- flex的使用实例
之前的随笔从阮一峰老师那里学到了flex的基本用法及作用,现在来把flex具体运用到实例中,看看flex的弹性布局效果. 1. flex设置元素垂直居中对齐 在之前的一篇文章中记载过如何垂直居中对齐 ...
- HDU--2363
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2363 分析:最短路+二分. #include<iostream> #include< ...
- bzoj3205 [Apio2013]机器人
3205: [Apio2013]机器人 Time Limit: 15 Sec Memory Limit: 128 MBSubmit: 953 Solved: 227[Submit][Status] ...
- C++标准库头文件找不到的问题
当你写C++程序时,在头文件中包含C++标准库的头文件,比如#include <string>,而编译器提示你找不到头文件! 原因就是你的实现源文件扩展名是".c"而不 ...
- 改变你一生的编辑器:VSCode使用总结
开发十年,只剩下这套Java开发体系了 >>> 前言:vscode是微软出品的,基于Electron和TypeScript的,现在已经是最火的一款文本编辑器.我认为vscode是 ...
- 您是哪个等级的CSS开发人员?
我们在不断的学习,追求进步与提高,到底学到什么程度了,到底是 不是真的了解CSS,是哪个层次了呢.我们来对照一下. 第0级:CSS?那不是一个多人射击游戏吗? CSS? Isn't that a m ...
- [Mac]一些命令技巧
Git相关 mac下git默认不区分大小写,通过下面脚本可以改变 #!/bin/bash # 让git区分大小写 cd 'path-of-project' git config core.ignore ...