中介者模式
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;
}