【设计模式】中介者

中介者,说白了跟市面上黑中介类似。当然这个中介,开发者是可以控制其行为的。也是在一定的信任关系上建立的。

该模式要解决的问题是,一堆对象之间交叉耦合问题。

网上看过群聊的例子。如果没有任何一个平台,多人之间的会话会是什么样的呢?不举多人,就三个吧A想把一句话说给BC,那么他首先要知道B和C在哪儿,然后分别告诉对方,自己想说的事情。如果再加一个人呢?

问题很明显,此时各种群聊工具应运而生。我写了个简单的demo:

/***************************************************************************
 * 
 * Copyright (c) 2013 itegel.com, Inc. All Rights Reserved
 * 
 **************************************************************************/
 
/**
 * @file test_mediator.cpp
 * @author itegel
 * @date 2013/06/05 17:00:07
 * @brief 群聊的例子
 *  
 **/
#include <string>
#include <vector>
#include <iostream>
#include <time.h>
#include <sstream>
using namespace std;

class Mediator;
//抽象colleague
class Colleague{
    public:
        Colleague(string & name, Mediator * media):_name(name){
            _mediator = media;
        }
        void SetName(string & name){
            _name = name;
        }
        string GetName(){
            return _name;
        }
        
        void SetContent(string content){
            _content = content;
        }
        string GetContent(){
            return _content;
        }

        virtual void talk(){
            cout<<this->GetName()<<" saied:"<<this->GetContent()<<endl;
        }
        Mediator * GetMediator(){
            return _mediator;
        }

    protected:
        string _name;
        string _content;
        Mediator * _mediator;
};

class Mediator{
    public:
        Mediator(){
            _history = "";
        }
        void AddColleague(Colleague * clg){
            _colleagues.push_back(clg);
        }
        virtual void Notify(){
            for(vector<Colleague *>::iterator iter = _colleagues.begin(); iter != _colleagues.end(); iter++){
                (*iter)->talk();
            }
        }

        void AppendHistory(string new_content){
            time_t t = time(NULL);
            struct tm* ct = localtime(&t);
            ostringstream oss;
            oss<<ct->tm_mon + 1<<"-"<<ct->tm_mday<<" "<<ct->tm_hour<<":"<<ct->tm_min<<":"<<ct->tm_sec<<" ";
            oss<<new_content<<"\n";
            _history += oss.str();
        }

        string GetHistory(){
            return _history;
        }
    protected:
        vector<Colleague *> _colleagues;
        string _history;
};

class ColleagueA : public Colleague{
    public:
        ColleagueA(string name, Mediator * media):Colleague(name, media){
        }
        ~ColleagueA(){}
        
        virtual void talk(){
            cout<<this->GetName()<<" saied:"<<this->GetContent()<<endl;
            _mediator->AppendHistory(this->GetName()+":"+this->GetContent());
        }
};

class ColleagueB : public Colleague{
    public:
        ColleagueB(string name, Mediator * media):Colleague(name, media){
        }
        ~ColleagueB(){}
        virtual void talk(){
            cout<<this->GetName()<<" saied:"<<this->GetContent()<<endl;
            _mediator->AppendHistory(this->GetName()+":"+this->GetContent());
        }
};

class Hi : public Mediator{
    public:
        Hi(){}
        ~Hi(){}
};



int main(){
    Hi hi;
    ColleagueA * A1 = new ColleagueA("A1", &hi);    
    ColleagueB * B1 = new ColleagueB("B1", &hi);    
    ColleagueB * B2 = new ColleagueB("B2", &hi);    
    hi.AddColleague(A1);
    hi.AddColleague(B1);
    hi.AddColleague(B2);

    A1->SetContent("I am hungry!");
    B1->SetContent("I am hungry too!");
    B2->SetContent("Let's go out and have sth. to eat!");
    hi.Notify();

    sleep(1);

    A1->SetContent("田老师?");
    B1->SetContent("米线吧?");
    B2->SetContent("有会,还是食堂吧!");
    hi.Notify();

    sleep(1);
    cout<<endl<<A1->GetName()<<" 查看聊天记录:"<<endl;
    cout<<A1->GetMediator()->GetHistory()<<endl;;
    return 0;
}

执行结果:

A1 saied:I am hungry!
B1 saied:I am hungry too!
B2 saied:Let's go out and have sth. to eat!
A1 saied:田老师?
B1 saied:米线吧?
B2 saied:有会,还是食堂吧!

A1 查看聊天记录:
6-5 19:34:59 A1:I am hungry!
6-5 19:34:59 B1:I am hungry too!
6-5 19:34:59 B2:Let's go out and have sth. to eat!
6-5 19:35:0 A1:田老师?
6-5 19:35:0 B1:米线吧?
6-5 19:35:0 B2:有会,还是食堂吧!


引入mediator之后,其实 每个对象不用感知有多少个其他对象(当然也可以通过一些接口从中介者那里获取),只需要把自己该干的干好,需要跟别人协调的,告诉中介者就好,中介者负责把相应的任务分发出去。这样多个对象之间只与mediator耦合,将N*M的关系减少为了N*1的关系。

中介者实际实现可以有很多种,要看具体应用。

用中介者的坏处估计也是跟黑中介类似,比如租房,实际上我只需要跟房东打交道就好。但是因为中介的介入,我同样的接口(比如电话号码)可能还得暴露给中介者!


<think>好的,我现在需要回答用户关于中介者设计模式的问题,包括概念、实现、使用场景、UML图和示例代码。首先,我得回顾一下中介者模式的基本概念。中介者模式属于行为型设计模式,主要用于减少多个对象之间的直接通信,通过引入一个中介者来集中处理交互。这样能降低对象之间的耦合度。 接下来是概念部分。根据引用[1],中介者模式的主要组成成分包括中介者接口、具体中介者、同事类等。需要明确说明中介者模式的定义,可能还需要引用其他资料来补充,比如引用[3]提到它适用于处理多个对象的复杂交互,中介者对象的设计需要谨慎,避免过于复杂。 然后是实现步骤。引用[1]详细列出了构建步骤:创建中介者接口、同事类、具体同事类、具体中介者,最后是客户端使用。需要分步骤解释,每个部分的作用和实现方法。例如,同事类需要持有中介者的引用,通过中介者来通信,而不是直接相互调用。 使用场景部分,引用[3]指出当多个对象之间存在复杂交互时适用,特别是在需要集中控制交互的情况下。比如GUI组件之间的通信或者聊天室中的用户消息传递。需要结合这些例子具体说明。 UML图部分,引用[1]和[4]可能有相关的类图结构。需要描述各个类之间的关系,比如中介者接口与具体中介者,同事类与用户类之间的关系。引用[4]提到User类持有中介者的引用,并定义了发送和接收消息的方法,这应该在UML中体现出来。 示例代码方面,引用[1]和[4]可能有代码示例。需要提供一个简化的代码,比如聊天室的例子,用户通过中介者发送消息。代码结构应包括中介者接口、具体中介者、同事类(用户),以及他们之间的交互逻辑。注意代码要符合用户指定的格式,比如Python,但根据引用中的例子,可能需要调整语言,但用户问题中的示例是Python,所以可能用Python代码更合适。 还需要考虑用户提到的引用标识,在回答中适当添加。比如在解释应用场景时引用[3],在UML图部分引用[1]或[4]。 最后,生成相关问题,参考用户提供的示例中的问题结构,可能涉及优缺点、与其他模式的区别、实际应用案例等。需要确保问题符合用户提供的引用内容,比如引用[2]提到23种设计模式,可能相关问题可以涉及与其他行为型模式的比较。 现在需要整合这些信息,确保各部分内容准确,引用正确,结构清晰。同时注意用户要求的中文回答,LaTeX格式的正确使用,行内公式用$...$,独立公式用$$...$$。不过当前问题可能不需要数学公式,但如果有相关部分需要展示公式的话,比如算法步骤中的计算,但中介者模式可能不涉及数学表达式,所以这部分可能不需要。但需要检查是否有需要的地方,确保符合格式要求。 最后,代码部分需要用正确的语法,用户示例中使用Python,所以示例代码可能用Python,但引用中的例子可能用Java或C++,需要统一。根据用户示例中的代码格式,使用Python更合适,所以需要调整示例代码为Python,同时确保正确性。</think>### 中介者设计模式详解 #### 1. **概念** 中介者模式(Mediator Pattern)是一种**行为型设计模式**,旨在通过引入一个**中介者对象**来封装一组对象之间的交互,从而减少对象间的直接耦合。所有对象通过中介者通信,而非直接相互引用,使得系统更易于维护和扩展[^3]。 #### 2. **实现步骤** 1. **定义中介者接口**:声明协调对象间交互的方法。 2. **创建同事类**(Colleague):定义需要交互的对象的基类,持有中介者的引用。 3. **实现具体同事类**:继承同事类,实现具体业务逻辑,通过中介者与其他对象通信。 4. **实现具体中介者**:维护同事对象的引用,并协调其交互。 5. **客户端使用**:创建中介者和同事对象,并将同事注册到中介者中[^1][^4]。 #### 3. **UML类图** ```plaintext +----------------+ +----------------+ | Colleague |<-------| Mediator | +----------------+ +----------------+ | - mediator | | + notify() | +----------------+ +----------------+ ▲ ▲ | | +----------------+ +----------------+ | ConcreteColleague | | ConcreteMediator| +----------------+ +----------------+ | + send() | | + notify() | | + receive() | +----------------+ +----------------+ ``` - **解析**: - `Colleague`(同事类)通过`Mediator`接口与中介者交互。 - `ConcreteMediator`(具体中介者)实现协调逻辑,管理同事对象间的调用。 #### 4. **示例代码(Python)** ```python from abc import ABC, abstractmethod # 中介者接口 class Mediator(ABC): @abstractmethod def notify(self, sender, event): pass # 同事基类 class Colleague(ABC): def __init__(self, mediator): self.mediator = mediator # 具体同事类:用户 class User(Colleague): def send_message(self, message): print(f"用户发送消息:{message}") self.mediator.notify(self, message) def receive_message(self, message): print(f"用户收到消息:{message}") # 具体中介者:聊天室 class ChatRoomMediator(Mediator): def __init__(self): self.users = [] def add_user(self, user): self.users.append(user) def notify(self, sender, event): for user in self.users: if user != sender: user.receive_message(event) # 客户端使用 mediator = ChatRoomMediator() user1 = User(mediator) user2 = User(mediator) mediator.add_user(user1) mediator.add_user(user2) user1.send_message("你好!") # user2会收到消息 ``` #### 5. **使用场景** - **对象间交互复杂**:如GUI组件间的联动、聊天室消息传递。 - **需要集中控制逻辑**:例如订单系统中支付、库存、物流的协调[^4]。 #### 6. **优缺点** - **优点**: - 减少对象间的直接依赖,提高可维护性。 - 简化多对多通信为中介者的一对多交互。 - **缺点**: - 中介者可能成为“上帝对象”,逻辑过于复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值