00.2 番外篇2 - java 中实现委托模式.(Delegate)

     委托可以理解为是一种代理, C# 中对委托做了完善的封装, 但是 java 中并没有相应的实现, 我们可以使用反射来简单实现委托的工作方式.

Event 类, 相当于对一个方法的封装, 也就是说通过Event 来实现方法的调用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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);//利用反射机制调用函数
}
}

EventHandler 用来处理Event, 登记注册, 删除, 或者是发出通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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));
}
// 需要增加 removeEvent 方法. 否则会内存溢出
public void notifyX() throws Exception {
for (Event event : objects) {
event.invoke();
}
}
}

Notifier 发布者/通知者类的接口, 向所有的订阅者/观察者发布消息.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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);
// 这里需要增加 remove 方法. 也就是删除观察者.
public abstract void notifyX();
}

定义一个具体的发布者/通知者.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();
}
}
}

这里随便定义两个观察者.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 玩儿游戏的
public class PlayingGameListener {
public PlayingGameListener() {
System.out.println("playing");
}
public void stopPlayingGame(Date date) {
System.out.println("stop playing" + date);
}
}
// 看电视的
public class WatchingTVListener {
public WatchingTVListener() {
System.out.println("watching TV");
}
public void stopWatchingTV(Date date) {
System.out.println("stop watching" + date);
}
}

客户端代码调用

1
2
3
4
5
6
7
8
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();

输出结果

1
2
3
4
playing
watching TV
stop playingFri Jan 27 15:41:10 CST 2017
stop watchingFri Jan 27 15:41:10 CST 2017

     这里仅仅是代表一种想法, java 中可以实现委托这种方式来实现观察者模式.

~感谢捧场,您的支持将鼓励我继续创作~