您现在的位置是:首页 >学无止境 >设计模式-中介者模式网站首页学无止境

设计模式-中介者模式

Evanpatchouli℃ 2024-10-25 12:01:04
简介设计模式-中介者模式

中介者模式

中介者模式,又称仲裁者模式,用于调整多个对象之间的关系。

角色

  • 抽象仲裁者(Mediator)

定义接口,用于各同事间的通信。

  • 具体仲裁者(ConcreteMediator)

维持了对各个同事对象的引用,通过协调各个同事对象来实现协作行为。

  • 抽象同事(Colleague)

定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现。

  • 具体同事类(ConcreteColleague)

维持了一个对抽象中介者类的引用,通过中介者来间接完成与其他同事类的通信。

案例

登录框

登录框有两个控件:输入框和登录按钮。仅当输入有效内容(非空)后,登录按钮才有效,并且登陆后输入框自动清空。

Colleague: 抽象同事

public interface Colleague {
    public void setMediator(Mediator mediator);  // 绑定老大
    public void setColleagueEnabled(boolean enabled);  // 设置禁用&可用
}

InputBox: 具体同事:输入框

public class InputBox implements Colleague{
    private Mediator mediator;
    private String content;
    private boolean enabled;

    public InputBox() {
        this.enabled = true;
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    public void setContent(String content) {
        if (this.enabled){
            System.out.printf("输入账号信息: %s
", content);
            this.content = content.trim();
            // 告诉仲裁者自己变了
            this.mediator.colleagueChanged(this);
        }
    }

    public void clear() {
        this.content = "";
        this.mediator.colleagueChanged(this);
    }

    public String getContent() {
        return this.content;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

LoginBtn: 具体同事:登录按钮

public class LoginBtn implements Colleague{
    private Mediator mediator;
    private boolean enabled;

    public LoginBtn() {
        this.enabled = false;
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public void click(){
        if (enabled==true){
            System.out.println("成功登录");
            this.mediator.colleagueChanged(this);
        } else {
            System.out.println("登录禁用");
        }
    }
}

Mediator: 抽象仲裁者

public interface Mediator {
    public void colleagueChanged(Colleague colleague);
}

ConcreteMediator: 具体仲裁者

public class ConcreteMediator implements Mediator{
    private InputBox inputBox;
    private LoginBtn loginBtn;

    public ConcreteMediator setInputBox(InputBox inputBox) {
        this.inputBox = inputBox;
        inputBox.setMediator(this);
        return this;
    }

    public ConcreteMediator setLoginBtn(LoginBtn loginBtn) {
        this.loginBtn = loginBtn;
        loginBtn.setMediator(this);
        return this;
    }

    @Override
    public void colleagueChanged(Colleague colleague) {
        if (colleague.equals(inputBox)){
            // 判断有内容没
            if (inputBox.getContent().length()==0){
                this.loginBtn.setColleagueEnabled(false);
            } else {
                this.loginBtn.setColleagueEnabled(true);
            }
        }
        if (colleague.equals(loginBtn)){
            inputBox.ckear(); //设置登录后清空
        }
    }
}

Main:

public class Main {
    public static void main(String[] args) {
        InputBox inputBox = new InputBox();
        LoginBtn loginBtn = new LoginBtn();

        ConcreteMediator mediator = new ConcreteMediator()
            .setInputBox(inputBox)
            .setLoginBtn(loginBtn);

        loginBtn.click();
        inputBox.setContent("root");
        loginBtn.click();
        loginBtn.click();
    }
}

Output:

登录禁用
输入账号信息: root
成功登录
登录禁用

中介者模式的优缺点

优点:

  1. 简化了对象之间的交互
  2. 将各同事对象解耦,可以独立地改变和复用每个同事和中介者,增加新的中介和同事很方便,符合开闭原则。
  3. 可以减少大量同事子类的生成,改变同事行为只需要生成新的中介者子类即可。

缺点:

  1. 具体中介者子类中包含了大量的同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

应用场景

  • 系统中对象之间存在复杂的引用关系 => 系统结构混乱且难以理解
  • 一个对象由于引用了其他很多对象并且直接和这些对象通信 => 难以复用该对象
  • 想要通过一个中间类来封装多个类的行为又不想生成太多子类 => 引入中介者即可实现
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。