事件委托java

来源:互联网 发布:80年代台湾经济 知乎 编辑:程序博客网 时间:2024/06/05 02:44


委托就像是拿另一种方法替代了原本的方法,交给现在这个替代后的方法使用,使用时和原来的方法没有区别。

在c#里面语法中就有委托这个概念,所以实现起来十分的方便,可是在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();}}}

这个类就是把事件都放入一个List中,到时候在一次取出来

队列定义完了,那么就可以定义通知的抽象类了

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{@Overridepublic void addListener(Object object, String methodName, Object... args) {this.getEventHandler().addEvent(object, methodName, args);}@Overridepublic void notifyX() {try {this.getEventHandler().notifyX();} catch (Exception e) {// TODO: handle exceptione.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();}}

这样就相当于c#的委托了,这样也改掉了观察者模式的缺点,通知者类完全不知道自己需要通知的是谁,做到了完全解耦,同时也去掉了抽象的观察者类。

原创粉丝点击