设计模式:中介者模式 Mediator

目录


前言

中介者是一种行为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。


问题

假如你有一个创建和修改客户资料的对话框, 它由各种控件组成, 例如 文本框(TextField)、复选框(Checkbox) 和 按钮(Button)等。

某些表单元素可能会直接进行互动。 例如, 选中"我有一只狗"复选框后可能会显示一个隐藏文本框用于输入狗狗的名字。 另一个例子是提交按钮必须在保存数据前校验所有输入内容。

如果直接在表单元素代码中实现业务逻辑, 你将很难在程序其他表单中复用这些元素类。 例如, 由于复选框类与狗狗的文本框相耦合, 所以将无法在其他表单中使用它。 你要么使用渲染资料表单时用到的所有类,要么一个都不用。

解决方案

中介者模式建议你停止组件之间的直接交流并使其相互独立。这些组件必须调用特殊的中介者对象, 通过中介者对象重定向调用行为,以间接的方式进行合作。最终,组件仅依赖于一个中介者类,无需与多个其他组件相耦合。

在资料编辑表单的例子中, 对话框(Dialog) 类本身将作为中介者, 其很可能已知自己所有的子元素, 因此你甚至无需在该类中引入新的依赖关系。

绝大部分重要的修改都在实际表单元素中进行。 让我们想想提交按钮。之前,当用户点击按钮后,它必须对所有表单元素数值进行校验。 而现在它的唯一工作是将点击事件通知给对话框。 收到通知后, 对话框可以自行校验数值或将任务委派给各元素。 这样一来, 按钮不再与多个表单元素相关联,而仅依赖于对话框类。

你还可以为所有类型的对话框抽取通用接口, 进一步削弱其依赖性。 接口中将声明一个所有表单元素都能使用的通知方法, 可用于将元素中发生的事件通知给对话框。 这样一来,所有实现了该接口的对话框都能使用这个提交按钮了。

采用这种方式, 中介者模式让你能在单个中介者对象中封装多个对象间的复杂关系网。 类所拥有的依赖关系越少, 就越易于修改、扩展或复用。

结构

代码

cpp 复制代码
#include <iostream>
#include <string>
#include <memory>
#include <map>
using namespace std;

class AbstractComponent{
public:
    virtual void operation()=0;
    virtual ~AbstractComponent(){}
};

class AbstractMediator{
public:
    virtual void notify(const string& sender)=0;
    virtual void addComponent(const string& name,shared_ptr<AbstractComponent> component)=0;
    virtual ~AbstractMediator(){}
};
class Dialog:public AbstractMediator{
public:
    void notify(const string& sender) override {
        if (sender == "button") {
            // 当按钮被触发时,协调复选框也执行操作
            cout << "中介者:按钮被按下,触发复选框操作" << endl;
            if (m_component.find("checkbox") != m_component.end()) {
                m_component["checkbox"]->operation();
            }
        } else if (sender == "checkbox") {
            cout<<"end"<<endl;
        }
    }
    void addComponent(const string& name,shared_ptr<AbstractComponent> component){
        m_component.insert(make_pair(name,component));
    }
private:
    map<string,shared_ptr<AbstractComponent>> m_component;
};

class Button:public AbstractComponent{
public:
    Button(shared_ptr<AbstractMediator> mediator){m=mediator;}
    void operation() override {
        cout << "按钮被按下" << endl;
        // 自身状态变化后,通过中介者通知其他组件
        m->notify("button"); 
    }
private:
    shared_ptr<AbstractMediator> m;
};
class Checkbox:public AbstractComponent{
public:
    Checkbox(shared_ptr<AbstractMediator> mediator){m=mediator;}
    void operation() override{
        cout << "调用复选框" << endl;
        // 自身状态变化后,通过中介者通知其他组件
        m->notify("checkbox"); 
    }
private:
    shared_ptr<AbstractMediator> m;
};

int main(){
    auto dialog=make_shared<Dialog>();
    auto button=make_shared<Button>(dialog);
    auto checkbox=make_shared<Checkbox>(dialog);

    dialog->addComponent("button",button);
    dialog->addComponent("checkbox",checkbox);
    
    button->operation();
    cout<<"----------------"<<endl;
    checkbox->operation();

    return 0;
}
相关推荐
qqxhb11 小时前
26|Agent 设计模式:ReAct、Plan-and-Solve 与反射
设计模式·react模式·plan-and-solve·reflection模式
hssfscv11 小时前
软件设计师下午题六——Java的各种设计模式
java·算法·设计模式
zhaoshuzhaoshu14 小时前
设计模式之创建型设计模式详细解析(含示例)
单例模式·设计模式·架构
倚楼盼风雨15 小时前
浅析设计模式-23种设计模式剖析
设计模式
Momentary_SixthSense2 天前
设计模式之工厂模式
java·开发语言·设计模式
Java码农也是农2 天前
Multi-Agent 系统设计模式
设计模式·agent·multi-agent
sg_knight2 天前
设计模式实战:状态模式(State)
python·ui·设计模式·状态模式·state
workflower2 天前
深度学习是通用型人工智能的基础
人工智能·深度学习·设计模式·软件工程·软件构建·制造
Meme Buoy2 天前
11.3设计模式-新
设计模式
cmpxr_2 天前
【单片机】常用设计模式
单片机·嵌入式硬件·设计模式