浅谈设计模式 - 中介者模式(十六)

简介: 浅谈设计模式 - 中介者模式(十六)

前言


中介者模式是一种行为设计模式, 他的目的和门面模式类似,他负责的是将所有的底层交互细节隐藏,提供统一的对外接口供外部调用。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。


优缺点:



优点: 1、将对象的交互模式由多对一变为一对一。 2、可以实现多个类之间的强耦合。 3、此设计模式十分符合迪米特原则。

迪米特法则(Law of Demeter)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话

**缺点:**中介者对象会逐渐庞大,如果组件过多会变得复杂难以维护。


使用场景


1、在系统内部的对象之间通信紊乱的时候,按照设计模式单一职责的原则,通常会使用三方对象负责“请求”的转发,而中介的作用就是再次之上一个扩展,可以实现多个类之间的互相通信变为一对一的通信模式。

2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

3、如果多个用户之间存在复杂的通信和耦合的情况时候,对外使用外观模式,对内则可以使用中介者模式。

**注意事项:**不应当在职责混乱的时候使用。


结构图



下面是中介者模式的结构图,这里构建了多个具体的实现对象,他们需要实现统一的通信就需要


网络异常,图片无法展示
|


和门面模式的对比


下面是门面模式的结构图,门面模式也叫做外观模式,可以看到和中介者的对象还有一定的相似性,外观提供,这两个模式的区别是外观主要提供对象的一致对外的接口,而中介模式实现的是让对象之间的通信由多对一变为一对一,我们简单的认为,中介者主要针对的对内多个复杂对象的统一,外观针对对外多个对象的方法统一。


网络异常,图片无法展示
|


实际案例


下面我们用一段简短的代码快速介绍一下这个设计模式的代码, 其实从上面结构图基本可以快速的写出模板代码,下面按照一个租房的案例进行快速的讲解:

首先是中介者的接口,中介者的接口需要由需要进行通信的子类实现,这里定义了租房的联络接口


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


用户类,内部嵌入了联络的对象,使得子类可以和任意对象进行通信


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


房东类,继承Person类的同时,实现自己的通信方法


public class HouseOwner extends Person{
    HouseOwner(String name, Mediator mediator) {
        super(name, mediator);
    }
    /**
     * @desc 与中介者联系
     * @param message
     * @return void
     */
    public void constact(String message){
        mediator.constact(message, this);
    }
    /**
     * @desc 获取信息
     * @param message
     * @return void
     */
    public void getMessage(String message){
        System.out.println("房主:" + name +",获得信息:" + message);
    }
}


下面是另一个Person类,也就是中介者的对象,负责和房东进行通信


public class Tenant extends Person{
    Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }
    /**
     * @desc 与中介者联系
     * @param message
     * @return void
     */
    public void constact(String message){
        mediator.constact(message, this);
    }
    /**
     * @desc 获取信息
     * @param message
     * @return void
     */
    public void getMessage(String message){
        System.out.println("租房者:" + name +",获得信息:" + message);
    }
}


下面是具体的中介对象,可以看到下面定义了房东的的信息以及租房者的对象,通过中介对象,我们实现了房东和房客之间的通信,让他们统一通过中介机构进行通信。


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;
    }
    public void constact(String message, Person person) {
        if(person == houseOwner){          //如果是房主,则租房者获得信息
            tenant.getMessage(message);
        }
        else{       //反正则是房主获得信息
            houseOwner.getMessage(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.constact("听说你那里有三室的房主出租.....");
        houseOwner.constact("是的!请问你需要租吗?");
    }
}


总结



  1. 由于中介者需要将多个对象的行为进行连接通信,虽然各个对象的改动会改变通信的细节,但是中介者的改动却会影响整体通信行为,这是一把双刃剑,既让对象的通信简化同时,也让复杂耦合到了一处。这时候可以结合策略或者工厂将中介的通信行为实现动态的扩展
  2. 在中介者模式中通过引用中介者对象,将系统中有关的对象所引用的其他对象数目减少到最少。
  3. 中介的行为类似一种对象的闭包和统一通信,中介者模式按照房东,中介,房客的理解可以快速的了解到这个结构
  4. 其实我们可以把MVC看作一种中介的变种,Service层起到了承接的作用。


写在最后



中介的行为经常在使用,但是使用中介者模式需要小心的考虑类的耦合和中介者类是否会变得复杂或者难以维护。

相关文章
|
6月前
|
设计模式 存储 Java
浅谈设计模式 - 备忘录模式(十五)
浅谈设计模式 - 备忘录模式(十五)
47 0
|
6月前
|
设计模式 前端开发
浅谈设计模式 - 中介者模式(十六)
浅谈设计模式 - 中介者模式(十六)
64 0
|
设计模式 C++
二十三种设计模式:状态模式
状态模式,就是把所有的状态抽象成一个个具体的类,然后继承一个抽象状态类,在每一个状态类内封装对应状态的行为,符合开放封闭原则,当增加新的状态或减少状态时,只需修改关联的类即可。很适合多分支行为方法的处理,这里的多分支,当然是状态比较多的情况下,如果只有小于4个状态,个人认为还是分支处理简单些。
58 0
|
设计模式
设计模式轻松学【十五】状态模式
在生活中,人的情绪往往都在变化,有高兴的时候和伤心的时候,不同的情绪有不同的行为,比如你开心的时候,会去大吃一顿,伤心的时候会出去唱K。外界也会影响我们的情绪,唱K之后你就变得开心了。 这个情绪的变化我们可以看成一个对象的状态变化,状态改变时会有不同的操作。对这种有状态的对象编程,传统的解决方案是:将这些所有可能发生的情况全都考虑到,然后使用 if-else 语句来做状态判断,再进行不同情况的处理。但当对象的状态很多时,程序会变得很复杂。这很像策略模式、但他们有着本质的区别。
87 0
设计模式轻松学【十五】状态模式
|
存储 设计模式 Java
设计模式轻松学【十九】享元模式
享指的是共享,String常量池、数据库连接池、线程池等都是享元模式的具体应用。
126 0
设计模式轻松学【十九】享元模式
|
设计模式
设计模式轻松学【十六】建造者模式
在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。
141 0
设计模式轻松学【十六】建造者模式
|
设计模式
设计模式轻松学【十四】外观模式
生活中我们去餐馆吃饭,我们需要被接待,点菜,后台厨师准备菜品,做菜,服务员传送到桌上面,开始吃饭,吃完结账等等操作。但这一连串的操作中有些操作是不需要被我们关注的,比如厨师怎么做菜,怎么上菜,我们只需要点菜,吃饭,结账,所以我们可以引入外观模式来隐藏这些无需关注的细节。
135 0
设计模式轻松学【十四】外观模式
|
设计模式 算法
二十三种设计模式之策略模式
二十三种设计模式之策略模式
147 0
|
设计模式 C#
设计模式(十五)之观察者模式
观察者模式(Observer Pattern)是设计模式中行为模式的一种,它解决了上述具有一对多依赖关系的对象的重用问题。此模式的参与者分为两大类,一类是被观察的目标,另一类是观察该目标的观察者们。 正因为该模式是基于“一对多”的关系,所以该模式一般是应用于由一个目标对象和N个观察者对象组成(当然也可以扩展为有多个目标对象,但我们现在只讨论前者)的场合。 当目标对象的状态发生改变或做出某种行为时,正在观察该目标对象的观察者们将自动地、连锁地作出相应的响应行为。
123 0
设计模式(十五)之观察者模式
|
设计模式
设计模式(十六)之抽象工厂模式
抽象工厂模式:提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类。
175 0
设计模式(十六)之抽象工厂模式