源碼地址:https://github.com/weilanhanf/PythonDesignPatterns
?
說明:
訪問者模式的基本想法是,軟件系統中擁有一個由許多對象構成的、比較穩定的對象結構,這些對象的類都擁有一個 accept 方法用來接受訪問者對象的訪問。訪問者是一個接口,它擁有一個 visit 方法,這個方法對訪問到的對象結構中不同類型的元素做出不同的處理。在對象結構的一次訪問過程中,我們遍歷整個對象結構,對每一個元素都實施 accept 方法,在每一個元素的 accept 方法中會調用訪問者的 visit 方法,從而使訪問者得以處理對象結構的每一個元素,我們可以針對對象結構設計不同的訪問者類來完成不同的操作,達到區別對待的效果。
訪問者模式定義:封裝一些作用于某種數據結構中的各元素的操作,它可以在不改變這個數據結構的前提下定義作用于這些元素的新的操作。
?
結構:
抽象訪問者,具體訪問者,抽象元素,具體元素,對象結構。
實例:
假設一個藥房,有一些大夫,一個藥品劃價員和一個藥房管理員,它們通過一個藥房管理系統組織工作流程。大夫開出藥方后,藥品劃價員確定藥品是否正常,價格是否正確;通過后藥房管理員進行開藥處理。該系統可以如何實現?最簡單的想法,是分別用一個一個if…else…把劃價員處理流程和藥房管理流程實現,這樣做的問題在于,擴展性不強,而且單一性不強,一旦有新藥的加入或者劃價流程、開藥流程有些變動,會牽扯比較多的改動。
#構造藥品類和工作人員類 class Medicine:name=""price=0.0def __init__(self,name,price):self.name=nameself.price=pricedef getName(self):return self.namedef setName(self,name):self.name=namedef getPrice(self):return self.pricedef setPrice(self,price):self.price=pricedef accept(self,visitor):pass #藥品類中有兩個子類,抗生素和感冒藥 class Antibiotic(Medicine):def accept(self,visitor):visitor.visit(self) class Coldrex(Medicine):def accept(self,visitor):visitor.visit(self)#工作人員分為劃價員和藥房管理員 class Visitor:name=""def setName(self,name):self.name=namedef visit(self,medicine):pass class Charger(Visitor):def visit(self,medicine):print("CHARGE: %s lists the Medicine %s. Price:%s " % (self.name,medicine.getName(),medicine.getPrice())) class Pharmacy(Visitor):def visit(self,medicine):print("PHARMACY:%s offers the Medicine %s. Price:%s" % (self.name,medicine.getName(),medicine.getPrice()))""" 在藥品類中,有一個accept方法,其參數是個visitor; 而工作人員就是從Visitor類中繼承而來的, 也就是說,他們就是Visitor,都包含一個visit方法,其參數又恰是medicine。 藥品作為處理元素,依次允許(Accept)Visitor對其進行操作, 這就好比是一條流水線上的一個個工人,對產品進行一次次的加工。 整個業務流程還差一步,即藥方類的構建(流水線大機器) """class ObjectStructure:pass class Prescription(ObjectStructure):medicines=[]def addMedicine(self,medicine):self.medicines.append(medicine)def rmvMedicine(self,medicine):self.medicines.append(medicine)def visit(self,visitor):for medc in self.medicines:medc.accept(visitor) #藥方類將待處理藥品進行整理,并組織Visitor依次處理。if __name__=="__main__":yinqiao_pill=Coldrex("Yinqiao Pill",2.0)penicillin=Antibiotic("Penicillin",3.0)doctor_prsrp=Prescription()doctor_prsrp.addMedicine(yinqiao_pill)doctor_prsrp.addMedicine(penicillin)charger=Charger()charger.setName("Doctor Strange")pharmacy=Pharmacy()pharmacy.setName("Doctor Wei")doctor_prsrp.visit(charger)doctor_prsrp.visit(pharmacy)
打印結果:
CHARGE: Doctor Strange lists the Medicine Yinqiao Pill. Price:2.0
CHARGE: Doctor Strange lists the Medicine Penicillin. Price:3.0
PHARMACY:Doctor Wei offers the Medicine Yinqiao Pill. Price:2.0
PHARMACY:Doctor Wei offers the Medicine Penicillin. Price:3.0
優點:
缺點:
使用場景:
?