0x02、設計模式原則 —— 單一職責原則
阿新 • • 發佈:2022-04-01
概念
對類來說的,一個類應該只負責一項職責。(記住)
假如:類A負責兩個不同職責:職責1,職責2。當職責1需求變更而改變類A時,可能造成職責2執行錯誤,所以需要將類A的粒度分解為A1, A2(即將類A的兩個職責分解為A1類和A2類);
先看如下程式碼:
Vehicle _vehicle = new Vehicle(); _vehicle.Run("汽車"); _vehicle.Run("飛機"); _vehicle.Run("輪船"); // 交通工具類 class Vehicle { public void Run(string vehicle) { Console.WriteLine($"{vehicle}在公路上執行...."); } }
Vehicle類的Run方法只管公路上的,而傳遞過來的引數除了汽車,還有飛機和輪船,難道飛機和輪船都在公路上執行嗎?顯然,這裡我們把 Vehicle類 當做三個職責來使用;
即:交通工具類Vehicle ,已經違反了 單一職責原則;
上面說了,單一職責原則 是 一個類應該只負責一個職責,那麼我們將改成下面這樣:
CarVehicle _vehicle = new CarVehicle(); _vehicle.Run("小汽車"); AirVehicle airVehicle = new AirVehicle(); airVehicle.Run("飛機"); WaterVehicle waterVehicle = new WaterVehicle(); waterVehicle.Run("輪船"); // 陸上交通工具 class CarVehicle { public void Run(string vehicle) { Console.WriteLine($"{vehicle}在公路上執行...."); } } // 水上交通工具 class WaterVehicle { public void Run(string vehicle) { Console.WriteLine($"{vehicle}在水上執行...."); } } // 天上交通工具 class AirVehicle { public void Run(string vehicle) { Console.WriteLine($"{vehicle}在天上執行...."); } }
上面程式碼,就遵守了單一職責原則;
但是這樣沒有問題嗎?有,當發生修改時,我們除了要修改每一個交通工具類,還需要修改 建立這些類的地方;
改進:
Vehicle _vehicle = new Vehicle(); _vehicle.RunAtRound("小汽車"); _vehicle.RunAtWater("輪船"); _vehicle.RunAtAir("飛機"); class Vehicle { public void RunAtRound(string vehicle) { Console.WriteLine($"{vehicle}在公路上執行...."); } public void RunAtWater(string vehicle) { Console.WriteLine($"{vehicle}在水上執行...."); } public void RunAtAir(string vehicle) { Console.WriteLine($"{vehicle}在天上執行...."); } }
上面程式碼並沒有用 類 來分解,我們只在交通工具類中添加了方法,即使這樣子,也是遵守了 單一職責原則 的,只是層面是在方法上分離了職責,而不是在類上;
補充
單一職責:
- 降低了類的複雜度,因為一個類只負責一項職責。(上面示例沒體現出來,而在大專案中尤為明顯)
- 提高類的可讀性,可維護性
- 降低變更引起的風險
- 通常情況下, 我們應當遵守單一職責原則,如果邏輯足夠簡單、類中方法數量足夠少,也是可以在程式碼級違反單一職責原則,在方法級別保持單一職責原則(上面改進的程式碼就是這種)
本章簡單吧?繼續下一個原則:介面隔離原則