目錄: html
設計模式六大原則:單一職責原則設計模式
設計模式六大原則:接口隔離原則 ide
設計模式六大原則:里氏替換原則.net
設計模式六大原則:開閉原則rest
單一職責原則:code
對象不該承擔太多功能,正如一心不能而用,好比太多的工做(種類)會令人崩潰。惟有專一才能保證對象的高內聚;惟有惟一,才能保證對象的細粒度。htm
解決問題:對象
假若有A和B兩個類,當A需求發生改變須要修改時,不能致使B類出問題。
現狀:
在實際狀況很難去作到單一職責原則,由於隨着業務的不斷變動,類的職責也在發生着變化,即職責擴散。如類A完成職責P的功能,可是隨着後期業務細化,職責P分解成更小粒度的P1與P2,這時根據單一職責原則則須要拆分類A以分別知足細分後的職責P1和P2。可是實際開發環節,若類的邏輯足夠簡單,能夠在代碼上級別上違背單一職責原則;若類的方法足夠少,能夠在方法級別上違背單一職責原則。
經典案例:
用一個類描述動物呼吸的場景
1 namespace MyDemo 2 { 3 internal class Animal 4 { 5 public void breath(string animal) 6 { 7 Console.WriteLine($"{animal}呼吸空氣"); 8 } 9 } 10 }
1 namespace MyDemo 2 { 3 internal class Program 4 { 5 private static void Main(string[] args) 6 { 7 Animal animal = new Animal(); 8 animal.breath("🐂"); 9 animal.breath("🐖"); 10 animal.breath("🐎"); 11 animal.breath("🐟"); 12 } 13 } 14 }
從示例能夠發現,Animal類已不足以支持客戶端所需職責,由於🐟吃水。若遵循單一職責原則,則須要拆分Animal類。
1 internal class Terrestrial 2 { 3 public void breath(string animal) 4 { 5 Console.WriteLine($"{animal}呼吸空氣"); 6 } 7 } 8 9 internal class Aquatic 10 { 11 public void breath(string animal) 12 { 13 Console.WriteLine($"{animal}吃水"); 14 } 15 }
1 internal class Program 2 { 3 private static void Main(string[] args) 4 { 5 Terrestrial terrestrial = new Terrestrial(); 6 terrestrial.breath("🐂"); 7 terrestrial.breath("🐖"); 8 terrestrial.breath("🐎"); 9 10 Aquatic aquatic = new Aquatic(); 11 aquatic.breath("🐟"); 12 } 13 }
這時你會發現,若針對簡單的業務邏輯來講,若每次細分都須要拆分的話實在是太繁瑣了,並且服務端與客戶端代碼都須要作相應的修改。因此直接在原先類中進行修改,雖然違背了單一職責原則,但花銷小。
1 internal class Animal 2 { 3 public void breath(string animal) 4 { 5 if ("🐟".Equals(animal)) 6 { 7 Console.WriteLine($"{animal}吃水"); 8 } 9 else 10 { 11 Console.WriteLine($"{animal}呼吸空氣"); 12 } 13 } 14 }
優勢:
一、下降類的功能複雜度
二、提升系統的可維護性
三、變動風險低