設計模式之前是學過的,這次報軟考既是複習又是提高。軟考需要通過java學習設計模式,之前學的雖然是C#,但設計模式的思想是一樣的。話不多說直奔主題,下面先了解一下什麼事政策模式。
政策模式定義了算法家族,分别封裝起來,讓它們之間可以互相轉換,此模式讓算法的變化不會影響到使用算法的客戶。
舉個例子:
現在有一個鴨子父類,我們需要它的之類有綠頭鴨、紅頭鴨。隻需要在父類裡面寫一個虛方法display然後讓子類去重寫,綠頭鴨的display就實作綠色的頭,紅頭鴨就實作紅色的頭。現在讓所有的鴨子都能飛,實作起來也比較簡單,在父類裡面添加一個fly的方法就可以了。同樣的道理如果需要所有的鴨子都會叫,在父類裡面添加quack方法就能實作。
那麼問題來了,現在我們有一隻橡皮鴨也繼承于父類。橡皮鴨會叫不會飛,但是它不會像真鴨子那樣呱呱叫,橡皮鴨隻能吱吱叫。我們隻能在橡皮鴨子類覆寫父類的fly方法讓它什麼也不做,然後覆寫quack方法讓它吱吱叫。
再延伸一下現在又來了一隻木頭假鴨不會飛也不會叫。同樣讓它繼承父類然後覆寫父類的fly和quack方法,讓這兩個方法什麼也不做。
這樣做确實把橡皮鴨和木頭鴨都實作了,但是橡皮鴨中根本不需要fly方法,木頭鴨中也不需要fly和quack方法,卻都要在寫一遍覆寫掉父類,簡直就是畫蛇添足。更痛苦的是再添加新的鴨子進來就得考慮是不是需要覆寫父類的fly和quack。那怎麼辦好呢?
這時候我們就需要把應用中可能變化的部分獨立出來,不會再影響到其他部分。
在這個例子中也就是把飛行行為和叫行為從Duck類中分離出來,鴨子類就不再需要知道行為的實作細節。類圖如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90TQOJzaq5UerRUT4FEVkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jM3MjMxAzMwEzNxMDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
代碼實作:
運作結果:
優點:
1、 政策模式提供了管理相關的算法族的辦法。政策類的等級結構定義了一個算法或行為族。恰當使用繼承可以把公共的代碼轉移到父類裡面,進而避免重複的代碼。
2、 政策模式提供了可以替換繼承關系的辦法。繼承可以處理多種算法或行為。如果不是用政策模式,那麼使用算法或行為的環境類就可能會有一些子類,每一個子類提供一個不同的算法或行為。但是,這樣一來算法或行為的使用者就和算法或行為本身混在一起。決定使用哪一種算法或采取哪一種行為的邏輯就和算法或行為的邏輯混合在一起,進而不可能再獨立演化。繼承使得動态改變算法或行為變得不可能。
3、 使用政策模式可以避免使用多重條件轉移語句。多重轉移語句不易維護,它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起,統統列在一個多重轉移語句裡面,比使用繼承的辦法還要原始和落後。
缺點:
1、用戶端必須知道所有的政策類,并自行決定使用哪一個政策類。這就意味着用戶端必須了解這些算法的差別,以便适時選擇恰當的算法類。換言之,政策模式隻适用于用戶端知道所有的算法或行為的情況。
2、 政策模式造成很多的政策類,每個具體政策類都會産生一個新類。有時候可以通過把依賴于環境的狀态儲存到用戶端裡面,而将政策類設計成可共享的,這樣政策類執行個體可以被不同用戶端使用。換言之,可以使用享元模式來減少對象的數量。