侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 285 篇文章
  • 累计创建 125 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

JAVA设计模式之中介者模式

孔子说JAVA
2019-12-12 / 0 评论 / 0 点赞 / 203 阅读 / 6,236 字 / 正在检测是否收录...

1、中介者模式(Mediator)的定义

定义一个对象来封装一系列对象的交互,中介者模式使各个对象之间不需要相互引用,从而使得其松耦合,而且用户可以独立地改变他们之间的交互。(当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些对象之间的相互作用。从而保证这些相互作用可以彼此独立地变化。)

下图右边是使用中介者模式的示例图。没有使用中介者之前,对象间互相依赖互相调用,错综复杂,盘根错节,当加入中介者后,对象间的关系一目了然,清晰明了。由中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

image-1649381489716

核心:

  1. 如果一个对象中对象之间的联系呈现为网状结构,对象之间存在大量多对多的关系,将导致关系极其复杂,这些对象被称为“同事对象”.
  2. 我们可以引入一个中介者对象,使各个同事对象只跟中介者对象打交道,将复杂的网络结构化解为星形结构。

2、模式(Mediator)优缺点

中介者模式是一种行为型设计模式,其主要优缺点如下:

优点:

  1. 使用中介者模式可以把对个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合。
  2. 中介者模式可以将原先多对多的同事对象关系变成中介者对象一对多同事对象的关系,这样会让对象之间的关系更容易理解、实现和扩展,将原本难以理解的网状结构换成相对接单的星状结构。
  3. 同事对象之间的交互都被封装到中介者对象里面集中管理,集中了控制交互。当交互发生改变时,着重修改的是中介者对象。当需要扩展中介者对象时,其他同事对象不需要做修改。(可以独立地改变和复用各个同事类和中介者。)
  4. 可以减少子类的生成。

缺点:

  1. 过度集中化,这是中介者模式潜在的缺点。如果同事对象多了,交互也复杂了。那么这些交互全部集中到中介者对象中(在具体中介中包含了大量的同事类之间的交互细节),会导致中介者对象十分臃肿(非常复杂),难以管理和维护。

3、模式(Mediator)适用环境

  1. 系统中对象之间存在复杂的引用关系,系统结构混乱难以理解。
  2. 一个对象由于引用了其他很多对象并且直接和这些对象进行通信,导致难以复用该对象。
  3. 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

4、模式(Mediator)的结构

image-1649381645763

中介者模式所涉及到的角色有:

  • 抽象中介者角色(Mediator) :定义一个接口用于与各同事对象之间进行通信,其中主要方法是一个(或多个)事件方法。
  • 具体中介者角色(ConcreteMediator) :实现抽象中介者中所声明的事件方法。具体中介者维持了对各个具体同事类对象的引用,并负责具体的协调各个同事对象的交互关系。
  • 抽象同事类角色(Colleague) :定义各个同事类对象共有的方法,并声明了一些抽象方法供子类实现,同时他维持了一个对抽象中介者类的引用,其子类可以通过该引用进行通讯。同事对象只知道中介者,而不知道其余的同事对象。
  • 具体同事类角色(ConcreteColleague) :所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者会负责与其他的同时交互。

5、模式(Mediator)的应用实例

5.1 应用实例一

抽象的同事类:

public abstract class Colleague {
 
    private Mediator mediator;
 
    private String name;
 
    Colleague(String name,Mediator mediator){
        this.name  =name;
        this.mediator = mediator;
    }
 
    // getter/setter方法
 
    // 得到其他同事发来的信息
    public abstract void getMessage(String message,String messageFormName);
 
    // 与其他同事通信
    public abstract void contactColleague(String message,String ... toColleagueName);
 
}

具体的同事:

public class ColleagueImpl extends Colleague {
 
    ColleagueImpl(String name, Mediator mediator) {
        super(name, mediator);
    }
 
    @Override
    public void getMessage(String message,String messageFormName) {
        System.out.println("我" + this.getName() + " 被" + messageFormName + " 联系了, " + "信息为:" + message );
    }
 
    @Override
    public void contactColleague(String message,String ... toColleagueNames) {
        System.out.print("我 " + this.getName() + " 向 ");
        for (String toColleagueName : toColleagueNames){
            System.out.print(toColleagueName + ",");
        }
        System.out.println(" 发 " + message + " 信息");
        this.getMediator().contact(message,this, toColleagueNames);
    }
}

抽象的中介:

/**
 * 抽象的中介者
 */
public interface Mediator {
 
    /**
     * 中介者来使各同事之间的联系
     * @param content 交流内容
     * @param toColleagueNames 被联系者的名字
     */
    void contact(String content,Colleague colleague,String ... toColleagueNames);
 
    /**
     * 添加同事
     * @param colleague 被添加的同事
     */
    void addColleague(Colleague colleague);
}

具体的中介:

public class MediatorImpl implements Mediator {
 
    // 维护并知道所有同事。
    private Map<String,Colleague> colleagueMap = new HashMap<>();
 
 
    @Override
    public void contact(String message,Colleague colleagueForm, String... toColleagueNames) {
        for (String name : toColleagueNames){
            Colleague colleague = colleagueMap.get(name);
            colleague.getMessage(message,colleagueForm.getName());
        }
    }
 
    @Override
    public void addColleague(Colleague colleague) {
        this.colleagueMap.put(colleague.getName(),colleague);
    }
}

测试代码:

public class MediatorTest {
    public static void main(String[] args) {
        Mediator mediator = new MediatorImpl();
 
        Colleague colleagueA = new ColleagueImpl("小花",mediator);
        Colleague colleagueB = new ColleagueImpl("小明",mediator);
        Colleague colleagueC = new ColleagueImpl("小绿",mediator);
        Colleague colleagueD = new ColleagueImpl("小蓝",mediator);
 
        mediator.addColleague(colleagueA);
        mediator.addColleague(colleagueB);
        mediator.addColleague(colleagueC);
        mediator.addColleague(colleagueD);
 
        colleagueA.contactColleague("大家好",colleagueB.getName(),colleagueC.getName(),colleagueD.getName());
    }
}

测试结果:

我 小花 向 小明,小绿,小蓝, 发 大家好 信息
我小明 被小花 联系了, 信息为:大家好
我小绿 被小花 联系了, 信息为:大家好
我小蓝 被小花 联系了, 信息为:大家好

5.2 应用实例二

定义一个中介者接口及学委的接口:

//中介者接口类
public interface Mediator {
    //注册委员
    void register(String lname,ClassLeader c);
    //班长根据委员名字获得通知请求
    void command(String lname);
    
}

//班干部接口
public interface ClassLeader {
    //本职工作
    void job();
    //向班长提出请求
    void sendRequest();
}

具体学委角色:

//生活委员
public class LifeLeader implements ClassLeader {
    //持有对班长大人的引用
    private Mediator media;

    public LifeLeader(Mediator media) {
        super();
        this.media = media;
        media.register("LifeLeader", this);
    }

    @Override
    public void job() {
        System.out.println("生活委员->小张最近生活作风有点问题,需要我的帮助!");
    }

    @Override
    public void sendRequest() {
        System.out.println("生活委员->小张是不是有什么精神负担,班长大人去叫心理委员去看看什么情况吧!");
        media.command("phycologic");
    }
}

//心理委员
public class PhychologicalLeader implements ClassLeader {
    //持有对班长大人的引用
    private Mediator media;
    public PhychologicalLeader(Mediator media) {
        super();
        this.media = media;
        media.register("phycologic", this);
    }

    @Override
    public void job() {
        System.out.println("心理委员->小张最近心情好像不太好,需要我的帮助!");
    }

    @Override
    public void sendRequest() {
        System.out.println("心理委员->小张是不是生活上有什么问题,班长大人叫生活委员多关注一下吧!");
        media.command("LifeLeader");
    }
}

//学习委员
public class StudyLeader implements ClassLeader {
    //持有对班长大人的引用
    private Mediator media;

    public StudyLeader(Mediator media) {
        super();
        this.media = media;
        media.register("StudyLeader", this);
    }

    @Override
    public void job() {
        System.out.println("学习委员->小张最近成绩突飞猛进,果然在我的英明指导下没有人能不起飞!");
    }

    @Override
    public void sendRequest() {
        System.out.println("学习委员->小张为了成绩居然还搞抄袭,怎么变成这样了?班长大人快去通知生活委员和心理委员看看情况!");
        media.command("LifeLeader");
        media.command("phycologic");
    }
}

具体中介者角色:

//班长
public class ClassMonitor implements Mediator {
    //利用map集合存放学委的相关属性
    private Map<String,ClassLeader> map=new HashMap<String,ClassLeader>();
    
    //将对应名称的学委对象进行注册
    @Override
    public void register(String lname, ClassLeader c) {
       map.put(lname, c);
    }
    //班长大人获取来自指定学委的请求通知
    @Override
    public void command(String lname) {
        map.get(lname).job();
    }
}

客户端类:

public class Client {
    public static void main(String[] args) {
        
        Mediator m=new ClassMonitor();
        ClassLeader life=new LifeLeader(m);
        ClassLeader study=new StudyLeader(m);
        ClassLeader phycho=new PhychologicalLeader(m);
        //当前委员发送请求给班长然后通过班长与其他委员通信
        System.out.println("------生活委员->班长->心理委员------");
        life.sendRequest();
        System.out.println("--------------------------");
        System.out.println("------学习委员->班长->心理委员,生活委员------");
        study.sendRequest();
        System.out.println("--------------------------");
        System.out.println("------心理委员->班长->生活委员------");
        phycho.sendRequest();
        System.out.println("--------------------------");
    }
}

效果截图:

image-1649381909199

0

评论区