亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python?設(shè)計(jì)模式行為型訪問(wèn)者模式

 更新時(shí)間:2022年02月15日 14:25:01   作者:范桂颶  
這篇文章主要介紹了Python?設(shè)計(jì)模式行為型訪問(wèn)者模式,訪問(wèn)者模式即Visitor?Pattern,訪問(wèn)者模式,指作用于一個(gè)對(duì)象結(jié)構(gòu)體上的元素的操作,下文相關(guān)資料需要的小伙伴可以參考一下

一、訪問(wèn)者模式(Visitor Pattern)

數(shù)據(jù)結(jié)構(gòu)中保存著許多元素,當(dāng)我們希望改變一種對(duì)元素的處理方式時(shí),要避免重復(fù)的修改數(shù)據(jù)結(jié)構(gòu)。那么就要求我們?cè)趯?shí)現(xiàn)代碼時(shí),將數(shù)據(jù)的處理進(jìn)行分離,即:數(shù)據(jù)類只提供一個(gè)數(shù)據(jù)處理的接口,而該數(shù)據(jù)處理接口就被稱之為訪問(wèn)者。那么,相同結(jié)構(gòu)的數(shù)據(jù)面臨不同的處理結(jié)果時(shí),我們只需要?jiǎng)?chuàng)建不同的訪問(wèn)者。

訪問(wèn)者模式,指作用于一個(gè)對(duì)象結(jié)構(gòu)體上的元素的操作。訪問(wèn)者可以使用戶在不改變?cè)摻Y(jié)構(gòu)體中的類的基礎(chǔ)上定義一個(gè)新的操作。

優(yōu)點(diǎn):

  • 使得在訪問(wèn)者類中針對(duì)復(fù)雜類結(jié)構(gòu)中的某個(gè)類添加新方法較為容易,即:只需要簡(jiǎn)單地添加一個(gè)新的訪問(wèn)者方法即可。如果不采用訪問(wèn)者模式,這需要在每個(gè)類中添加一個(gè)新的方法。
  • 訪問(wèn)者將相關(guān)的方法集中在一個(gè)具體的訪問(wèn)者類中,而其他相關(guān)的方法集中在另外一個(gè)具體的訪問(wèn)者類中。也就是說(shuō),訪問(wèn)者子類是按照方法的類型來(lái)分類的。

缺點(diǎn):

  • 增加一個(gè)具體的新 ConcreteElement 類比較困難。因?yàn)榇藭r(shí)需要在每一個(gè) ConcreteVisitor 類中添加該 ConcreteElement 類的訪問(wèn)方法。

二、應(yīng)用場(chǎng)景

當(dāng)一個(gè)對(duì)象的結(jié)構(gòu)中,包含有多種類型的具有不同接口的對(duì)象,且用戶要在這些對(duì)象上進(jìn)行依賴于具體的類的運(yùn)算時(shí),需要用到訪問(wèn)者模式。這就是為什么訪問(wèn)者模式要針對(duì)每個(gè)被訪問(wèn)的子類都設(shè)計(jì)一個(gè)不同的接口的原因。事實(shí)上,如果每個(gè)被訪問(wèn)的子類都有相同的接口,包括構(gòu)造方法、其他方法、參數(shù)都一致,則訪問(wèn)者類只需要設(shè)計(jì)一個(gè)訪問(wèn)方法,在該方法中含有一個(gè)用于區(qū)別不同的被訪問(wèn)的子類的參數(shù)即可。例如:可以使用被訪問(wèn)者基類作為參數(shù)類型。在對(duì)象的結(jié)構(gòu)中包含有多種類型的有不同接口的對(duì)象時(shí),各個(gè)不同的訪問(wèn)方法可能為訪問(wèn)所對(duì)應(yīng)的類提供不同的參數(shù)類型。

當(dāng)有多個(gè)不同的并且互不相關(guān)的運(yùn)算將作用到這些對(duì)象上,而用戶不希望這些運(yùn)算混淆這些類時(shí),可以使用訪問(wèn)者模式將相關(guān)的操作放到獨(dú)立的類中,例如:為了實(shí)現(xiàn)每個(gè)結(jié)點(diǎn)類中的計(jì)算價(jià)格方法,可以將所有的計(jì)算價(jià)格方法放到一個(gè) VisitPrice 類中。

在對(duì)象的數(shù)據(jù)類型很少改變,但是需要經(jīng)常改變操作或者增加新的操作的情況下,可以使用訪問(wèn)者模式。反之,如果 Element 的子類經(jīng)常改變結(jié)構(gòu),例如:需要增加一個(gè)新的稅種,這就需要在訪問(wèn)者類中增加新的訪問(wèn)方法,因此,在這種情況下使用訪問(wèn)者模式代價(jià)較高,盡量不要使用訪問(wèn)者模式。

三、代碼示例

該類圖包含兩個(gè)系列的類:“Element 類” 和 “訪問(wèn)者類”,訪問(wèn)者類定義了施加于 Element 類上的操作,為 Element 類提供一些功能。可以有多種具體的訪問(wèn)者類,各自完成特定的目的,如一個(gè)訪問(wèn)者類是計(jì)算價(jià)格,另一個(gè)訪問(wèn)者類則是計(jì)算存貨數(shù)量。因此需要定義一個(gè)抽象的訪問(wèn)者父類 Visitor 以及用于各種特殊目的具體的子類。Visitor 類必須給每個(gè)結(jié)點(diǎn)類提供一個(gè)操作,即訪問(wèn)方法,例如獲得各結(jié)點(diǎn)所代表的商品對(duì)象的價(jià)格等。

實(shí)體角色組成:

  • Visitor:為每個(gè) Element 的對(duì)象聲明一個(gè)訪問(wèn)操作。該訪問(wèn)操作的名字最好要包含被訪問(wèn)的類的名字,以便確認(rèn)該訪問(wèn)操作是專門針對(duì)哪個(gè)具體的類,如:visitFamilyNoChildren 是專門為了服務(wù)類 FamilyNoChildren 的。
  • ConcreteVisitor:實(shí)現(xiàn) Visitor 聲明的運(yùn)算。每個(gè)運(yùn)算實(shí)現(xiàn)為對(duì)應(yīng)的類的對(duì)象定義的算法的一部分。ConcreteVisitor 提供算法的環(huán)境并且存儲(chǔ)其局部狀態(tài)。
  • Element:定義了一些基本的方法,其中包含提供基本數(shù)據(jù)的方法,例如一些 get()與 set()方法。重要的是,每個(gè) Element 子類都必須定義一個(gè)接收者方法,該方法以 Visitor 為參數(shù)類型:Accept(Visitor),其作用是為被訪問(wèn)者對(duì)象和訪問(wèn)者對(duì)象之間的交互提供接口。
  • ConcreteElement:具體的 Element 的子類,例如 ElementA,該類包含一個(gè) accept 方法接收訪問(wèn)者對(duì)象。另外,該類還可能定義一些其他的方法以幫助訪問(wèn)者實(shí)現(xiàn)一些功能。
  • ObjectStructure:提供一個(gè)高層接口,允許訪問(wèn)者訪問(wèn) Element 的子類。在該類中可以包含一個(gè)結(jié)構(gòu),例如 ArrayList、Vector 等,提供所要訪問(wèn)的 element 的列表。

示例:上市公司的原始財(cái)務(wù)數(shù)據(jù):

  • 對(duì)于會(huì)計(jì)來(lái)說(shuō)需要制作各種報(bào)表
  • 對(duì)于財(cái)務(wù)總監(jiān)來(lái)說(shuō)需要分析公司業(yè)績(jī)
  • 對(duì)于戰(zhàn)略顧問(wèn)來(lái)說(shuō)需要分析行業(yè)變化
class Finance:
? ? """財(cái)務(wù)數(shù)據(jù)結(jié)構(gòu)類"""
? ??
? ? def __init__(self):
? ? ? ? self.salesvolume = None ? ? ? ? ?# 銷售額
? ? ? ? self.cost = None ? ? ? ? ? ? ? ? # 成本
? ? ? ? self.history_salesvolume = None ?# 歷史銷售額
? ? ? ? self.history_cost = None ? ? ? ? # 歷史成本

? ? def set_salesvolume(self, value):
? ? ? ? self.salesvolume = value

? ? def set_cost(self, value):
? ? ? ? self.cost = value

? ? def set_history_salesvolume(self, value):
? ? ? ? self.history_salesvolume = value

? ? def set_history_cost(self, value):
? ? ? ? self.history_cost = value

? ? def accept(self, visitor):
? ? ? ? pass


class Finance_year(Finance):
? ? """2018 年財(cái)務(wù)數(shù)據(jù)類"""

? ? def __init__(self, year):
? ? ? ? Finance.__init__(self)
? ? ? ? self.work = [] ? ?# 安排工作人員列表
? ? ? ? self.year = year

? ? def add_work(self, work):
? ? ? ? self.work.append(work)

? ? def accept(self):
? ? ? ? for obj in self.work:
? ? ? ? ? ? obj.visit(self)


class Accounting:
? ? """會(huì)計(jì)類"""

? ? def __init__(self):
? ? ? ? self.ID = "會(huì)計(jì)"
? ? ? ? self.Duty = "計(jì)算報(bào)表"

? ? def visit(self, table):
? ? ? ? print('會(huì)計(jì)年度: {}'.format(table.year))
? ? ? ? print("我的身份是: {} 職責(zé): {}".format(self.ID, self.Duty))
? ? ? ? print('本年度純利潤(rùn): {}'.format(table.salesvolume - table.cost))
? ? ? ? print('------------------')


class Audit:
? ? """財(cái)務(wù)總監(jiān)類"""

? ? def __init__(self):
? ? ? ? self.ID = "財(cái)務(wù)總監(jiān)"
? ? ? ? self.Duty = "分析業(yè)績(jī)"

? ? def visit(self, table):
? ? ? ? print('會(huì)計(jì)總監(jiān)年度: {}'.format(table.year))
? ? ? ? print("我的身份是: {} 職責(zé): {}".format(self.ID, self.Duty))
? ? ? ? if table.salesvolume - table.cost > table.history_salesvolume - table.history_cost:
? ? ? ? ? ? msg = "較同期上漲"
? ? ? ? else:
? ? ? ? ? ? msg = "較同期下跌"
? ? ? ? print('本年度公司業(yè)績(jī): {}'.format(msg))
? ? ? ? print('------------------')


class Adviser:
? ? """戰(zhàn)略顧問(wèn)"""
? ? def __init__(self):
? ? ? ? self.ID = "戰(zhàn)略顧問(wèn)"
? ? ? ? self.Duty = "制定明年戰(zhàn)略"

? ? def visit(self, table):
? ? ? ? print('戰(zhàn)略顧問(wèn)年度: {}'.format(table.year))
? ? ? ? print("我的身份是: {} 職責(zé): {}".format(self.ID, self.Duty))
? ? ? ? if table.salesvolume > table.history_salesvolume:
? ? ? ? ? ? msg = "行業(yè)上行,擴(kuò)大生產(chǎn)規(guī)模"
? ? ? ? else:
? ? ? ? ? ? msg = "行業(yè)下行,減小生產(chǎn)規(guī)模"
? ? ? ? print('本年度公司業(yè)績(jī): {}'.format(msg))
? ? ? ? print('------------------')


class Work:
? ? """工作類"""

? ? def __init__(self):
? ? ? ? self.works = [] ?# 需要處理的年度數(shù)據(jù)列表

? ? def add_work(self, obj):
? ? ? ? self.works.append(obj)

? ? def remove_work(self, obj):
? ? ? ? self.works.remove(obj)

? ? def visit(self):
? ? ? ? for obj in self.works:
? ? ? ? ? ? obj.accept()


if __name__ == '__main__':
? ? work = Work() ?# 計(jì)劃安排財(cái)務(wù)、總監(jiān)、顧問(wèn)對(duì)2018年數(shù)據(jù)處理
? ? # 實(shí)例化2018年數(shù)據(jù)結(jié)構(gòu)
? ? finance_2018 = Finance_year(2018)
? ? finance_2018.set_salesvolume(200)
? ? finance_2018.set_cost(100)
? ? finance_2018.set_history_salesvolume(180)
? ? finance_2018.set_history_cost(90)
? ? accounting = Accounting() ? # 實(shí)例化會(huì)計(jì)
? ? audit = Audit() ?# 實(shí)例化總監(jiān)
? ? adviser = Adviser() ? ? # 實(shí)例化顧問(wèn)
? ? finance_2018.add_work(accounting) ? # 會(huì)計(jì)安排到2018分析日程中
? ? finance_2018.add_work(audit) ? ?# 總監(jiān)安排到2018分析日程中
? ? finance_2018.add_work(adviser) ?# 顧問(wèn)安排到2018分析日程中
? ? work.add_work(finance_2018) # 添加2018年財(cái)務(wù)工作安排
? ? work.visit()

到此這篇關(guān)于Python 設(shè)計(jì)模式行為型 訪問(wèn)者模式的文章就介紹到這了,更多相關(guān)Python訪問(wèn)者模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python 讀寫文件,按行修改文件的方法

    python 讀寫文件,按行修改文件的方法

    今天小編就為大家分享一篇python 讀寫文件,按行修改文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 關(guān)于Kotlin中SAM轉(zhuǎn)換的那些事

    關(guān)于Kotlin中SAM轉(zhuǎn)換的那些事

    這篇文章主要給大家介紹了關(guān)于Kotlin中SAM轉(zhuǎn)換的那些事,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • python使用數(shù)字與字符串方法技巧

    python使用數(shù)字與字符串方法技巧

    這篇文章主要介紹了python使用數(shù)字與字符串方法技巧,文章內(nèi)容介紹詳細(xì)具有一的參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03
  • Pycharm中的Python?Console用法解讀

    Pycharm中的Python?Console用法解讀

    這篇文章主要介紹了Pycharm中的Python?Console用法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 帶你了解Python妙開根號(hào)的三種方式

    帶你了解Python妙開根號(hào)的三種方式

    這篇文章主要為大家介紹了Python妙開根號(hào)的三種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • pandas如何修改某一列的數(shù)據(jù)

    pandas如何修改某一列的數(shù)據(jù)

    這篇文章主要介紹了pandas如何修改某一列的數(shù)據(jù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Python爬蟲爬取有道實(shí)現(xiàn)翻譯功能

    Python爬蟲爬取有道實(shí)現(xiàn)翻譯功能

    這篇文章主要介紹了Python爬蟲爬取有道實(shí)現(xiàn)翻譯功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Python實(shí)現(xiàn)多子圖繪制系統(tǒng)的示例詳解

    Python實(shí)現(xiàn)多子圖繪制系統(tǒng)的示例詳解

    這篇文章主要介紹了如何利用python實(shí)現(xiàn)多子圖繪制系統(tǒng),文中的示例代碼講解詳細(xì),具有一定的的參考價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • 使用Python實(shí)現(xiàn)全攝像頭拍照與鍵盤輸入監(jiān)聽功能

    使用Python實(shí)現(xiàn)全攝像頭拍照與鍵盤輸入監(jiān)聽功能

    這篇文章主要介紹了使用Python實(shí)現(xiàn)全攝像頭拍照與鍵盤輸入監(jiān)聽功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • 淺談python print(xx, flush = True) 全網(wǎng)最清晰的解釋

    淺談python print(xx, flush = True) 全網(wǎng)最清晰的解釋

    今天小編就為大家分享一篇淺談python print(xx, flush = True) 全網(wǎng)最清晰的解釋,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02

最新評(píng)論