設計模式六大原則(一):單一職責原則


單一職責原則定義是:不要存在多於一個導致類變更的原因。通俗地說,即一個類只負責一項職責。

單一職責原則針對的問題

有一個類T負責兩個不同的職責:職責P1和職責P2。當因為職責P1的需求發生改變而需要修改類T的時候,有可能會導致原本運行正常的職責P2功能發生故障。

單一職責原則的解決方案

遵循單一職責原則,分別建立兩個類T1、T2,使T1完成職責P1功能,T2完成職責P2功能。這樣,當修改類T1的時候,不會使職責P2發生故障風險。同理,當修改T2的時候,也不會使職責P1發生故障風險。

單一職責原則的認識

說到單一職責原則,很多人都會不屑一顧,因為它太簡單了。稍有經驗的程序員即使從來沒有讀過設計模式,從來沒有聽說過單一職責原則,在設計軟件的時候也會自覺遵守這個重要原則,因為這是一個常識。在軟件編程中,誰也不希望因為修改了一個功能導致其他的功能發生故障。而避免出現這一問題的方法便是遵循單一職責原則。雖然單一職責原則如此簡單,並且被認為是常識,但是即使是經驗豐富的程序員寫出的程序也會有違背這一設計原則的代碼存在。這是職責擴散導致的。所謂的職責擴散,指的就是因為某種原因,職責P1被分化為粒度更細的職責P1和P2。

比如說,類T只負責一個職責P,這樣設計是符合單一職責原則的。后來由於某種原因,或許是需求變更了,又或許是程序的設計者境界提高了,需要將職責P細分為粒度更細的職責P1和P2。這時候,如果要使程序遵循單一職責原則,就需要將類T也分解為兩個類T1和T2,分別去負責P1和P2兩個職責。但是在程序已經寫好的情況下這樣做,十分浪費時間和精力。所以,簡單地修改類T,用它來負責兩個職責是一個比較不錯的選擇,雖然這樣做會有悖於單一職責原則。

適當地違背單一職責原則有時候反而能提高開發效率,因此設計原則還是要按照實際需求來選擇使用的。

單一職責原則的案例

用一個類來描述程序員編寫代碼這個場景。

public class AnimalTest {
    public static void main(String[] args) {
        Programmer programmer = new Programmer();
        programmer.program("靜靜"); // 靜靜使用IDEA編寫代碼。
        programmer.program("標標"); // 標標使用IDEA編寫代碼。
    }
}

class Programmer {
    void program(String programmer) {
        System.out.println(programmer + "使用IDEA編寫代碼。");
    }
}

在工作中發現,並不是所有的程序員都使用IDEA編寫代碼的,有的程序員喜歡用Eclipse,有的程序員喜歡用記事本。那么,這時候如果要遵循單一原則,就需要將Programmer類細分為野生程序員EclipseProgrammer和大佬程序員BossProgrammer。

public class AnimalTest {
    public static void main(String[] args) {
        BossProgrammer bossProgrammer = new BossProgrammer();
        bossProgrammer.program("飄飄"); // 飄飄使用記事本編寫代碼。
        EclipseProgrammer eclipseProgrammer = new EclipseProgrammer();
        eclipseProgrammer.program("毛毛"); // 毛毛使用Eclipse編寫代碼。
    }
}

class BossProgrammer {
    void program(String programmer) {
        System.out.println(programmer + "使用記事本編寫代碼。");
    }
}

class EclipseProgrammer {
    void program(String programmer) {
        System.out.println(programmer + "使用Eclipse編寫代碼。");
    }
}

我們會發現這樣修改的花銷很大,因為處理要將原來的類(被調用方)分解成多個類之外,還要修改調用方的代碼。這時候適當地違反單一職責原則,即在Programmer類中的program方法中使用條件分支的形式(使用程序員名硬編碼)就會簡單很多,只需要修改Programmer類(被調用方)即可,不需要修改調用方的代碼。當然了,因為用的是硬編碼,會導致很多時候條件判斷失敗,比如說程序員燦燦就不知道該用什么IDE去編寫代碼了。

上面的例子是個簡單的例子(只有一個方法),實際應用中的類要比這復雜得多。一旦發生職責擴散而需要修改類的時候,除非這個類本身非常簡單,否則還是遵循單一職責原則比較好。

單一職責原則的優點

1.降低類的復雜度,一個類只負責一個職責。這樣寫出來的代碼邏輯肯定要比負責多項職責簡單得多。

2.提高類的可讀性,提高系統的可維護性。

3.降低變更引起的風險。變更是必然的,如果單一職責原則遵守得好,當修改一個功能的時候可以顯著降低對其他功能的影響。

需要說明的一點是,單一職責原則不只是面向對象編程思想所特有的,只要是模塊化的程序設計,都適用單一職責原則。比如說單一職責原則不僅僅適用於類,還適用於方法。

 

"做一個有溫度的人。"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM