不要存在多于一個(gè)導(dǎo)致類變更的原因.
舉個(gè)簡(jiǎn)單的例子, 我定義了一個(gè)接口AB, 定義了兩個(gè)方法 methodA 和methodB
public interface AB {
void methodA(String a);
void methodB(String b);
}
這時(shí)我需要有一個(gè)方法需要實(shí)現(xiàn)接口A,但是因?yàn)锳B兩個(gè)接口是在一起的,所以這里我給B一個(gè)空實(shí)現(xiàn),代碼如下:
public class AImpl1 implements AB{
@Override
public void methodA(String a) {
System.out.println(a);
}
@Override
public void methodB(String b) {
return;
}
}
這時(shí)需求變化,我不得不對(duì)methodB做一些修改,比如增加一個(gè)參數(shù), 此時(shí)AImpl1這個(gè)類明明并不關(guān)心methodB卻因?yàn)锳B接口的更改而不得不隨之改動(dòng).
這時(shí)我們需要修改設(shè)計(jì), 將AB接口拆成兩個(gè)獨(dú)立的接口
public interface A {
void methodA(String a);
}
public interface B {
void methodA(String a);
}
這時(shí)A的實(shí)現(xiàn)類只需實(shí)現(xiàn)A接口即可
public class AImpl2 implements A{
@Override
public void methodA(String a){
System.out.println(a);
}
}
此時(shí)如果B接口有改動(dòng),那么只需修改實(shí)現(xiàn)了B接口的類即可,AImpl2 類不受影響, 即只存在一個(gè)導(dǎo)致類AImpl2 更改的原因
類的單一職責(zé), 貼個(gè)別人的代碼示例幫助理解
https://blog.csdn.net/zhengzhb/article/details/7278174
另外做一點(diǎn)補(bǔ)充, 單一職責(zé)原理不僅僅是一個(gè)類或接口應(yīng)該承擔(dān)盡量少的職責(zé), 函數(shù)也是, 我們?cè)诠ぷ髦型ǔ?huì)對(duì)一些業(yè)務(wù)邏輯做一些封裝來讓代碼的邏輯看起來清晰一點(diǎn), 當(dāng)封裝到函數(shù)中業(yè)務(wù)邏輯發(fā)生變化時(shí), 比如需要對(duì)一些特殊的值或場(chǎng)景做一些額外的處理, 比較簡(jiǎn)便的做法是直接 if else即可, 但更推薦遵循單一職責(zé)原理, 把不同的業(yè)務(wù)邏輯封裝到不同的方法中, 這樣代碼會(huì)更清晰, 代碼也更易維護(hù)一些
比如我們經(jīng)常遇到這種情況, 參數(shù)中傳入一個(gè)boolean值根據(jù)是否為真執(zhí)行不同的邏輯, 這時(shí)代碼的可讀性就不太好,從方法名無法明確知道方法的職責(zé), 因?yàn)榉椒鶕?jù)不同的邏輯承擔(dān)了兩種責(zé)任
public void doSth(Object obj, boolean flag){
if(flag){
// TODO ...
}else {
// TODO ...
}
}
建議改寫為
public void doSth1(Object obj){
// TODO ...
}
public void doSth2(Object obj){
// TODO ...
}
這樣每個(gè)函數(shù)承擔(dān)各自的職責(zé),邏輯判斷交給上層, 這樣邏輯會(huì)更加清晰, 如果將來邏輯發(fā)生變更我們只需要更改變更的那個(gè)函數(shù)的即可,不會(huì)對(duì)另一個(gè)函數(shù)的代碼造成影響
優(yōu)點(diǎn)
- 降低類的復(fù)雜度,提高可讀性
- 提高系統(tǒng)可維護(hù)性,降低變更引起的風(fēng)險(xiǎn)