單一職責(zé)原則
There should never be more than one reason for a class to change.
分析
電話通話的時(shí)候有四個(gè)過程發(fā)生:撥號(hào)、通話、回應(yīng)、掛機(jī)邻奠,如下所示:
下面是具體代碼實(shí)現(xiàn):
/**
* 類描述:
*
* @author:tangniannian
* @date:2016/12/5
* @修改描述:
* @modifier ${tags}
*/
public interface IPhone {
void dial(String phoneNum);
void chat(Object o);
void hangup();
}
上面的代碼看起來沒有問題,但是單一職責(zé)原則要求一個(gè)接口或者類只有一個(gè)原因引起變化为居,也就是說一個(gè)接口或者類只有一個(gè)職責(zé)碌宴,它就負(fù)責(zé)一件事,上面的接口顯然并不是只負(fù)責(zé)一件事情蒙畴。
IPone這個(gè)接口可不只是有一個(gè)職責(zé)贰镣,它包含了兩個(gè)職責(zé):一個(gè)是協(xié)議管理,一個(gè)是數(shù)據(jù)送達(dá)膳凝。dial()和hangup()兩個(gè)方法實(shí)現(xiàn)的是協(xié)議管理碑隆,分別負(fù)責(zé)撥號(hào)和掛機(jī);chat()是實(shí)現(xiàn)數(shù)據(jù)送達(dá)蹬音。
下面分析上面存在的問題上煤。第一,協(xié)議變化顯然會(huì)造成接口或者類引起變化著淆;第二劫狠,數(shù)據(jù)傳送也會(huì)造成接口或者類引起變化。
分析發(fā)現(xiàn)永部,上面的接口包含了兩個(gè)職責(zé)独泞,而且兩個(gè)職責(zé)互不影響,所以考慮拆分為兩個(gè)接口苔埋。如下圖所示:
// 代碼描述
public interface IDataTransfer {
void chat(IConnectionManager iConnectionManager);
}
public interface IConnectionManager {
void dial(String phoneNum);
void hangup();
}
/**
* 類描述:電話具有撥打電話懦砂、掛斷電話、通話的功能
*
* @修改描述:
* @modifier ${tags}
*/
public class Phone implements IConnectionManager, IDataTransfer{
public void dial(String phoneNum) {
}
public void hangup() {
}
public void chat(IConnectionManager iConnectionManager) {
}
}
總結(jié) 單一職責(zé)原則優(yōu)點(diǎn)
- 類的復(fù)雜性降低组橄,實(shí)現(xiàn)什么職責(zé)都有清晰明確的定義荞膘;
- 可讀性提高,復(fù)雜性降低晨炕,那當(dāng)然可讀性提高了衫画;
- 可維護(hù)性提高,可讀性提高瓮栗,那當(dāng)然更容易維護(hù)了削罩;
- 變更引起的風(fēng)險(xiǎn)降低,變更是必不可少的费奸,如果接口的單一職責(zé)做得好弥激,一個(gè)接口修改只對(duì)相應(yīng)的實(shí)現(xiàn)類有影響,對(duì)其他的接口無影響愿阐,這對(duì)系統(tǒng)的擴(kuò)展性微服、維護(hù)性都有非常大的幫助。
分析
對(duì)于接口缨历,我們?cè)谠O(shè)計(jì)的時(shí)候一定要做到單一以蕴,但是對(duì)于實(shí)現(xiàn)類就需要多方面考慮了糙麦。生搬硬套單一職責(zé)原則會(huì)引起類的劇增,給維護(hù)帶來非常多的麻煩丛肮,而且過分細(xì)分類的職責(zé)也會(huì)人為地增加系統(tǒng)的復(fù)雜性赡磅。本來一個(gè)類可以實(shí)現(xiàn)的行為硬要拆成兩個(gè)類,然后再使用聚合或組合的方式耦合在一起宝与,人為制造了系統(tǒng)的復(fù)雜性焚廊。