中介者模式就像代理模式的高級版,代理模式只代理一方,而中介者代理兩方或者更多的角色。
場景案例:公司的3個部門,銷售、採購、庫存相互協作,他們之間有如下約定:
- 銷售部門的成績決定是否要採購
- 庫存不足的情況下,銷售部門停止銷售,採購部門儘快採購
- 庫存要清倉,通知採購部門停止採購,銷售部門打折出售
這裏看到3者之間都是相互聯繫的,如果用通常的做法定義3個類,會發現他們之間耦合非常大,讀者有興趣可以嘗試下。下面我使用中介者模式來實現它。
抽象中介者類:
# 抽象中介者類
class AbstractMediator:
# 中介者管理的同事列表
_colleagues = {}
# 增加一個要被管理的同事
def add_colleague(self, name, colleague):
self._colleagues[name] = colleague
colleague.set_mediator(self)
# 中介者最重要的事件方法,處理多個同事對象之間的關係
def execute(self, method, args):
pass
抽象同事類:
# 抽象同事類,只定義關聯的中介者,繼承此類的子類共用一箇中介者
class AbstractColleague:
_mediator = None
def set_mediator(self, _mediator):
self._mediator = _mediator
庫存類:
# 庫存類
class Stock(AbstractColleague):
# 庫存數量,剛開始有10臺
__number = 10
# 獲取庫存餘量
def get_stock_number(self):
return self.__number
# 增加庫存
def increase(self, number):
self.__number += number
# 減少庫存
def decrease(self, number):
self.__number -= number
# 清倉處理
def clear_stock(self):
print('開始清倉,當前庫存數量:%d' % self.__number)
self._mediator.execute('stock.clear', None)
採購類:
# 採購類
class Purchase(AbstractColleague):
# 採購多少臺電腦
def buy_computer(self, number):
self._mediator.execute('purchase.buy', number)
# 停止採購
def stop_buy(self):
print('停止採購啦')
銷售類:
# 銷售類
class Sale(AbstractColleague):
# 銷售電腦
def sell_computer(self, number):
self._mediator.execute('sale.sell', number)
print('銷售賣了%d臺電腦' % number)
# 獲取銷售情況(0-100分)
def get_sale_score(self):
score = random.randint(0, 100)
print('當前銷售分數:%d' % score)
return score
# 打折處理
def off_sale(self):
self._mediator.execute('sale.offSale', None)
下面是關鍵的中介者類:
# 具體中介者
class Mediator(AbstractMediator):
# 重寫抽象類的事件方法
def execute(self, method, args):
if method == 'purchase.buy':
self.buy_computer(args)
elif method == 'sale.sell':
self.sell_computer(args)
elif method == 'sale.offSale':
self.off_sale()
elif method == 'stock.clear':
self.clear_stock()
# 購買電腦
def buy_computer(self, number):
__sale = self._colleagues['sale']
__stock = self._colleagues['stock']
score = __sale.get_sale_score()
if score > 80:
print('銷售情況不錯,採購電腦%d臺' % number)
__stock.increase(number)
elif score >= 30:
print('銷售情況湊合,採購電腦%d臺' % (number / 2))
__stock.increase(number / 2)
else:
print('銷售情況稀爛,不買了')
# 銷售電腦
def sell_computer(self, number):
__stock = self._colleagues['stock']
__purchase = self._colleagues['purchase']
if __stock.get_stock_number() < number:
print('庫存不足%d,急需要採購' % number)
__purchase.buy_computer(number)
__stock.decrease(number)
# 打折銷售
def off_sale(self):
__stock = self._colleagues['stock']
print('折價銷售%d臺電腦' % __stock.get_stock_number())
__stock.decrease(__stock.get_stock_number())
# 清倉處理
def clear_stock(self):
__purchase = self._colleagues['purchase']
__sale = self._colleagues['sale']
__purchase.stop_buy()
__sale.off_sale()
構造場景:
if __name__ == '__main__':
purchase = Purchase()
sale = Sale()
stock = Stock()
mediator = Mediator()
mediator.add_colleague("purchase", purchase)
mediator.add_colleague("sale", sale)
mediator.add_colleague("stock", stock)
print()
buy_number = random.randint(50, 100)
print('---------採購人員計劃採購電腦' + str(buy_number) + '臺---------')
purchase.buy_computer(buy_number)
print('當前庫存數量爲:%d' % stock.get_stock_number())
print()
sell_number = random.randint(20, 80)
print('---------銷售人員要銷售電腦' + str(sell_number) + '臺---------')
sale.sell_computer(sell_number)
print('當前庫存數量爲:%d' % stock.get_stock_number())
print()
print('---------庫房清倉---------')
stock.clear_stock()
print('當前庫存數量爲:%d' % stock.get_stock_number())
print()
執行結果:
---------採購人員計劃採購電腦59臺---------
當前銷售分數:80
銷售情況湊合,採購電腦29臺
當前庫存數量爲:39
---------銷售人員要銷售電腦49臺---------
庫存不足49,急需要採購
當前銷售分數:68
銷售情況湊合,採購電腦24臺
銷售賣了49臺電腦
當前庫存數量爲:15
---------庫房清倉---------
開始清倉,當前庫存數量:15
停止採購啦
折價銷售15臺電腦
當前庫存數量爲:0
中介者模式往往在框架的設計層面上才用得到,比如著名的MVC(這裏的C即Controller,就是一箇中介者)。平時業務代碼很少出現這麼高的耦合情況,如果濫用的話,反而會使項目變的更復雜。