### 事件委托
委托就像是拿另一種方法替代了原本的方法,交給現在這個替代后的方法使用,使用時和原來的方法沒有區別。
在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{
@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();
}
}
~~~
這樣就相當于c#的委托了,這樣也改掉了觀察者模式的缺點,通知者類完全不知道自己需要通知的是誰,做到了完全解耦,同時也去掉了抽象的觀察者類。
昨天完全不明白java委托要怎么做,后來終于找到了一個,感覺這個還不錯,就寫出來和大家分享一下。
- 前言
- (1)代碼無錯就是優?——簡單工廠模式
- (2)商場促銷——策略模式
- (3)&amp;(4)&amp;(5) 設計模式原則
- (6)穿什么有這么重要?——裝飾模式
- (7)為別人做嫁衣——代理模式
- (8)雷鋒依然在人間——工廠方法模式
- (9)簡歷復印——原型模式
- (10)考題抄錯會做也白搭——模板方法模式
- (11)迪米特法則
- (12)牛市股票還會虧錢?—— 外觀模式
- (13)好菜每回味不同——建造者模式
- (14)老板回來,我不知道——觀察者模式
- java實現事件委托
- (15)就不能不還DB嗎?—— 抽象工廠模式
- (16)無盡加班何時休息——狀態模式
- (17)在NBA我需要翻譯——適配器模式
- (18)如果再回到從前——備忘錄模式
- (19)分公司=部門——組合設計模式
- (20)想走?可以!先買票——迭代器模式
- (21)有些類也需計劃生育——單例模式
- (22)手機軟件何時統一——橋接模式
- (23)烤羊肉串引來的思考——命令模式
- (24)加薪非要老總批?——職責鏈模式
- (25)世界需要和平——中介者模式
- (26)項目多也別傻做——享元模式
- (28)男人和女人——訪問者模式