Singleton  (獨身模式或叫單例模式):確保一個類只有一個實例,並提供對該實例的全局訪問。

I. 單一職責原則
1. 簡介
單一職責原則(Single Responsibility Principle,SRP)其定義為:應該且僅有一個原因引起類別的變更。假設我們設計一個業務角色存取控制的模型,傳統上我們將增加用戶、用戶管理等功能都寫入同一個介面中,如圖1-1。這樣的設計方式會一團糟,不易於維護。我們應該把用戶的屬性與行為分開,將用戶資訊抽取成一個業務物件(Business Object,BO),把行為抽取成業務邏輯(Business Logic,Biz),按照這個思路就可以將類別圖修正為圖1-2。利用介面導向就可以依需求全部實做,或是只當其中單一功能,UserInfo要獲得用戶資訊,就當作IUserBO的實做類別,若希望能操作用戶行為,就當作IUserBiz的實做類別及可。


圖 1-1 傳統用戶資訊維護類別圖

圖 1-2 職責劃分後的類別圖

2. 單一職責原則的好處
單一職責原則提出了一個程式設計的標準,用“職責”或“變化原因”來衡量介面或類別設計是否優良,但是這些都是不可度量的,會因專案而異,因環境而異。單一職責原則好處如下:
 類別的複雜度降低:實現什麼職責都有清晰明確的定義。
 可讀性提升:複雜度降低可提升可讀性。
 可維護性提升:複雜度降低易於維護。
 變更引起的風險降低:修改介面只會影響相應有實做的類別,降低改錯風險。

3. 實踐原則
對於介面,很容易就可以做到單一職責。但是對於類別實做就得多方面考慮,生搬硬套單一職責類別可能會造成類別數量劇增,過度細分則會增加系統維護的複雜性,因此可以靈活運用。單一職責也適用於方法,一個方法盡可能只做一件事情,譬如定義一個修改用戶密碼方法,就別把此方法合併到修改用戶資訊方法中,簡而言之,單一職責方法清晰明確,可以避免別人還要猜測方法的邏輯,維護較為容易。對於單一職責原則,建議為介面一定要做到單一職責原則,類別的設計則盡量做到只有一個原因引起的變化,方法則盡可能只做一件事情

 

 

 

學習設計模式,自然會涉及面向對象的設計原則,面向對象的設計原則一般包括五個原則,下面詳細介紹下五個原則:

 

1、單一職責原則( single responsibility principle )

 

      There should never be more than one reason for a class to change.

 

      所謂單一職責原則,就是對一個類而言,應該僅有一個引起它變化的原因。換句話說,一個類的功能要單一,只做與它相關的事情。在類的設計過程中要按職責進行設計,彼此保持正交,互不干涉。

 

什麼是職責?

 

      在SRP 中,職責定義為“變化的原因”。如果你能夠想到多於一個的動機去改變一個類,那麼該類就具有多於一個的職責。

 

為什麼要採用單一職責原則?

 

      因為每一個職責都是變化的一個軸線,當需求變化時,該變化會反映為類的職責的變化。如果一個類承擔了多於一個的職責,那麼就意味著引起它的變化的原因會有多個。如果一個類承擔的職責過多,那麼就等同於把這些職責耦合在了一起。一個職責的變化可能會抑製到該類完成其他職責的能力,這樣的耦合會導致脆弱的設計。當變化發生時,設計會受到意想不到的破壞。單一職責原則正是實現高內聚低耦合需要遵守的一個原則。

 

       注意:單一職責原則簡單而直觀,但在實際應用中很難實現。只有變化的軸線僅當實際發生時才具有真正的意義。如果沒有預兆,那麼去應用SRP或者其他任何的原則都是不明智的。

 

下面就Modem接口為例,說明其原則。

 

Java代碼 複製代碼 收藏代碼
  1. interface  Modem {   
  2.     public  void  dial(String pno);    //撥號  
  3.     public  void  hangup();     //掛斷  
  4.     public  void  send( char  c);    //發送數據  
  5.     public  char  recv();    //接收數據  
  6. }  

 

      大多數會認為看起來非常合理,該接口聲明的4個函數確實是調製解調器的功能。然而,該接口中卻顯示出兩個職責。第一個職責連接管理,第二個職責是數據通信。dial和hangup函數進行調製解調器的連接管理,而send和recv負責進行數據通信。這兩個職責應該被分開嗎?這依賴於應用程序變化的方式。如果應用程序的變化會影響到連接函數的簽名,那麼這個設計就是僵硬的設計,因為調用send和recv的類必須重新編譯、部署的次數會超過我們預想的情況。在這種情況下,這兩個職責必須被分離,我們分別實現這兩個職責於:

 

Java代碼 複製代碼 收藏代碼
  1. interface  DataChannel   
  2. {   
  3.     public  void  send( char  c);   
  4.     public  void  recv();   
  5. }   
  6.   
  7. interface  Connection   
  8. {   
  9.     public  void  dial(string pno);   
  10.     public  void  hangup();   
  11. }  

 

下面的類圖將它的2個不同職責分成2個​​不同的接口,這樣至少可以讓客戶端應用程序使用具有單一職責的接口:

讓ModemImplementation 實現這兩個接口。我們注意到,ModemImplementation又組合了2個職責,這不是我們希望的,但有時這又是必須的。通常由於某些原因,迫使我們不得不綁定多個職責到一個類中,但我們至少可以通過接口的分割來分離應用程序關心的概念。事實上,這個例子一個更好的設計應該是這樣的,如圖:

小結

 

Single Responsibility Principle (SRP)從職責(改變理由)的側面上為我們對類(接口)的抽象的顆粒度建立了判斷基準,在為系統設計類(接口)的時候應該保證它們的單一職責性。

 

 

 

高內聚、低耦合解釋:

 

      這是軟件工程中的概念,是判斷設計好壞的標準,主要是面向OO的設計,主要是看類的內聚性是否高,偶合度是否低
      首先要知道一個軟件是由多個子程序組裝而成,而一個程序由多個模塊(方法)構成!

“高內聚,低耦合”主要是闡述的面向對象系統中,各個類需要職責分離的思想。
      每一個類完成特定的獨立的功能,這個就是高內聚。耦合就是類之間的互相調用關係,如果耦合很強,互相牽扯調用很多,那麼會牽一發而動全身,不利於維護和擴展。

       類之間的設置應該要低耦合,但是每個類應該要高內聚.耦合是類之間相互依賴的尺度.如果每個對像都有引用其它所有的對象,那麼就有高耦合,這是不合乎要求的,因為在兩個對象之間,潛在性地流動了太多信息.低耦合是合乎要求的:它意味著對象彼此之間更獨立的工作.低耦合最小化了修改一個類而導致也要修改其它類的"連鎖反應".內聚是一個類中變量與方法連接強度的尺度.高內聚是值得要的,因為它意味著類可以更好地執行一項工作.低內聚是不好的,因為它表明類中的元素之間很少相關.成分之間相互有關聯的模塊是合乎要求的.每個方法也應該高內聚.大多數的方法只執行一個功能.不要在方法中添加'額外'的指令,這樣會導致方法執行更多的函數。
      推廣開來說,這個思想並不限於類與類之間的關係。模塊和模塊,子系統之間也都要遵守這個原則,才可以設計出延展性比較強的系統。

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 milly20423 的頭像
    milly20423

    millydream的部落格

    milly20423 發表在 痞客邦 留言(0) 人氣()