【设计模式】之二十三种设计模式--中介者模式

中介者模式

Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.

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

通用类图

抽象中介类,定义统一的接口,用于各同事角色之间的通信

具体中介类,协调各同事角色实现写作行为,依赖于同事角色,继承抽象中介类

同事角色类,每个同事角色类都知道中介者角色,并通过中介者角色和其他同事通信

通用源码

//抽象中介类
class Mediator {
protected:
    //定义同事类
    ConcreteColleague1 c1;
    ConcreteColleague2 c2;
public:
    //通过set和get注入同事类
    ConcreteColleague1 getC1() {return c1;}
    void setC1(ConcreteColleague1& c) {c1 = c;}
    ConcreteColleague2 getC2() {return c2;}
    void setC2(ConcreteColleague2& c) {c2 = c;}
    //中介者模式的业务逻辑
    virtual void doSomething1() = 0;
    virtual void doSomething2() = 0;
};
//具体中介者类
class ConcreteMediator : public Mediator {
    virtual void doSomething1() {
        //调用同事类的方法
        c1.selfMethod1();
        c2.selfMethod2();
    }
    virtual void doSomething2() {
        c1.selfMethod1();
        c2.selfMethod2();
    }
};
//抽象同事类
class Colleague {
protected:
    Mediator mediator;
public:
    Colleague(Mediator m) { mediator = m;}
};
//具体同事类
class ConcreteColleague1 : public Colleague {
public:
    //构造函数传递中介者
    ConcreteColleague1(Mediator m) : Colleague(m) { }
    //自有方法self-method
    void selfMethod1() {
        //业务逻辑
    }
    //依赖方法 dep-method
    void depMethod1() {
        //业务逻辑
        //委托中介者处理
        mediator.doSomething1();
    }
};
class ConcreteColleague2 : public Colleague {
public:
    //构造函数传递中介者
    ConcreteColleague2(Mediator m) : Colleague(m) { }
    //自有方法self-method
    void selfMethod2() {
        //业务逻辑
    }
    //依赖方法 dep-method
    void depMethod2() {
        //业务逻辑
        //委托中介者处理
        mediator.doSomething2();
    }
};

优点

减少类间依赖,降低类间耦合

缺点

中介者会膨胀,且逻辑复杂

使用场景

适用于多个对象之间紧密耦合的情况,在类图中出现了蜘蛛网状结构,可以考虑使用中介者模式,使得蜘蛛网状结构变成星型结构。

N(N>2)个对象之间产生了相互的依赖关系

多个对象有依赖关系,但是依赖的行为尚不确定或者有发生改变的可能

产品开发,例如MVC框架

实际应用

机场调度中心;

MVC框架;

媒介网关;

中介服务;

示例代码

#include <iostream>
#include <string>
#include <time.h>
#include <stdlib.h>

using namespace std;

class Purchase {
public:
    void buyIBMcomputer(int);
    void refuseBuyIBM();
};

class Sale {
public:
    void sellIBMComputer(int);
    int getSaleStatus() {
        srand((int)time(0));
        return rand()%100;
    }
    void offSale();
};

class Stock {
private:
    static int COMPUTER_NUMBER;
public:
    void increase(int);
    void decrease(int);
    int getStockNumber() {return COMPUTER_NUMBER;}
    void clearStock();
};

int Stock::COMPUTER_NUMBER = 100;

void Purchase::buyIBMcomputer(int number) {
    Stock stock; Sale sale;
    int saleStatus = sale.getSaleStatus();
    if(saleStatus > 80) {
        cout << "Purchase IBM computer: " << number << endl;
        stock.increase(number);
    }else {
        int buyNumber = number / 2;
        cout << "Purchase IBM computer: " << number << endl;
        stock.increase(buyNumber);
    }
}

void Purchase::refuseBuyIBM() {
    cout << "No more need to purchase IBM computer" << endl;
}

void Stock::increase(int number) {
    COMPUTER_NUMBER += number;
    cout << "Stock COMPUTER_NUMBER: " << COMPUTER_NUMBER << endl;
}

void Stock::decrease(int number) {
    COMPUTER_NUMBER -= number;
    cout << "Stock COMPUTER_NUMBER: " << COMPUTER_NUMBER << endl;
}

void Stock::clearStock() {
    Purchase purchase; Sale sale;
    cout << "Clear stock number: " << COMPUTER_NUMBER << endl;
    sale.offSale();
    purchase.refuseBuyIBM();
}

void Sale::sellIBMComputer(int number) {
    Stock stock; Purchase purchase;
    if(stock.getStockNumber() < number) purchase.buyIBMcomputer(number);
    cout << "Sell IBM computer number: " << number << endl;
    stock.decrease(number);
}

void Sale::offSale() {
    Stock stock;
    cout << "Sell IBM computer discount number: " << stock.getStockNumber() << endl;
    stock.decrease(stock.getStockNumber());
}

int main() {
    Purchase purchase; Stock stock; Sale sale;
    purchase.buyIBMcomputer(100);
    sale.sellIBMComputer(10);
    stock.clearStock();
    return 0;
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦