JAVA设计模式之中介者模式详解-程序员宅基地

技术标签: java  中介者模式  设计模式  

中介者模式

1 中介者模式介绍

提到中介模式,有一个比较经典的例子就是航空管制。 为了让飞机在飞行的时候互不干扰,每架飞机都需要知道其他飞机每时每刻的位置,这就需要时刻跟其他飞机通信。飞机通信形成的通信网络就会无比复杂。这个时候,我们通过引 入“塔台”这样一个中介,让每架飞机只跟塔台来通信,发送自己的位置给塔台,由塔台来 负责每架飞机的航线调度。这样就大大简化了通信网络。

在这里插入图片描述

中介模式(mediator pattern)的定义: 定义一个单独的(中介)对象,来封装一组对象之间的交互,将这组对象之间的交互委派给予中介对象交互,来避免对象之间的交互.

中介者对象就是用于处理对象与对象之间的直接交互,封装了多个对象之间的交互细节。中介模式的设计跟中间层很像,通过引入中介这个中间层,将一组对象之间的交互关系从多对多的网状关系转换为一对多的星状关系.原来一个对象要跟N个对象交互,现在只需要跟一个中介对象交互,从而最小化对象之间的交互关系,降低代码的复杂度,提高代码的可读性和可维护性.

2 中介者模式原理

在这里插入图片描述

中介者模式包含以下主要角色:

  • 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。

  • 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。

  • 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

  • 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

3 中介者模式实现

代码示例

/**
 * 抽象中介者
 **/
public interface Mediator {
    

    void apply(String key);
}

/**
 * 具体中介者
 **/
public class MediatorImpl implements Mediator {
    

    @Override
    public void apply(String key) {
    
        System.out.println("最终中介者执行操作,key为: " + key);
    }
}

/**
 * 抽象同事类
 **/
public abstract class Colleague {
    

    private Mediator mediator;

    public Colleague(Mediator mediator) {
    
        this.mediator = mediator;
    }

    public Mediator getMediator() {
    
        return mediator;
    }

    public abstract void exec(String key);
}

/**
 * 具体同事类
 **/
public class ConcreteColleagueA extends Colleague {
    

    public ConcreteColleagueA(Mediator mediator) {
    
        super(mediator);
    }

    @Override
    public void exec(String key) {
    
        System.out.println("====在组件A中,通过中介者执行!");
        getMediator().apply(key);
    }
}

public class ConcreteColleagueB extends Colleague {
    

    public ConcreteColleagueB(Mediator mediator) {
    
        super(mediator);
    }

    @Override
    public void exec(String key) {
    
        System.out.println("====在组件B中,通过中介者执行!");
        getMediator().apply(key);
    }
}

public class Client {
    

    public static void main(String[] args) {
    

        //创建中介者
        MediatorImpl mediator = new MediatorImpl();

        //创建同事对象
        Colleague c1 = new ConcreteColleagueA(mediator);
        c1.exec("key-A");
        Colleague c2 = new ConcreteColleagueB(mediator);
        c2.exec("key-B");
    }
}


====在组件A,通过中介者执行!
最终中介者执行操作,key为: key-A
====在组件B,通过中介者执行!
最终中介者执行操作,key为: key-B

4 中介者模式应用实例

【例】租房

现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房屋中介充当租房者与房屋所有者之间的中介者。

/**
 * 抽象中介者
 **/
public abstract class Mediator {
    

    //申明一个联络方法
    public abstract void contact(String message,Person person);
}

/**
 * 抽象同事类
 **/
public abstract class Person {
    

    protected String name;

    protected Mediator mediator;

    public Person(String name, Mediator mediator) {
    
        this.name = name;
        this.mediator = mediator;
    }
}

/**
 * 中介机构
 **/
public class MediatorStructure extends Mediator {
    

    //中介要知晓房主和租房者的信息
    private HouseOwner houseOwner;
    private Tenant tenant;

    public HouseOwner getHouseOwner() {
    
        return houseOwner;
    }

    public void setHouseOwner(HouseOwner houseOwner) {
    
        this.houseOwner = houseOwner;
    }

    public Tenant getTenant() {
    
        return tenant;
    }

    public void setTenant(Tenant tenant) {
    
        this.tenant = tenant;
    }

    @Override
    public void contact(String message, Person person) {
    
        if(person == houseOwner){
      //如果是房主,则租房者获得信息
            tenant.getMessage(message);
        }else {
     //如果是租房者则获取房主信息
            houseOwner.getMessage(message);
        }
    }
}

/**
 * 具体同事类-房屋拥有者
 **/
public class HouseOwner extends Person{
    

    public HouseOwner(String name, Mediator mediator) {
    
        super(name, mediator);
    }

    //与中介者联系
    public void contact(String message){
    
        mediator.contact(message,this);
    }

    //获取信息
    public void getMessage(String message){
    
        System.out.println("房主" + name + "获取到的信息: " + message);
    }
}

/**
 * 具体同事类-承租人
 **/
public class Tenant extends Person{
    

    public Tenant(String name, Mediator mediator) {
    
        super(name, mediator);
    }

    //与中介者联系
    public void contact(String message){
    
        mediator.contact(message,this);
    }

    //获取信息
    public void getMessage(String message){
    
        System.out.println("租房者" + name + "获取到的信息: " + message);
    }
}

public class Client {
    

    public static void main(String[] args) {
    

        //一个房主 一个租房者 一个中介机构
        MediatorStructure mediator = new MediatorStructure();

        //房主和租房者只需要知道中介机构即可
        HouseOwner houseOwner = new HouseOwner("路飞", mediator);
        Tenant tenant = new Tenant("娜美", mediator);

        //中介收集房租和租房者信息
        mediator.setHouseOwner(houseOwner);
        mediator.setTenant(tenant);

        tenant.contact("需要一个两室一厅的房子,一家人住");
        houseOwner.contact("出租一套两室一厅带电梯,月租5000");
    }
}

5 中介者模式总结

  1. 中介者模式的优点
  • 中介者模式简化了对象之间的交互,他用中介者和同事的一对多代替了原来的同事之间的多对多的交互,一对多关系更好理解 易于维护和扩展,将原本难以理解的网状结构转换成习相对简单的星型结构.
  • 可以将各个同事就对象进行解耦.中介者有利于各个同事之间的松耦合,可以独立的改变或者复用每一个同事或者中介者,增加新的中介者类和新的同事类都比较方便,更符合开闭原则
  • 可以减少子类生成,中介者将原本分布与多个对象的行为集中在了一起,改变这些行为只需要生成新的中介者的子类即可,使得同事类可以被重用,无需直接对同事类进行扩展.
  1. 中介者模式的缺点
  • 在具体中介者类中包含了大量同事之间的交互细节,可能会导致中介者类变得非常的复杂,使得系统不好维护.
  1. 中介者模式使用场景
  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解.
  • 一个对象由于引用了其他的很多对象并且直接和这些对象进行通信,导致难以复用该对象.
  • 想要通过一个中间类来封装多个类中的行为,而又不想生成太多的子类,此时可以通过引用中介者类来实现,在中介者类中定义对象的交互的公共行为,如果需要改变行为则可以在增加新的中介类.
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jbjmh/article/details/136105641

智能推荐

iOS 上通过 802.11k、802.11r 和 802.11v 实现 Wi-Fi 网络漫游-程序员宅基地

文章浏览阅读848次。在 iOS 上通过 802.11k、802.11r 和 802.11v 实现 Wi-Fi 网络漫游了解 iOS 如何使用 Wi-Fi 网络标准提升客户端漫游性能。iOS 支持在企业级 Wi-Fi 网络上对客户端漫游进行优化。802.11 工作组标准 k、r 和 v 可让客户端在同一网络内更加顺畅地从一个接入点 (AP) 漫游到另一个接入点。802.11k通过创建优..._11v漫游流程 csdn

sig值怎么计算_T检验、sig.值-程序员宅基地

文章浏览阅读4.8k次。你的分析结果有T值,有sig值,说明你是在进行平均值的比较。也就是你在比较两组数据之间的平均值有没有差异。从具有t值来看,你是在进行T检验。T检验是平均值的比较方法。T检验分为三种方法:1.单一样本t检验(One-samplettest),是用来比较一组数据的平均值和一个数值有无差异。例如,你选取了5个人,测定了他们的身高,要看这五个人的身高平均值是否高于、低于还是等于1.70m,就需要用这个..._sig值计算公式

新手java五子棋完整代码判断落子落在线上_Java初学者,编写小游戏五子棋的问题?...-程序员宅基地

文章浏览阅读362次。首先你需要掌握GUI编程,事件处理,已经监听器,你就掌握Swing的知识就好了Swing框架,JFrame,JPanel,鼠标、键盘监听事件Java基础,面向对象,异常处理,集合,IO流网络编程,Socket通信线程知识,Java逻辑基础上述的技术点估计需要将JavaSE这块学完才能掌握,下面进入正题。这里呢,我把几个常见的小游戏列出来,如下图:象棋对战,带聊天五子棋对战,带聊天打字游戏对战音乐播..._五子棋程序判断落子位置

杭电2041 超级楼梯_超级楼梯 (杭电2041)比赛题目 题目统计 全部提交时间限制:c/c++ 1000ms,其他语言-程序员宅基地

文章浏览阅读322次,点赞6次,收藏8次。【代码】杭电2041 超级楼梯。_超级楼梯 (杭电2041)比赛题目 题目统计 全部提交时间限制:c/c++ 1000ms,其他语言

关于构建数据仓库的几个问题_从需求出发建设数仓会有什么问题-程序员宅基地

文章浏览阅读1.6k次。写在前面数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented)、集成的(Integrated)、相对稳定的(Non-Volatile)、反映历史变化(Time Variant)的数据集合,用于支持管理决策(Decision Making Support)。近年来,随着大数据的应用不断深入,构建企业级数据仓库成为了企业进行精细化运营的一种趋势。从管理者的视角来看,数据仓库是赋能业务并辅助决策的一种工具,从开发者的视角来看,数据仓库是一堆数据模型的集合。数仓开发是一个系_从需求出发建设数仓会有什么问题

手写B+树-程序员宅基地

文章浏览阅读3.2k次。插入关键字 40 ,按照第 2 种情况将结点分裂,并将关键字 37 上移到父结点,发现父结点 [15、37、44、59] 包含的关键字的个数大于 M ,所以将结点 [15、37、44、59] 分裂为两个结点 [15、37] 和结点 [44、59] ,并将关键字 37 上移到父结点中 [37、59、97] . 父结点包含关键字个数没有超过 M ,插入结束。比如插入关键字 12 ,插入关键字所在的结点的 [10,15] 包含两个关键字,小于 M ,则直接插入关键字 12。B+树插入删除时间复杂度为0(1)_手写b+树

随便推点

图解通信原理与案例分析-17:2G GPRS通用分组无线业务详解_2g slot-程序员宅基地

文章浏览阅读4.7k次。先占个空,以后再详细拆解主要关注与GSM的区别,特别是GRPS是如何通过增加信道和分组交换系统支持数据传输,如何通过新的调制解调技术,增加数据传输的速率的!1. GSM是全球移动通讯系统(Global System for Mobile Communications)的简称2. GPRS是通用分组无线业务(General Packet Radio Service)的简称3. GPRS是在GSM系统基础上发展起来的分组数据承载和传输业务。4. GPRS与GSM......_2g slot

【图像拼接】论文精读:Natural Image Stitching Using Depth Maps-程序员宅基地

文章浏览阅读10w+次。图像拼接系列相关论文精读Seam Carving for Content-Aware Image ResizingAs-Rigid-As-Possible Shape ManipulationAdaptive As-Natural-As-Possible Image StitchingShape-Preserving Half-Projective Warps for Image StitchingSeam-Driven Image StitchingParallax-tolerant Ima_natural image stitching using depth maps

【Java基础知识 11】java泛型方法的定义和使用-程序员宅基地

文章浏览阅读1.6w次,点赞131次,收藏52次。一、基本介绍Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。二、提出背景Java集合(Collection)中元素的类型是多种多样的。例如,有些集合中的元素是Byte类型的,而有些则可能是String类型的,等等。Java允许程序员构建一个元素类型为Object的Collection,其中的元素可以是任何类型在Java S._java基础

vue中使用echarts实现省市地图绘制,根据数据在地图上显示柱状图信息,增加涟漪特效动画效果_vue 市区地图+经纬度自定义显示弹窗详情-程序员宅基地

文章浏览阅读1.7k次,点赞26次,收藏14次。vue中使用echarts实现省市地图绘制,根据数据在地图上显示柱状图信息;增加涟漪特效动画。本文以吉林省地图为例,来实现吉林省市的地图的绘制。根据数据在地图上显示柱状图信息;增加涟漪特效动画。你也可以显示中国地图或其他身份地图。原理是一样的哦。主要是通过geo地理坐标系组件实现地图绘制。柱状图是利用3个样式(顶部椭圆、中部矩形、底部椭圆)层叠实现的。_vue 市区地图+经纬度自定义显示弹窗详情

网络安全等级保护2.0自查表 | 技术部分_网络安全等级保护自查表-程序员宅基地

文章浏览阅读1.2k次,点赞46次,收藏20次。网络安全等级保护2.0自查表 | 技术部分_网络安全等级保护自查表

已知一个iis漏洞可以让php解释任意的给定文件-程序员宅基地

文章浏览阅读64次。已知一个iis漏洞可以让php解释任意的给定文件。挑战:怎么执行任意命令?应用环境:防火墙配置不准许对外连接。要求:不能要求上传文件。总算看到一次答案了:http://www.inbreak.net/kxlzxtest/phpiis.txtC:\Windows\System32\LogFiles\w3svcXXXX让php解析当天访问日志,然后用get请求提交user agent为 User-Ag..._php iis 漏洞