【设计模式】中介者模式

系列文章目录


文章目录


世界需要和平

本篇文章为大家介绍中介者模式,中介者模式又叫做调停者模式,其实就是中间人或者调停者的意思,举个例子。

比如乌克兰,战争带给人类的真是无法弥补的伤痛,世界需要和平,再比如巴以问题、伊核问题以及各国间的政治外交问题,构成了极为复杂的国际形势。

由于各国的利益不同,所以矛盾冲突是难免的,但如果有这样一个组织,由各国的代表组成,用来维护国际和平与安全,这也就是联合国组织,它起到的就是一个调停者、中介者的角色。自联合国建立之后就没有再出现过世界大战这样规模的战争了。

国与国之间的关系,就类似于不同的对象和对象之间的关系,这就要求对象之间需要知道其他所有对象,尽管将一个系统分割成许多对象通常可以增加其可复用性,但是对象间相互连接的激增又会降低其可复用性了 ,导致这种结果的原因是 大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难了 。

解决这样的问题,我们可以用 '迪米特原则' ,如果两个类之间不必彼此直接通信,那么者两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。在这里意思就是,国与国之间可以通过联合国这个中介者来发生关系,而不是直接通信。只有这样,每个具体对象不再通过直接的联系与另一个对象发生相互作用,而是通过中介者对象与另一个对象发生相互作用。中介者对象的设计,使得系统的结构不会因为新对象的引入造成大量的修改工作。

中介者模式

中介者模式,用一个中介对象来封转一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使得其耦合松散,而且可以独立地改变他们之间的交互。

中介模式结构图:

Colleague叫做抽象同事类,而ConcreteColleague是具体同事类。,每个具体同事只知道自己的行为,而不了解其他同时类的情况,但他们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,他需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令。

Colleague类:抽象同事类。

java 复制代码
 abstract class Colleague{
        protected Mediator mediator;
        public Colleague(Mediator mediator){
            this.mediator = mediator;
        }
    }

ConcreteColleague1和ConcreteColleague2等各种同事对象;

java 复制代码
class ConcreteColleague1 extends Colleague{
        public ConcreteColleague1(Mediator mediator) {
            super(mediator);
        }
        public void send(String message){
            this.mediator.send(message,this);
        }
        public void notify(String message){
            System.out.println("同事1得到消息:" + message);
        }
    }
    class ConcreteColleague2 extends Colleague{
        public ConcreteColleague2(Mediator mediator) {
            super(mediator);
        }
        public void send(String message){
            this.mediator.send(message,this);
        }
        public void notify(String message){
            System.out.println("同事2得到消息:" + message);
        }
    }

Mediator抽象中介者类:

java 复制代码
    //中介者类
    abstract class Mediator{
        //定义一个抽象的发送消息方法,得到同事对象和发送消息。
        public abstract void send(String message,Colleague colleague);
    }

ConcreteMediator类:具体中介者类

java 复制代码
 class ConcreteMediator extends Mediator{
        private ConcreteColleague1 colleague1;
        private ConcreteColleague2 colleague2;

        public void setColleague1(ConcreteColleague1 value){
            this.colleague1 = value;
        }
        public void setColleague2(ConcreteColleague2 value){
            this.colleague2 = value;
        }
        @Override
        public void send(String message, Colleague colleague) {
            if(colleague  == colleague1){
                colleague2.notify();
            }else{
                colleague1.notify();
            }
        }
    }

客户端:

java 复制代码
  public static void main(String[] args) {
        ConcreteMediator m  = new ConcreteMediator();
        //让两个具体同事类人事中介者对象
        ConcreteColleague1 c1 = new ConcreteColleague1();
        ConcreteColleague2 c2 = new ConcreteColleague2();
        m.setColleague1(c1);
        m.setColleague2(c2);
        //具体同事类对象发送消息都是中介者类来转发
        c1.send("吃过饭了吗");
        c2.send("没有呢,你要请客吗");
    }

由于有了Mediator,使得COncreteColleague1和ConcreteColleague2在发送消息和接收消息时,其实是通过中介者来完成的,这就减少了他们之间的耦合度了。

下面对联合国这一实例代码化:

国家类

java 复制代码
 abstract class Country{
        protected UnitedNations unitedNations;
        public Country(UnitedNations unitedNations){
            this.unitedNations = unitedNations;
        }
    }

美国类:

java 复制代码
class USA extends Country{
        public USA(UnitedNations unitedNations) {
            super(unitedNations);
        }
        public void declare(String message){
            this.unitedNations.declare(message,this);
        }
        public void getMessage(String message){
            System.out.println("美国获得对方消息:" + message);
        }
    }

伊拉克类:

java 复制代码
class Iraq extends Country{
        public Iraq(UnitedNations unitedNations) {
            super(unitedNations);
        }
        public void declare(String message){
            this.unitedNations.declare(message,this);
        }
        public void getMessage(String message){
            System.out.println("伊拉克获得对方信息:" + message);
        }
    }

联合国机构类:

java 复制代码
abstract class UnitedNations {
        public abstract  void declare(String message,Country country);
    }

联合国安理会:相当于ConcreteMediator类

java 复制代码
 class UnitedNationsSecurityCouncil extends UnitedNations{
        private USA countryUSA;

        private Iraq countryIraq;

        public void setUSA(USA value){
            this.countryUSA  =USA;
        }
        public void setIraq(Iraq value){
            this.countryIraq = value;
        }
        @Override
        public void declare(String message, Country country) {
            if (country == this.countryUSA) {
                this.countryIraq.getMessage(message);
            } else if (country == this.countryIraq) {
                this.countryUSA.getMessage(message);
            }
        }
    }

客户端:

java 复制代码
 public static void main(String[] args) {
       UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();
       USA c1 = new USA(UNSC);
       Iraq c2 = new Iraq(UNSC);
       UNSC.setUSA(c1);
       UNSC.setIraq(c2);

       c1.declare("不准研究核武器,否则就要发动战争");
       c2.declare("我们没有核武器,也不怕侵略");
    }

结果显示:

中介者模式的优缺点

上述代码中,虽然确实减少了ConcreteColleague类之间的耦合,但这又使的ConcreteMediator类的职责太多了,如果他出了问题,则整个系统都会有问题了。

所以 中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了'多对多'交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是否合理。

中介者模式的优点首先是Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator类, 比如任何国家的改变不会影响到其他国家,而只是与安理会发生变化。其次由于把对象如何协作进行了抽象,将中介作为一个独立地概念并将其封装在一个对象汇总,这样关注的对象就从对象各自本身的行为转移到他们之间的交互上来,也就是站在一个更宏观的角度去看待系统。 比如巴以冲突,本来只算得上是国与国之间的矛盾,因此各自的看法可能都比较狭隘,但站在联合国安理会的角度,就可以从全球化、也更客观的角度来看待这个问题。

中介者模式的缺点是由于ConcreteMediator控制了集中化,于是就把交互复杂性变为中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。

中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。

总结

以上就是本文全部内容,本文主要向大家介绍了设计模式中的中介者模式,以联合国安理会调节各国矛盾为例,引出中介者模式代码,最后撰写联合国实例代码。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!

相关推荐
努力努力再努力wz2 小时前
【C++进阶系列】:位图和布隆过滤器(附模拟实现的源码)
java·linux·运维·开发语言·数据结构·c++
Yeats_Liao2 小时前
Java网络编程(三):NIO核心组件Channel通道详解
java·网络·nio
Yeats_Liao2 小时前
Java网络编程(六):NIO vs BIO性能对比与场景选择
java·网络·nio
Akshsjsjenjd3 小时前
Tomcat 简介与 Linux 环境部署
java·linux·tomcat
qq_569384123 小时前
Jenkins(速通版)
java·kubernetes·jenkins
青云交4 小时前
Java 大视界 -- Java 大数据在智能教育学习效果评估与教学质量改进中的深度应用(414)
java·flink 实时计算·java 大数据·智能教育·学习效果评估·教学质量改进·spark 离线分析
青草地溪水旁4 小时前
设计模式(C++)详解——代理模式 (Proxy Pattern)(1)
c++·设计模式·代理模式
Charles豪4 小时前
MR、AR、VR:技术浪潮下安卓应用的未来走向
android·java·人工智能·xr·mr
TeleostNaCl4 小时前
SMBJ 简单使用指南 实现在 Java/Android 程序中访问 SMB 服务器
android·java·运维·服务器·经验分享·kotlin