在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交互的对象。例如,每个人必须记住他(她)所有朋友的电话;而且,朋友中如果有人的电话修改了,他(她)必须告诉其他所有的朋友修改,这叫作“牵一发而动全身”,非常复杂。
如果把这种“网状结构”改为“星形结构”的话,将大大降低它们之间的“耦合性”,这时只要找一个“中介者”就可以了。如前面所说的“每个人必须记住所有朋友电话”的问题,只要在网上建立一个每个朋友都可以访问的“通信录”就解决了。这样的例子还有很多,例如,你刚刚参力口工作想租房,可以找“房屋中介”;或者,自己刚刚到一个陌生城市找工作,可以找“人才交流中心”帮忙
什么叫中介者(Mediator)模式?
中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
例子
在这个例子中,中介器封装了一组对象({@link partymember(派对成员)})互动。他们使用中介器({@link party(派对)})而不是直接相互引用接口。
public class App {
/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
// create party and members
Party party = new PartyImpl();
var hobbit = new Hobbit();
var wizard = new Wizard();
var rogue = new Rogue();
var hunter = new Hunter();
// add party members
party.addMember(hobbit);
party.addMember(wizard);
party.addMember(rogue);
party.addMember(hunter);
// perform actions -> the other party members
// are notified by the party
hobbit.act(Action.ENEMY);
wizard.act(Action.TALE);
rogue.act(Action.GOLD);
hunter.act(Action.HUNT);
}
}
/**
* Action enumeration.
*/
public enum Action {
HUNT("hunted a rabbit", "arrives for dinner"),
TALE("tells a tale", "comes to listen"),
GOLD("found gold", "takes his share of the gold"),
ENEMY("spotted enemies", "runs for cover"),
NONE("", "");
private final String title;
private final String description;
Action(String title, String description) {
this.title = title;
this.description = description;
}
public String getDescription() {
return description;
}
public String toString() {
return title;
}
}
/**
* Interface for party members interacting with {@link Party}.
*/
public interface PartyMember {
void joinedParty(Party party);
void partyAction(Action action);
void act(Action action);
}
/**
* Abstract base class for party members.
*/
public abstract class PartyMemberBase implements PartyMember {
private static final Logger LOGGER = LoggerFactory.getLogger(PartyMemberBase.class);
protected Party party;
@Override
public void joinedParty(Party party) {
LOGGER.info("{} joins the party", this);
this.party = party;
}
@Override
public void partyAction(Action action) {
LOGGER.info("{} {}", this, action.getDescription());
}
@Override
public void act(Action action) {
if (party != null) {
LOGGER.info("{} {}", this, action);
party.act(this, action);
}
}
@Override
public abstract String toString();
}
/**
* Hobbit party member.
*/
public class Hobbit extends PartyMemberBase {
@Override
public String toString() {
return "Hobbit";
}
}
/**
* Hunter party member.
*/
public class Hunter extends PartyMemberBase {
@Override
public String toString() {
return "Hunter";
}
}
/**
* Rogue party member.
*/
public class Rogue extends PartyMemberBase {
@Override
public String toString() {
return "Rogue";
}
}
/**
* Wizard party member.
*/
public class Wizard extends PartyMemberBase {
@Override
public String toString() {
return "Wizard";
}
}
/**
* Party interface.
*/
public interface Party {
void addMember(PartyMember member);
void act(PartyMember actor, Action action);
}
/**
* Party implementation.
*/
public class PartyImpl implements Party {
private final List<PartyMember> members;
public PartyImpl() {
members = new ArrayList<>();
}
@Override
public void act(PartyMember actor, Action action) {
for (var member : members) {
if (!member.equals(actor)) {
member.partyAction(action);
}
}
}
@Override
public void addMember(PartyMember member) {
members.add(member);
member.joinedParty(this);
}
}