目錄:
單一職責原則:
對象不應承擔太多功能,正如一心不能而用,比如太多的工作(種類)會使人崩潰。唯有專注才能保證對象的高內聚;唯有唯一,才能保證對象的細粒度。
解決問題:
假如有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 }
優點:
1、降低類的功能復雜度
2、提高系統的可維護性
3、變更風險低