中介者模式 行为型模式之四

本文介绍了中介者模式,它是行为型模式,用于降低多个对象和类之间的通信复杂性。文中阐述了其意图、解决的问题、使用场景等,还列举了应用实例,如WTO、机场调度系统等,同时指出其优缺点,最后给出了示例代码和引用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.定义

        中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

2.介绍

意图:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

主要解决:对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。

何时使用:多个类相互耦合,形成了网状结构。

如何解决:将上述网状结构分离为星型结构。

关键代码:对象 Colleague 之间的通信封装到一个类中单独处理。

应用实例: 1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。 2、机场调度系统。 3、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

优点: 1、降低了类的复杂度,将一对多转化成了一对一。 2、各个类之间的解耦。 3、符合迪米特原则。

缺点:中介者会庞大,变得复杂难以维护。

使用场景: 1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。 2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

典型例子:电脑主板,电脑的CPU、内存、显卡等配件之间需要相互交互,通过主板即可。

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

3.示例代码

#include<iostream>
#include<map>
#include<ctime>
#include<sstream>
using namespace std;
class AbstractChatroom;
//抽象同事类
class Member {
protected:
    AbstractChatroom* chatroom;
    string name;
public:
    Member(string name) {
        this->name = name;
    }
    AbstractChatroom* getChatroom() {
        return chatroom;
    }
    void setChatroom(AbstractChatroom* chatroom) {
        this->chatroom = chatroom;
    }
    string getName() {
        return name;
    }
    void setName(string name) {
        this->name = name;
    }
    virtual void sendText(string to, string message) = 0;
    virtual void sendImage(string to, string image) = 0;
    void receiveText(string from, string message) {
        cout << from << "发送文本给" << this->name << ",内容为:" << message << endl;
    }
    void receiveImage(string from, string image) {
        cout << from << "发送图片给" << this->name << ",内容为:" << image << endl;
    }
};
string replace(string strSrc, const string& oldStr, const string& newStr, int count = -1)
{
    string strRet = strSrc;
    size_t pos = 0;
    int l_count = 0;
    if (-1 == count) //替换所有
        count = strRet.size();
    while ((pos = strRet.find(oldStr, pos)) != string::npos)
    {
        strRet.replace(pos, oldStr.size(), newStr);
        if (++l_count >= count) break;
        pos += newStr.size();
    }
    return strRet;
}
//抽象中介者类
class AbstractChatroom {
public:
    virtual void registers(Member* member) = 0;
    virtual void sendText(string from, string to, string message) = 0;
    virtual void sendImage(string from, string to, string image) = 0;
};
//具体中介者类
class ChatGroup : public AbstractChatroom {
private:
    map<string, Member*> members;
    map<string, Member*>::iterator iter;
public:
    void registers(Member* member) {
        iter = members.find(member->getName());
        if (iter == members.end()) {
            members.insert(map<string, Member*>::value_type(member->getName(), member));
            member->setChatroom(this);
        }
    }
    void sendText(string from, string to, string message) {
        Member* member = members.find(to)->second;
        string newMessage = message;
        newMessage = replace(message, "日", "*");
        member->receiveText(from, newMessage);
    }
    void sendImage(string from, string to, string image) {
        Member* member = members.find(to)->second;
        if (image.length() > 5) {
            cout << "图片太大,发送失败" << endl;
        }
        else {
            member->receiveImage(from, image);
        }
    }
};
//具体中介者类
class NewChat :public AbstractChatroom {
private:
    map<string, Member*> members;
    map<string, Member*>::iterator iter;
public:
    void registers(Member* member) {
        iter = members.find(member->getName());
        if (iter == members.end()) {
            members.insert(map<string, Member*>::value_type(member->getName(), member));
            member->setChatroom(this);
        }
    }
    void sendText(string from, string to, string message) {
        Member* member = members.find(to)->second;
        string newMessage = message;
        newMessage = replace(message, "日", "*");
        if (message.length() > 100) {
            cout << "发送的文字长度不得超过100个字符,发送失败" << endl;
        }
        else {
            member->receiveText(from, newMessage);
        }
    }
    void sendImage(string from, string to, string image) {
        Member* member = members.find(to)->second;
        if (image.length() > 20) {
            cout << "图片大小不得超过20M,发送失败" << endl;
        }
        else {
            member->receiveImage(from, image);
        }
    }
};
//具体同事类
class CommonMember :public Member {
protected:
    string name;
public:
    CommonMember(string name) :Member(name) {
        this->name = name;
    }
    void sendText(string to, string message) {
        cout << "普通会员发送消息:" << endl;
        chatroom->sendText(this->name, to, message);
    }

    void sendImage(string to, string image) {
        cout << "普通会员不能发送图片!" << endl;
    }
};
//具体同事类
class DiamondMember :public Member {
protected:
    string name;
public:
    DiamondMember(string name) :Member(name) {
        this->name = name;
    }
    void sendText(string to, string message) {
        cout << "钻石会员发送消息:" << endl;
        chatroom->sendText(name, to, message);
    }
    void sendImage(string to, string image) {
        cout << "钻石会员发送图片:" << endl;
        chatroom->sendImage(name, to, image);
    }
};
//具体同事类
class NewMember :public Member {
protected:
    string name;
public:
    NewMember(string name) :Member(name) {
        this->name = name;
    }
    void sendText(string to, string message) {
        time_t now = time(NULL);
        tm* t = localtime(&now);
        // 将信息输出到字符串流
        stringstream ss;
        stringstream ss2;
        ss << t->tm_year + 1900 << "." << t->tm_mon + 1 << "." <<
            t->tm_mday << ".." << t->tm_hour << "." << t->tm_min << "." << t->tm_sec;
        cout << "新会员发送消息:" << endl;
        chatroom->sendText(name, to, message + "  现在时间" + ss.str());
    }
    void sendImage(string to, string image) {
        cout << "会员发送图片:" << endl;
        chatroom->sendImage(name, to, image);
    }
};
//测试函数
int main() {
    AbstractChatroom* newChat = new NewChat();
    Member* member1, * member2, * member3, * member4;
    member1 = new DiamondMember("张三");
    member2 = new CommonMember("小李");
    member3 = new NewMember("小芳");
    member4 = new NewMember("小红");

    newChat->registers(member1);
    newChat->registers(member2);
    newChat->registers(member3);
    newChat->registers(member4);

    member1->sendText("小李", "小李,你好!");
    member2->sendText("张三", "张三,你好!");
    cout << "---------------------------------------------" << endl;
    member3->sendText("小红", "小红你好。");
    member3->sendText("小红", "你好小红!-----------------------------------------------------------------------------------------------------");
    member3->sendImage("小红", "哈哈.jpg");
    member4->sendText("小芳", "你好,小芳");
    member4->sendImage("小芳", "哈哈.jpg--------------------");
}

4.引用

1.中介者模式详解(作用优缺及应用场景实例) – mikechen

2.中介者模式 | 菜鸟教程 (runoob.com)

3.中介者模式——C++实现 - 戈瑾 - 博客园 (cnblogs.com)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值