1. 程式人生 > 其它 >0x02、設計模式原則 —— 單一職責原則

0x02、設計模式原則 —— 單一職責原則

概念

對類來說的,一個類應該只負責一項職責。(記住)

假如:類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}在天上執行....");
    }
}

上面程式碼並沒有用 類 來分解,我們只在交通工具類中添加了方法,即使這樣子,也是遵守了 單一職責原則 的,只是層面是在方法上分離了職責,而不是在類上;

 

補充

單一職責:

  1. 降低了類的複雜度,因為一個類只負責一項職責。(上面示例沒體現出來,而在大專案中尤為明顯)
  2. 提高類的可讀性,可維護性
  3. 降低變更引起的風險
  4. 通常情況下, 我們應當遵守單一職責原則,如果邏輯足夠簡單、類中方法數量足夠少,也是可以在程式碼級違反單一職責原則,在方法級別保持單一職責原則(上面改進的程式碼就是這種)

 

本章簡單吧?繼續下一個原則:介面隔離原則