中介者模式是行为型模式的一种,他一般用于系统中不同对象间消息的统一处理,在GoF中这样介绍:

通过某种封装,将不同对象松耦合,使之可以互相影响,消息可以互相转发,同时也允许不同对象互不依赖

当某个应用出现很多对象互相影响时,中介者模式就派上用场了。如果对象之间是强耦合的,这样就会导致维护难度大大增大,不易扩展。而中介者模式可以使对象间松耦合。

飞机场广播就是一个很好的例子,提供了不同飞机之间消息转发的一种机制。对于模式来说的话,他一般是作为一个中间路由,就好比游戏服务中gateway服务一样。

系统中互相交流的对象,我们称之为同事(-_-),我们通常用一个接口类或抽象类表示,然后针对不同的同事再实现具体类

Mediator Interface

首先我们创建一个 Mediator Interface,定义了中介者是如何工作的

ChatMediator.java

1
2
3
4
5
6
7
package com.walterlife.dp.MediatorDP;

public interface CharMediator {
public void sendMessage(String msg, User user);

public void addUser(User user);
}

Colleague Interface

同事间可以互相转发消息,可以将之定义为接口或抽象类,这里我把他定义为抽象类

User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.walterlife.dp.MediatorDP;

public abstract class User {
CharMediator mediator;

String name;

public User(CharMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}

public abstract void sendMessage(String msg);

public abstract void receive(String msg);
}

在每个同事的内部维护着中介者的引用,这样就可以和其他同事间互相交流了

Concrete Mediator

现在开始实现具体的中介者,该中介者内部维护这 Colleagues list,同时提供了同事间交流的逻辑

ChatMediatorImpl.java

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
32
33
34
35
36
37
package com.walterlife.dp.MediatorDP;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

public class CharMediatorImpl implements CharMediator {

private static Logger logger = Logger.getLogger(CharMediatorImpl.class);

private List<User> users = new ArrayList<User>();

@Override
public void sendMessage(String msg, User user) {
// TODO Auto-generated method stub
for(User u: users) {
if(u != user) {
u.receive(msg);
}
}
}

@Override
public void addUser(User user) {
// TODO Auto-generated method stub
if(user != null) {
if(!users.contains(user)) {
users.add(user);
} else {
logger.warn("add user name " + user.getName() + " is already existing!!!");
}
} else {
logger.warn("add user param is null!!!");
}
}
}

Concrete Colleague

现在我们开始实现具体的Colleagues

UserImpl.java

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
package com.walterlife.dp.MediatorDP;

import org.apache.log4j.Logger;

public class UserImpl extends User {

private static Logger logger = Logger.getLogger(CharMediatorImpl.class);

public UserImpl(CharMediator mediator, String name) {
super(mediator, name);
}

@Override
public void sendMessage(String msg) {
// TODO Auto-generated method stub
logger.info("User " + this.name + " send msg " + msg + "!!!");
mediator.sendMessage(msg, this);
}

@Override
public void receive(String msg) {
// TODO Auto-generated method stub
logger.info("User " + this.name + " receive msg " + msg + "!!!");
}

}

在Colleague 进行发消息时,他是通过中介者来发送的,但是他是不知道中介者内部是如何处理的

测试代码

现在我们开始测试已经实现的中介者模式,主要实现是,先往中介者中添加Colleagues,然后其中一个Colleague 发送消息来测试逻辑的正确性

1
2
3
4
5
6
7
8
9
10
public static void testMediator() {
CharMediatorImpl mediator = new CharMediatorImpl();
UserImpl walter = new UserImpl(mediator, "walter");
mediator.addUser(walter);
mediator.addUser(new UserImpl(mediator, "ym"));
mediator.addUser(new UserImpl(mediator, "cj"));
mediator.addUser(new UserImpl(mediator, "test"));

walter.sendMessage("Hello World");
}

解释结果

1
2
3
4
2015-09-08 08:27:49 INFO  com.walterlife.dp.MediatorDP.UserImpl sendMessage:16 -> User walter send msg Hello World!!!
2015-09-08 08:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl receive:23 -> User ym receive msg Hello World!!!
2015-09-08 08:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl receive:23 -> User cj receive msg Hello World!!!
2015-09-08 08:27:49 INFO com.walterlife.dp.MediatorDP.UserImpl receive:23 -> User test receive msg Hello World!!!

留言