1. 程式人生 > >設計模式學習筆記(二) 設計基本原則之【單一職責原則】

設計模式學習筆記(二) 設計基本原則之【單一職責原則】

code 分享 開發者 實際應用 需要 ret ext file類 tor

單一職責原則(SRP: Single Responsibility Principle)

名詞解釋:

1) 職責:是指類變化的原因。

2) 職責擴散:就是因為某種原因,職責P被分化為粒度更細的職責P1和P2。

3) 可變類:是指創建該類的實例後,可以對其屬性進行修改。

4)不可變類:是指創建該類的實例後,不可對其屬性進行修改。不可變類是線程安全的。

1、應用場景

一個類T負責兩個不同的職責:職責P1、職責P2。當由於職責P1需求發生改變而需要修改類T時,有可能會導致原來運行的職責P2功能發生故障。

2、解決方案

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

3、優點

  • 可以降低類的復雜度,一個類只負責一項職責,其邏輯肯定要比負責多項職責簡單的多。

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

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

  • 提供重用基礎:代碼塊獨立,功能單一,可以容易地重用。

  • 提供可擴展性 :依賴別的單元提供的接口,便於擴展。

4、缺點

如果嚴格的遵循單一職責原則,即所有的類均只負責一項職責,開發者面對的將是巨量的類(類的爆炸),如果沒有一個清晰的類管理方法,勢必降低系統的可讀性和可維護性。

我們不可能針對每個類都設計原子級的職責。那麽就會牽涉到職責的組合和劃分,我們很難建立一個標準來界定如何對職責進行合理的劃分。職責的大小怎麽定義是個難題,什麽樣的職責放在一起是好的內聚也不好定義。

實際項目應用中很少能夠實現單一職責原則,必須考慮可變因素與不可變因素的影響和開發效率的問題。

5、實踐及示例

一般來說,接口的設計需嚴格遵守單一職責原則。如下圖說所示,我們定義一個文件操作的接口,實現文件的基本操作

技術分享

代碼如下:

技術分享
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Text;
 4 
 5 namespace LoadBalan
 6 {
 7      public  interface IFileOperator
 8     {        
 9         void Open(string
fileName); 10 void Write(string fileName,byte[] fileData); 11 byte[] Read(); 12 void Save(string fileName); 13 void Close(string fileName); 14 } 15 16 class DisplayFile : IFileOperator 17 { 18 public void Open(string fileName) 19 { 20 21 } 22 23 public void Write(string fileName, byte[] fileData) 24 { 25 } 26 public byte[] Read() { 27 28 return null ; 29 } 30 public void Save(string fileName) 31 { 32 33 } 34 public void Close(string fileName) 35 { 36 37 } 38 } 39 class SaveFile : IFileOperator 40 { 41 public void Open(string fileName) 42 { 43 44 } 45 46 public void Write(string fileName, byte[] fileData) 47 { 48 } 49 public byte[] Read() 50 { 51 52 return null; 53 } 54 public void Save(string fileName) 55 { 56 57 } 58 public void Close(string fileName) 59 { 60 61 } 62 } 63 }
View Code

我們可以看到,IFileOperator接口包含了一系列的操作,而我們的DisplayFile類和SaveFile類都只是用到其中一部分操作,但都要實現該接口中所有的操作,造成大量的代碼冗余,也影響程序的可讀性。根據單一職責原則,我們做如下改進:

技術分享

代碼如下(設計不一定合理,只是為了說明單一職責原則):

技術分享
using System;
using System.Collections.Generic;
using System.Text;

namespace LoadBalan
{
    class Lesson_SRP02
    {
        public interface IFileOperator
        {
            void Open(string fileName);           
            void Close(string fileName);
        }
        public interface IFileRead
        {    
            byte[] Read();         
        }
        public interface IFileSave
        {
           
            void Write(string fileName, byte[] fileData);           
            void Save(string fileName);
       
        }

        class DisplayFile : IFileOperator,IFileRead
        {
            public void Open(string fileName)
            {

            }
        
            public byte[] Read()
            {

                return null;
            }
           
            public void Close(string fileName)
            {

            }
        }
        class SaveFile : IFileOperator
        {
            public void Open(string fileName)
            {

            }

            public void Write(string fileName, byte[] fileData)
            {
            }
            
            public void Save(string fileName)
            {

            }
            public void Close(string fileName)
            {

            }
        }
    }
}
View Code

這樣,DisplayFile類與SaveFile類裏就沒有冗余代碼,各自只實現自己所需的功能。

設計模式學習筆記(二) 設計基本原則之【單一職責原則】