15、Python與設計模式–中介者模式

途索發表於2017-02-27

一、倉儲管理系統

有一個手機倉儲管理系統,使用者有三方:銷售、倉庫管理員、採購。需求是:銷售一旦達成訂單,銷售人員會通過系統的銷售子系統部分通知倉儲子系統,倉儲子系統會將可出倉手機數量減少,同時通知採購管理子系統當前銷售訂單;倉儲子系統的庫存到達閾值以下,會通知銷售子系統和採購子系統,並督促採購子系統採購;採購完成後,採購人員會把採購資訊填入採購子系統,採購子系統會通知銷售子系統採購完成,並通知倉庫子系統增加庫存。
從需求描述來看,每個子系統都和其它子系統有所交流,在設計系統時,如果直接在一個子系統中整合對另兩個子系統的操作,一是耦合太大,二是不易擴充套件。為解決這類問題,我們需要引入一個新的角色-中介者-來將“網狀結構”精簡為“星形結構”。(為充分說明設計模式,某些系統細節暫時不考慮,例如:倉庫滿了怎麼辦該怎麼設計。類似業務性的內容暫時不考慮)
首先構造三個子系統,即三個類(在中介者模式中,這些類叫做同事些):

class colleague():
    mediator = None
    def __init__(self,mediator):
        self.mediator = mediator
class purchaseColleague(colleague):
    def buyStuff(self,num):
        print "PURCHASE:Bought %s"%num
        self.mediator.execute("buy",num)
    def getNotice(self,content):
        print "PURCHASE:Get Notice--%s"%content
class warehouseColleague(colleague):
    total=0
    threshold=100
    def setThreshold(self,threshold):
        self.threshold=threshold
    def isEnough(self):
        if self.total<self.threshold:
            print "WAREHOUSE:Warning...Stock is low... "
            self.mediator.execute("warning",self.total)
            return False
        else:
            return True
    def inc(self,num):
        self.total+=num
        print "WAREHOUSE:Increase %s"%num
        self.mediator.execute("increase",num)
        self.isEnough()
    def dec(self,num):
        if num>self.total:
            print "WAREHOUSE:Error...Stock is not enough"
        else:
            self.total-=num
            print "WAREHOUSE:Decrease %s"%num
            self.mediator.execute("decrease",num)
        self.isEnough()
class salesColleague(colleague):
    def sellStuff(self,num):
        print "SALES:Sell %s"%num
        self.mediator.execute("sell",num)
    def getNotice(self, content):
        print "SALES:Get Notice--%s" % content

當各個類在初始時都會指定一箇中介者,而各個類在有變動時,也會通知中介者,由中介者協調各個類的操作。
中介者實現如下:

class abstractMediator():
    purchase=""
    sales=""
    warehouse=""
    def setPurchase(self,purchase):
        self.purchase=purchase
    def setWarehouse(self,warehouse):
        self.warehouse=warehouse
    def setSales(self,sales):
        self.sales=sales
    def execute(self,content,num):
        pass
class stockMediator(abstractMediator):
    def execute(self,content,num):
        print "MEDIATOR:Get Info--%s"%content
        if  content=="buy":
            self.warehouse.inc(num)
            self.sales.getNotice("Bought %s"%num)
        elif content=="increase":
            self.sales.getNotice("Inc %s"%num)
            self.purchase.getNotice("Inc %s"%num)
        elif content=="decrease":
            self.sales.getNotice("Dec %s"%num)
            self.purchase.getNotice("Dec %s"%num)
        elif content=="warning":
            self.sales.getNotice("Stock is low.%s Left."%num)
            self.purchase.getNotice("Stock is low. Please Buy More!!! %s Left"%num)
        elif content=="sell":
            self.warehouse.dec(num)
            self.purchase.getNotice("Sold %s"%num)
        else:
            pass

中介者模式中的execute是最重要的方法,它根據同事類傳遞的資訊,直接協調各個同事的工作。
在場景類中,設定倉儲閾值為200,先採購300,再賣出120,實現如下:

if  __name__=="__main__":
    mobile_mediator=stockMediator()#先配置
    mobile_purchase=purchaseColleague(mobile_mediator)
    mobile_warehouse=warehouseColleague(mobile_mediator)
    mobile_sales=salesColleague(mobile_mediator)
    mobile_mediator.setPurchase(mobile_purchase)
    mobile_mediator.setWarehouse(mobile_warehouse)
    mobile_mediator.setSales(mobile_sales)

    mobile_warehouse.setThreshold(200)
    mobile_purchase.buyStuff(300)
    mobile_sales.sellStuff(120)

列印結果如下:
PURCHASE:Bought 300
MEDIATOR:Get Info–buy
WAREHOUSE:Increase 300
MEDIATOR:Get Info–increase
SALES:Get Notice–Inc 300
PURCHASE:Get Notice–Inc 300
SALES:Get Notice–Bought 300
SALES:Sell 120
MEDIATOR:Get Info–sell
WAREHOUSE:Decrease 120
MEDIATOR:Get Info–decrease
SALES:Get Notice–Dec 120
PURCHASE:Get Notice–Dec 120
WAREHOUSE:Warning…Stock is low…
MEDIATOR:Get Info–warning
SALES:Get Notice–Stock is low.180 Left.
PURCHASE:Get Notice–Stock is low. Please Buy More!!! 180 Left
PURCHASE:Get Notice–Sold 120

二、中介者模式

中介者模式的定義為:用一箇中介物件封裝一系列的物件互動。中介者使各物件不需要顯式地互相作用,從而使其耦合鬆散,並可以獨立地改變它們之間的互動。
f1.png

三、中介者模式的優點和應用場景

優點:
1、減少類與類的依賴,降低了類和類之間的耦合;
2、容易擴充套件規模。
應用場景:
1、設計類圖時,出現了網狀結構時,可以考慮將類圖設計成星型結構,這樣就可以使用中介者模式了。如機場排程系統(多個跑道、飛機、指揮塔之間的排程)、路由系統;著名的MVC框架中,其中的C(Controller)就是M(Model)和V(View)的中介者。

四、中介者模式的缺點

1、中介者本身的複雜性可能會很大,例如,同事類的方法如果很多的話,本例中的execute邏輯會很複雜。


相關文章