设计模式学习笔记(13)中介者

本文实例代码:https://github.com/JamesZBL/java_design_patterns

中介者(Mediator)模式是用来降低多个对象和类之间的通信复杂性的。这种模式中通常提供一个充当中介者角色的类,用来承担“中心化”或“集中化”的职能,与各个对象之间都可以分别相互通信,它的一大优势是减少或避免其他对象之间的互相通信,在通信方面降低了耦合度。

实例

现在要举行一场派对,派对中会穿插各种游戏活动,凡是参加派对的人都要到派对举办者那里登记。并且,每次有参与者想要参加派对中的某个活动的时候都要先向派对举办者提出请求,由举办者来批准他的请求,然后这个活动才开始进行。

先定义派对举办者行为的接口,举办者的职责有邀请成员加入和批准成员参加活动

Party.java


public interface Party {

  void addMember(PartyMember member);

  void letAct(PartyMember member, Activity activity);

}

然后是派对成员的接口,成员的职责有参加派对、提出参加活动的请求以及参加活动

PartyMember.java


public interface PartyMember {

  void joinParty(Party party);

  void partyActivity(Activity activity);

  void act(Activity activity);

}

再定义一个类来具体实现派对举办者功能

PartyImpl.java


public class PartyImpl implements Party {

  private List<PartyMember> members;

  public PartyImpl() {

    members = new ArrayList<>();

  }

  @Override

  public void addMember(PartyMember member) {

    members.add(member);

    member.joinParty(this);

  }

  @Override

  public void letAct(PartyMember member, Activity activity) {

    for (PartyMember m : members) {

      if (!member.equals(m)) {

        m.partyActivity(activity);

      }

    }

  }

}

定义一个派对实现成员接口的抽象类,保留一个 toString() 抽象方法,留到其具体子类中实现

AbstractPartyMember.java


public abstract class AbstractPartyMember implements PartyMember {

  private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPartyMember.class);

  private Party party;

  @Override

  public void joinParty(Party party) {

    LOGGER.info("{}加入了派对", this);

    this.party = party;

  }

  @Override

  public void act(Activity activity) {

    if (null != activity) {

      LOGGER.info("{}提议进行{}活动", this, activity);

      party.letAct(this, activity);

    }

  }

  @Override

  public void partyActivity(Activity activity) {

    LOGGER.info("进行派对活动,名称:{},介绍:{}", activity, activity.getDescription());

  }

  @Override

  public abstract String toString();

}

派对中提供的活动有射击、猜灯谜、桌游和唱歌,为其定义一个枚举类

Activity.java


public enum Activity {

  SHOOT("射击", "Shooting"), GUESS("猜灯谜", "Guess"), DESKTOP_GAME("桌游", "Desktop games"), SING("唱歌", "singing");

  private String name;

  private String description;

  Activity(String name, String description) {

    this.name = name;

    this.description = description;

  }

  public String getDescription() {

    return description;

  }

  @Override

  public String toString() {

    return name;

  }

}

有四种不同职业或特点的参与者,分别继承自 AbstractPartyMember 类,分别覆盖了父类中的 toString() 方法来表示其特征

他们分别是 Officer.java,Oldman.java,Student.javaBusinessman.java,此处省略具体代码

现在来举办一次派对,参与者们分别向派对举办者提出活动请求,举办者分别批准

App.java


public class Application {

  private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);

  public static void main(String[] args) {

    // 派对举办者

    Party party = new PartyImpl();

    // 学生

    Student student = new Student();

    // 官员

    Officer officer = new Officer();

    // 商人

    Businessman businessman = new Businessman();

    // 老人

    Oldman oldman = new Oldman();

    // 邀请成员加入

    party.addMember(student);

    party.addMember(officer);

    party.addMember(businessman);

    party.addMember(oldman);

    // 分别提出参加活动的请求

    student.act(Activity.DESKTOP_GAME);

    officer.act(Activity.GUESS);

    businessman.act(Activity.SHOOT);

    oldman.act(Activity.SING);

  }

}

总结

需要使用中介者模式的场景是对象与对象之间存在大量的关联关系,这样下去会导致系统的结构变得复杂,一个对象的改动势必会影响到另一个与之关联的对象,,同时做出相应的改动,它们之间分别相互耦合,几乎形成了“网状”的结构,这对于复杂的系统是非常不利的。

中介者模式可以将这种 “网状结构” 解耦形成 “星形结构”,最典型的应用实例就是 MVC 结构,其中的 C (控制器) 就担当了 V(视图)和 M(模型)之间的中介者。

中介者模式的缺点是会使中介者对象异常复杂,降低了可维护性,所以应当尽量避免在对象间的职责划分比较难以界定的场景中使用。

个人博客同步更新,获取更多技术分享请关注:郑保乐的博客

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容