concept
There should never be more than one reason for a class to change.
引起一個類發(fā)生變化的原因有且僅有一個
analyse
- 不要讓一個類承載過多的功能點,如果一個類擁有多余一個的功能點,就等同于把這些職責(zé)耦合在一起,對于其中某一個職責(zé)的修改可能可能會削弱或者抑制這個類完成其他職責(zé)的能力
- 類的職責(zé)主要包括兩個方面:數(shù)據(jù)職責(zé)和行為職責(zé)
》數(shù)據(jù)職責(zé)通過其屬性來體現(xiàn),
》行為職責(zé)通過其方法來體現(xiàn)- 符合單一職責(zé)原則的類中,每一個職責(zé)都是中心,當(dāng)需求發(fā)生變動時,只需要修改相應(yīng)的類,就能做出相應(yīng)的調(diào)整
example
統(tǒng)計一個文本文件里面有少個英文單詞
》反例
public String singleResponsibilityPrincipleCounterexample( String filePath) throws IOException {
// 加載文件
BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(filePath)));
StringBuffer stringBuffer = new StringBuffer();
while (bufferedReader.readLine() != null) {
stringBuffer.append(bufferedReader.readLine());
stringBuffer.append(" ");
}
bufferedReader.close();
// 將文件中的單詞分割出來
String[] words = stringBuffer.toString().split("[^0-9 (0-9a-zA-Z0-9\\\\u4e00-\\\\u9fa5) \\\\()() ())($]");
Map<String, Integer> map = new HashMap<>();
for (String word : words) {
if (map.containsKey(word)) {
map.put(word, map.get(word) + 1);
} else {
map.put(word, 1);
}
}
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
StringBuffer stringBuffer = new StringBuffer();
int n = 0;
for (Map.Entry<String, Integer> entry : list) {
stringBuffer.append("[單詞:" + entry.getKey() + "------頻次" + entry.getValue() + "]");
n = n + entry.getValue();
}
return "文本中單詞共計:" + n + " " + stringBuffer;
}
假設(shè),此時需求調(diào)整為統(tǒng)計文本中的中文字符數(shù)量,那么上述方法已經(jīng)不適用該需求,需要重寫上述方法,這樣會大大降低開發(fā)效率。而且與【高內(nèi)聚,低耦合】的思想背道而馳。
所以,根據(jù)SRP對上述代碼進(jìn)行優(yōu)化
public String singleResponsibilityPrinciple() throws IOException {
String fileString = loadFile(filePath);
String filterCharacters = filterCharacters(fileString);
String[] words = getWords(fileString);
return getWordsNum(words);
}
/**
* 加載文件
* @param filePath
* @return
* @throws IOException
*/
public String loadFile(String filePath) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(filePath)));
StringBuffer stringBuffer = new StringBuffer();
while (bufferedReader.readLine() != null) {
stringBuffer.append(bufferedReader.readLine());
stringBuffer.append(" ");
}
bufferedReader.close();
return stringBuffer.toString();
}
/**
* 過濾出英文單詞
* @param fileString
* @return
*/
public String filterCharacters(String fileString) {
String regex = "[^0-9 (0-9a-zA-Z0-9\\\\u4e00-\\\\u9fa5) \\\\()() ())($]";
return fileString.replaceAll(regex, " ");
}
/**
* 得到字符中的單詞
* @param str
* @return
*/
public String[] getWords(String str) {
return str.split(" ");
}
/**
* 計算字符總數(shù),并輸出單詞以及詞頻
* @param words
* @return
*/
public String getWordsNum(String[] words) {
Map<String, Integer> map = new HashMap<>();
for (String word : words) {
if (map.containsKey(word)) {
map.put(word, map.get(word) + 1);
} else {
map.put(word, 1);
}
}
List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
StringBuffer stringBuffer = new StringBuffer();
int n = 0;
for (Map.Entry<String, Integer> entry : list) {
stringBuffer.append("[字符" + entry.getKey() + "------頻次" + entry.getValue() + "]");
n = n + entry.getValue();
}
return "文本中字符共計:" + n + " " + stringBuffer;
}
根據(jù)職責(zé)對 方法/類/框架 進(jìn)行劃分,能夠提高一個程序的可擴展性,同時降低了代碼的耦合
單一職責(zé)原則可以看做是低耦合、高內(nèi)聚在面向?qū)ο笤瓌t上的引申,將職責(zé)定義為引起變化的原因,以提高內(nèi)聚性來減少引起變化的原因。
職責(zé)過多,可能引起它變化的原因就越多,這將導(dǎo)致職責(zé)依賴,相互之間就產(chǎn)生影響,從而大大損傷其內(nèi)聚性和耦合度。