單一職責原則
阿新 • • 發佈:2020-11-29
一、前言
單一職責原則是對類來說的,即一個類應該只負責一項具體的職責.如類 A 負責兩個不同職責:職責 1、職責 2.當職責 1 需求變更而改變 A 時,可能造成職責 2 執行錯誤,所以需要將類 A 的粒度分解為 A1、A2
單一職責原則注意事項和細節
1、降低類的複雜度,一個類只負責一項職責
2、提高類的可讀性,可維護性
3、降低變更引起的風險
4、通常情況下,我們應當遵守單一職責原則,只有邏輯足夠簡單,才可以在程式碼級違反單一職責原則,只有類中方法數量足夠少,可以在方法級別保持單一職責原則
二、案例分析(以交通工具執行方式為例)
1、方式一
// 測試類 public class DesignPatternPrinciple { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.run("car"); vehicle.run("railway"); vehicle.run("steamer"); vehicle.run("airplane"); } } // 交通工具類 class Vehicle{ public void run(String vehicleType){ System.out.println(vehicleType + "在地上執行..."); } } // 測試結果 car在地上執行... railway在地上執行... steamer在地上執行... airplane在地上執行...
方式一程式碼比較簡單,但是我們發現一個問題, car 、railway 在地上執行時符合我們邏輯的,但是 steamer、airplane 在地上執行,這明顯不符合我們的思維邏輯,它違反了單一職責,即一個類應該只完成一項具體的職責,而我們這裡的 Vehicle 卻完成了多項職責,所以我們嘗試著改進
2、方式二
public class DesignPatternPrinciple { public static void main(String[] args) { RoadVehicle roadVehicle = new RoadVehicle(); roadVehicle.run("railway"); SeaVehicle seaVehicle = new SeaVehicle(); seaVehicle.run("steamer"); AirVehicle airVehicle = new AirVehicle(); airVehicle.run("airplane"); } } class RoadVehicle{ public void run(String vehicleType){ System.out.println(vehicleType + "在地上執行..."); } } class SeaVehicle{ public void run(String vehicleType){ System.out.println(vehicleType + "在海上執行..."); } } class AirVehicle{ public void run(String vehicleType){ System.out.println(vehicleType + "在空中執行..."); } } // 測試結果 railway在地上執行... steamer在海上執行... airplane在空中執行...
方式二就嚴格的遵循了單一職責原則,不同型別的交通工具執行方式進行類級別的拆分,每個類只負責完成自己對應的執行方式,但是呢,這裡有一個缺點,我們這裡類的方法很少,只有一個 run 方法,但是我們需要使用的時候建立了三個類,並且呢使用不同的交通工具的時候還建立了三次物件,這樣的花銷是很大的,所以我們還可以改進
3、方式三
public class DesignPatternPrinciple { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); vehicle.runWithRoad("railway"); vehicle.runWithSea("steamer"); vehicle.runWithAir("airplane"); } } class Vehicle{ public void runWithRoad(String vehicleType){ System.out.println(vehicleType + "在地上執行..."); } public void runWithSea(String vehicleType){ System.out.println(vehicleType + "在海上執行..."); } public void runWithAir(String vehicleType){ System.out.println(vehicleType + "在空中執行..."); } } // 測試結果 railway在地上執行... steamer在海上執行... airplane在空中執行...
方式三雖然不是完全遵循單一職責原則,但是它卻是在方法級別上遵循了單一職責原則,我們之所以這樣設計是因為它這個類裡面的方法很少,如果 Vehicle 類中方法比較多的情況下還採用方式三的設計原則,就會造成Vehicle 這個類裡面的方法很多,設計上就會很臃腫,所以方法較多的情況下建議使用方式二