乙個類應該有且僅有乙個能引起它變化的原因,否則類應該被拆分。
從定義可以看出,「職責」指導致類發生變化的原因,實質上就是專案的業務需求。定義只給出了類,方法和介面同樣也可作為單一職責原則適用的物件,本文中以類作為舉例,描述內容同樣適用於方法、介面。
類對應的職責有改變的潛在區域。超過乙個職責,意味著超過乙個會發生改變的區域,會提高修改**的風險。從詞義角度出發,遵循單一職責原則似乎很簡單,只需將專案劃分為若干子模組,各自對應乙個類即可。但在程式設計實踐中,區分設計中的責任,也就是我們常說的對業務的抽象劃分能力,恰恰是最困難的環節之一。更困難的是,即使在專案初期能夠對其進行合理的功能拆分,由於無法避免出現職責擴散,原本遵循單一職責原則的軟體實體變得不再遵循。因此,遵循單一職責原則要立足於當前需求,同時考慮未來的需求擴充套件。
職責擴散:軟體需求發生變化等原因,職責p被分化為粒度更細的職責p1 和 p2.單一職責原則的核心是控制類的粒度大小,使其承擔最小的責任,具備較高的內聚性。同時,減少了修改**的可能性。
在兩種情況下,要考慮遵循單一職責原則:
以上兩種情況是對業務模型進行拆分,直至達到符合要求的粒度。一般來說,真是世界中的實體包含多想功能,譬如專案組長包含編碼功能和管理功能,在完成拆分之後,需要利用繼承或實現組合成符合業務的軟體實體。因此,遵循單一職責原則總體上分為兩步:
拆分。對職責進行分離。
組合。對職責進行組裝。
在編碼實踐上,以下角度可使**貼近單一職責原則
正如上文的討論,在設計類、介面、方法時都要遵循單一職責原則,否則應對其進行重構。
下圖是不遵循單一職責的bird類,可以看到存在明顯的if-else語句:
public
class
bird
else
}}
我們對其進行重構,以判斷條件為分界,將該類拆分為兩個類:
//類一,只包含翅膀分功能
public
class
flybird
public
void
movemode()
}//類二 ,只包含用腳走功能
public
class
footbird
public
void
movemode()
}
重構之後類圖如下所示:
同類層面類似,不遵循單一職責原則的介面如下
//介面包含了兩項功能
public
inte***ce
icourse
對上面介面進行拆分,得到兩個介面如下
//定義獲取課程名稱的規範
public
inte***ce
igetname
//定義管理課程的操作
public
inte***ce
imanagercourse
同類不同的是,實現類可以繼承多個介面,進行對功能進行組裝,如下面**
//實現兩個介面,具備兩個介面定義的功能
public
class
studycourse
implements
icourse
, imanagercourse
@override
public
void
managercourse()
}
顯然,這種方式對應的類圖如下
//將上面方法拆分為下面兩個方法
public
void
updatename
(string name)
public
void
updataage
(string age)
//存在判斷,可對其進行拆分
public
void
someaction
(boolean b)
else
}}
設計模式之單一職責原則
關於單一職責原則,我想大家都聽過不少,今天來看看這個原則具體是什麼,有哪些好處使我們需要選擇遵守它呢?一 定義 乙個類只能因為乙個原因而修改。怎麼理解呢?簡單來說,乙個類只能實現一項功能,或者換句話說,乙個類只有乙個職責,只有當這個職責發生變化,它才會被修改,說白了就是乙個類質感乙個類該幹的事。二 ...
設計模式之單一職責原則
首先就名字而言不難想象,單一必定是只能有乙個,而這個乙個指的是什麼呢,那就是乙個職責。而職責通俗易懂來說就是乙個功能,乙個類只能有乙個功能,而如果有兩個及以上的功能就不再符合單一職責原則了。就好比乙個水壺,它的功能就只是裝水,而不存放別的東西,那它就滿足了單一職責原則。優點有複雜度低,或者說簡單明瞭...
設計模式 物件導向設計原則之單一職責原則
初學者在程式設計的時候可能一開始會有這樣的經歷,使用乙個類來實現很多的功能,新新增的甚至不相關的功能都放在乙個類裡來實現,煮成了一鍋大雜燴,往往使得某個類包羅永珍,無所不能。可能剛開始實現功能比較簡單,這樣做不會引發什麼特別大的問題。但是隨著專案複雜度的提公升,各種不相關的實現 耦合在一起,一旦有功...