学习设计模式之中介者模式
中介者模式
用一个中介对象来封装一系列的对象的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
类结构图
Mediator
抽象中介者,定义了同事对象到中介者对象的接口。
ConcreteMediator
具体的中介者对象,实现抽象类的方法,它需要知道所有的 “组织” 类。并从具体的 “组织” 类接收消息,向具体的 ““组织”” 对象对象发出命令。
Colleague
抽象的 “组织” 对象,比如国家之间的关系。
ConcreteColleague
具体的 “组织” 对象,每个具体的对象只知道自己的行为,而不了解其他 “组织” 类的情况,但它们都知道中介者对象。
代码示例
直接写示例代码可能会比较模糊,举个栗子元朝末年六大门派围攻光明顶,少林、峨眉、武当、崆峒、华山、昆仑在围攻之前每个门派都是各自独立的,各自维护着自己门派的关系。关系极为混乱,一般这个时候就需要选举出一个武林盟主加入的门派那么就可以通过这个联盟来维持关系。联盟关联着所有的门派,进而简化了各个门派之间的交往。
public interface Alliance {
void addAlliance(School school);
void attack(School activeSide, School passiveSide);
}
public class ConcreteAlliance implements Alliance {
private List<School> schools;
public ConcreteAlliance() {
this.schools = new ArrayList<>();
}
@Override
public void addAlliance(School school) {
if (!schools.contains(school)) {
this.schools.add(school);
}
}
@Override
public void attack(School activeSide, School passiveSide) {
if (schools.contains(activeSide) && schools.contains(passiveSide)) {
System.out.println("攻击方" + activeSide.getName() + "以及被攻方" + passiveSide.getName() + "都已加入联盟,不允许内讧!");
} else if (schools.contains(activeSide) && !schools.contains(passiveSide)) {
System.out.println("攻击方" + activeSide.getName() + "已加入联盟,被攻方" + passiveSide.getName() + "不在联盟之中,将集体攻打该门派!");
for (School school : schools) {
school.attack(passiveSide);
}
} else {
System.out.println("攻击方" + activeSide.getName() + "未加入联盟,联盟不干预此事!");
activeSide.attack(passiveSide);
}
}
}
public abstract class School {
private String name;
private Alliance alliance;
public School(Alliance alliance) {
this.alliance = alliance;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Alliance getAlliance() {
return alliance;
}
public void setAlliance(Alliance alliance) {
this.alliance = alliance;
}
public void attack(School passiveSide) {
System.out.println(getName() + "攻击" + passiveSide.getName());
}
public abstract void attackByPatternAlliance(School school);
}
public class EmeiSchool extends School {
public EmeiSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "峨嵋派";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
public class HuashanSchool extends School {
public HuashanSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "华山派";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
public class KongdongSchool extends School {
public KongdongSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "崆峒派";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
public class KunlunSchool extends School {
public KunlunSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "昆仑派";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
public class ShaolinSchool extends School {
public ShaolinSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "少林派";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
public class WudangSchool extends School {
public WudangSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "武当派";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
public class MingjiaoSchool extends School {
public MingjiaoSchool(Alliance alliance) {
super(alliance);
}
@Override
public String getName() {
return "明教";
}
@Override
public void attackByPatternAlliance(School school) {
getAlliance().attack(this, school);
}
}
客户端示例
public class AllianceClient {
public static void main(String[] args) {
Alliance alliance = new ConcreteAlliance();
EmeiSchool emeiSchool = new EmeiSchool(alliance);
HuashanSchool huashanSchool = new HuashanSchool(alliance);
KongdongSchool kongdongSchool = new KongdongSchool(alliance);
KunlunSchool kunlunSchool = new KunlunSchool(alliance);
ShaolinSchool shaolinSchool = new ShaolinSchool(alliance);
WudangSchool wudangSchool = new WudangSchool(alliance);
MingjiaoSchool mingjiaoSchool = new MingjiaoSchool(alliance);
alliance.addAlliance(emeiSchool);
alliance.addAlliance(huashanSchool);
alliance.addAlliance(kongdongSchool);
alliance.addAlliance(kunlunSchool);
alliance.addAlliance(shaolinSchool);
alliance.addAlliance(wudangSchool);
emeiSchool.attackByPatternAlliance(huashanSchool);
System.out.println("=========================================");
emeiSchool.attackByPatternAlliance(mingjiaoSchool);
}
}
运行结果
攻击方峨嵋派以及被攻方华山派都已加入联盟,不允许内讧!
=========================================
攻击方峨嵋派已加入联盟,被攻方明教不在联盟之中,将集体攻打该门派!
峨嵋派攻击明教
华山派攻击明教
崆峒派攻击明教
昆仑派攻击明教
少林派攻击明教
武当派攻击明教
Process finished with exit code 0
优点
减少了各个 Colleague 类的耦合关系,使得可以独立地改变和复用各个 Colleague 类和 Mediator。
缺点
随着 Mediator 管理的 “组织类” 越来越多,那么中介者就会变得非常复杂。会使系统变得复杂难以维护。
勿在浮沙筑高台
——个人浅见,难免有误导之处,麻烦请指出。