There should never be more than one reason for a class to change.
什么意思呢?
所謂單一職責(zé)原則就是一個(gè)類只負(fù)責(zé)一個(gè)職責(zé),只有一個(gè)引起變化的原因。
如果一個(gè)類承擔(dān)的職責(zé)過多,就等于把這些職責(zé)耦合在一起,一個(gè)職責(zé)的變化會(huì)削弱或抑制這個(gè)類完成其他職責(zé)的能力,這個(gè)耦合會(huì)脆弱的設(shè)計(jì)。
軟件設(shè)計(jì)真正要做的許多內(nèi)容,就是發(fā)現(xiàn)職責(zé)并把這些職責(zé)相互分離;如果能夠想到多于一個(gè)動(dòng)機(jī)去改變一個(gè)類,那么這個(gè)類就具有多于一個(gè)職責(zé),就應(yīng)該考慮類的分離。
以調(diào)制解調(diào)器為例如下圖:
從上述類圖里面我們發(fā)現(xiàn)有四個(gè)方法Dial(撥通電話),Hangup(掛電話),Receive(收到信息),Send(發(fā)送信息),經(jīng)過分析不難判斷出,實(shí)際上Dial(撥通電話)和Hangup(掛電話)是屬于連接的范疇,而Receive(收到信息)和Send(發(fā)送信息)是屬于數(shù)據(jù)傳送的范疇。這里類包括兩個(gè)職責(zé),顯然違反了SRP。
這樣做有潛在的隱患,如果要改變連接的方式,勢必要修改Modem,而修改Modem類的結(jié)果導(dǎo)致凡事依賴Modem類可能都需要修改,這樣就需要重新編譯和部署,不管數(shù)據(jù)傳輸這部分是否需要修改。
因此要重構(gòu)Modem類,從中抽象出兩個(gè)接口,一個(gè)專門負(fù)責(zé)連接,另一個(gè)專門負(fù)責(zé)數(shù)據(jù)傳送。依賴Modem類的元素要做相應(yīng)的細(xì)化,根據(jù)職責(zé)的不同分別依賴不同的接口。如下圖:
這樣以來,無論單獨(dú)修改連接部分還是單獨(dú)修改數(shù)據(jù)傳送部分,都彼此互不影響。
總結(jié)單一職責(zé)優(yōu)點(diǎn):
降低類的復(fù)雜性,
提高可維護(hù)性
提高可讀性。
降低需求變化帶來的風(fēng)險(xiǎn)。需求變化是不可避免的,如果單一職責(zé)做的好,一個(gè)接口修改只對相應(yīng)的實(shí)現(xiàn)類有影響,對其它的接口無影響,這對系統(tǒng)的擴(kuò)展性和維護(hù)性都有很大的幫助。
聯(lián)系客服