python-patterns

behavioral行爲

catalog (目錄模式)

類中根據init指定的參數執行相應相應的函數
使用一個字典來代替多個條件。
調用方式
被調用函數:靜態方法無參數

self._static_method_choices[self.param]()

被調用函數:普通函數

self._instance_method_choices[self.param].__get__(self)()

被調用函數:類函數

self._class_method_choices[self.param].__get__(None, self.__class__)()
def __get__(self, obj: Optional[object], type: Optional[type]) -> MethodType: ...

Chain of responsibility(責任鏈)

對象版的:if … elif … elif … else …
擴充:tree of responsibility
實現
抽象類:Handler

def handle(self, request):
	res = self.check_range(request) # 劃分範圍,及處理
	if not res and self.successor: # 責任傳遞
		self.successor.handle(request)
def check_range(self, request):pass

command(命令模式)

封裝執行一個動作或者觸發一個時間的所有信息
例子:
MoveFileCommand
變量src、dest
函數 execute、undo、rename
iterator(迭代器)
遍歷容器並獲取元素
Mediator(中介者)
系統中的對象通過一箇中介交流而不是直接交流。減少對象依賴,因此減少耦合。
例子:用戶通過聊天室聊天。

memento (備忘錄)

保存一個對象之前的狀態
實例
定義用函數,返回函數名(閉包)
定義用類,可用作裝飾器。初始化保留函數,__get__方法返回閉包,state狀態就保留着,失敗直接恢復。

observer(觀察者)

維護依賴列表項,並在狀態改變時喚醒他們。
基類——觀察者管理列
value 觀察列表
方法:attach:添加觀察者;detach:減少觀察者;notify:喚醒觀察者
數據類:繼承基類
觀察者類,處理觀察值。

publish_subscribe(發佈訂閱模式)

消息訂閱與發佈。類似訂報紙。
實例
Provider 消息訂閱、取消、新增消息以及分發功能
Publisher 發佈消息,保留一個provider實例
Subscriber 訂閱消息

registry (註冊模式)

記錄一個類的所有子類
把生成的實例記錄到字典中,通過鍵值(如類名可找到相應的實例)

specification(規約模式)

通過boolean邏輯來串聯重組已有規則
規約模式經常在DDD中使用,用來將業務規則(通常是隱式業務規則)封裝成獨立的邏輯單元,從而將隱式業務規則提煉爲顯示概念,並達到代碼複用的目的。
實現

Specification類:
def and_specification(self, candidate):raise NotImplementedError()
def or_specification(self, candidate):raise NotImplementedError()
def not_specification(self):raise NotImplementedError()
抽象方法def is_satisfied_by(self, candidate): pass
CompositeSpecification(Specification)類,實現and,or,not方法

實例

root_specification = UserSpecification().and_specification(SuperUserSpecification())

state(狀態模式)

定義: 狀態模式允許對象在內部狀態改變時改變他的行爲,對象看起來好像修改了他的類。
主要解決:對象的行爲依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行爲。
何時使用:代碼中包含大量與對象狀態有關的條件語句。
注:可用有限狀態機DFA實現。

strategy(策略模式)

意圖:定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。
主要解決:在有多種算法相似的情況下,使用 if…else 所帶來的複雜和難以維護。
何時使用:一個系統有許多許多類,而區分它們的只是他們直接的行爲。
如何解決:將這些算法封裝成一個一個的類,任意地替換。
注意事項:如果一個系統的策略多於四個,就需要考慮使用混合模式,解決策略類膨脹的問題。
例子:訂單打折,有多種訂單打折策略。傳入不同函數,如10%打折,促銷打折。

template(模板模式)

意圖:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
主要解決:一些方法通用,卻在每一個子類都重新寫了這一方法。
何時使用:有一些通用的方法。

visitor(訪問者模式)

意圖:主要將數據結構與數據操作分離。
主要解決:穩定的數據結構和易變的操作耦合問題。
何時使用:需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而需要避免讓這些操作"污染"這些對象的類,使用訪問者模式將這些封裝到類中。
如何解決:在被訪問的類裏面加一個對外提供接待訪問者的接口。
使用場景: 1、對象結構中對象對應的類很少改變,但經常需要在此對象結構上定義新的操作。 2、需要對一個對象結構中的對象進行很多不同的並且不相關的操作,而需要避免讓這些操作"污染"這些對象的類,也不希望在增加新操作時修改這些類。
注意事項:訪問者可以對功能進行統一,可以做報表、UI、攔截器與過濾器。

creational創建

abstract_factory抽象工廠模式

意圖:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
主要解決:主要解決接口選擇的問題。
何時使用:系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。
如何解決:在一個產品族裏面,定義多個產品。
value:類
borg(MonoState) 單一狀態模式
單例的一種實現方式
共享狀態
實例:數據庫連接管理
實現:self.dict = self.__shared_state # __shared_state = {} 爲類變量

builder建造者模式

意圖:將一個複雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。
主要解決:主要解決在軟件系統中,有時候面臨着"一個複雜對象"的創建工作,其通常由各個部分的子對象用一定的算法構成;由於需求的變化,這個複雜對象的各個部分經常面臨着劇烈的變化,但是將它們組合在一起的算法卻相對穩定。
何時使用:一些基本部件不會變,而其組合經常變化的時候。

factory工廠模式

意圖:定義一個創建對象的接口,讓其子類自己決定實例化哪一個工廠類,工廠模式使其創建過程延遲到子類進行。
主要解決:主要解決接口選擇的問題。
何時使用:我們明確地計劃不同條件下創建不同實例時。

lazy_evaluation懶執行模式

延遲表達式計算直到值需要時,並且避免重複計算
實現:封裝方法,作爲裝飾器。

object_pool對象池模式

意圖:在創建對象比較昂貴,或者對於特定類型能夠創建的對象數目有限制時,管理對象的重用。
例子
queue.Queue
prototype原型模式
意圖:減少應用程序所需的類的數量
主要解決:在運行期建立和刪除原型。
何時使用

  1. 當一個系統應該獨立於它的產品創建,構成和表示時。
  2. 當要實例化的類是在運行時刻指定時,例如,通過動態裝載。
  3. 爲了避免創建一個與產品類層次平行的工廠類層次時。
  4. 當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。

使用場景

  1. 資源優化場景。
  2. 類初始化需要消化非常多的資源,這個資源包括數據、硬件資源等。
  3. 性能和安全要求的場景。
  4. 通過 new 產生一個對象需要非常繁瑣的數據準備或訪問權限,則可以使用原型模式。
  5. 一個對象多個修改者的場景。
  6. 一個對象需要提供給其他對象訪問,而且各個調用者可能都需要修改其值時,可以考慮使用原型模式拷貝多個對象供調用者使用。
  7. 在實際項目中,原型模式很少單獨出現,一般是和工廠方法模式一起出現,通過 clone 的方法創建一個對象,然後由工廠方法提供給調用者。原型模式已經與 Java 融爲渾然一體,大家可以隨手拿來使用。
    fundamental基礎

delegation_pattern委託

使對象複合獲得和繼承相同的代碼重用
在委託模式中,有兩個對象參與處理同一個請求,接受請求的對象將請求委託給另一個對象來處理。

structural結構

3-tier 三層架構:界面層、業務邏輯層、數據訪問層

adapter適配器模式

將不同的接口整合到一個特定的API而不需要修改原來的對象。

bridge橋接模式

目的:將抽象部分與它的實現部分分離,使他們都可以獨立地變化。
“將抽象部分與它的實現部分分離”指實現系統可能有多個角度分類,每一種分類都可能變化,那麼就把這種多角度分離出來讓它們獨立變化,減少它們之間的耦合。
好處

  1. 分離接口及實現部分:接口與實現分離有助於分層,產生更好的結構化系統,系統的高層次部分僅需要關注抽象接口即可。
  2. 提高可擴展性:在一個維度有變化,不需要調整另外一個維度的任何代碼;可以獨立地對多個維度進行擴展。
  3. 實現細節對客戶透明:客戶不需要關注任何實現細節,僅僅需要關注抽象類邏輯。

composite組合模式

主要功能:將對象組合成樹形結構以表示“部分-整體”的層次結構。這可以使得用戶在使用單個對象和組合對象時有一致性。
主要解決:它在我們樹型結構的問題中,模糊了簡單元素和複雜元素的概念,客戶程序可以像處理簡單元素一樣來處理複雜元素,從而使得客戶程序與複雜元素的內部結構解耦。
何時使用:

  1. 您想表示對象的部分-整體層次結構(樹形結構)。
  2. 您希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象。
    UML類圖
    File, Directory 繼承Entry,Entry聚合於Directory(has-a關係)

UML類圖參考 https://www.cnblogs.com/zyrblog/p/9237943.html

decorate裝飾模式

用處:動態添加新功能而不改變原有實現。不像繼承,新功能添加到所有子類,而是隻添加到特定的一個對象。
實例:爲字符串添加xml格式的tag

facade外觀模式

目的:通過爲多個複雜的子系統提供一個一致的接口,而使這些子系統更加容易被訪問的模式。
好處:該模式對外有一個統一接口,外部應用程序不用關心內部子系統的具體的細節,這樣會大大降低應用程序的複雜度,提高了程序的可維護性。
例子:臺式機開機只需要按一個開機按鈕。

flyweight享元模式

意圖:運用共享技術有效地支持大量細粒度的對象。
主要解決:在有大量對象時,有可能會造成內存溢出,我們把其中共同的部分抽象出來,如果有相同的業務請求,直接返回在內存中已有的對象,避免重新創建。
適用性

  1. 一個應用程序使用了大量的對象。
  2. 完全由於使用大量的對象,造成很大的存儲開銷。
  3. 對象的大多數狀態都可變爲外部狀態。
  4. 如果刪除對象的外部狀態,那麼可以用相對較少的共享對象取代很多組對象。
    應用程序不依賴於對象標識。
    弱引用:弱引用指引用一個對象但不增加它的引用計數器 https://blog.51cto.com/sleepd/1073044

frontcontroller前段控制器模式

用來提供一個集中的請求處理機制,所有的請求都將由一個單一的處理程序處理。該處理程序可以做認證/授權/記錄日誌,或者跟蹤請求,然後把請求傳給相應的處理程序。
實現
前端控制器(Front Controller) - 處理應用程序所有類型請求的單個處理程序,應用程序可以是基於 web 的應用程序,也可以是基於桌面的應用程序。
調度器(Dispatcher) - 前端控制器可能使用一個調度器對象來調度請求到相應的具體處理程序。
視圖(View) - 視圖是爲請求而創建的對象。
MVC模型-視圖-控制器模式
用於應用程序的分層開發

proxy代理模式

意圖:爲其他對象提供一種代理以控制對這個對象的訪問。
主要解決:在直接訪問對象時帶來的問題,比如說:要訪問的對象在遠程的機器上。在面向對象系統中,有些對象由於某些原因(比如對象創建開銷很大,或者某些操作需要安全控制,或者需要進程外的訪問),直接訪問會給使用者或者系統結構帶來很多麻煩,我們可以在訪問此對象時加上一個對此對象的訪問層。
何時使用:想在訪問一個類時做一些控制。
例子:客戶——代理溝通——經理

dependency_injection依賴注入

實現控制反轉
如果一個類A 的功能實現需要藉助於類B,那麼就稱類B是類A的依賴,如果在類A的內部去實例化類B,那麼兩者之間會出現較高的耦合,一旦類B出現了問題,類A也需要進行改造,如果這樣的情況較多,每個類之間都有很多依賴,那麼就會出現牽一髮而動全身的情況,程序會極難維護,並且很容易出現問題。要解決這個問題,就要把A類對B類的控制權抽離出來,交給一個第三方去做,把控制權反轉給第三方,就稱作控制反轉(IOC Inversion Of Control)。控制反轉是一種思想,是能夠解決問題的一種可能的結果,而依賴注入(Dependency Injection)就是其最典型的實現方法。由第三方(我們稱作IOC容器)來控制依賴,把他通過構造函數、屬性或者工廠模式等方法,注入到類A內,這樣就極大程度的對類A和類B進行了解耦。

參考資料

Head First設計模式
https://github.com/faif/python-patterns
https://www.runoob.com/design-pattern/strategy-pattern.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章