concept
There should never be more than one reason for a class to change.
引起一個類發生變化的原因有且僅有一個
analyse
- 不要讓一個類承載過多的功能點,如果一個類擁有多余一個的功能點,就等同于把這些職責耦合在一起,對于其中某一個職責的修改可能可能會削弱或者抑制這個類完成其他職責的能力
- 類的職責主要包括兩個方面:數據職責和行為職責
》數據職責通過其屬性來體現,
》行為職責通過其方法來體現- 符合單一職責原則的類中,每一個職責都是中心,當需求發生變動時,只需要修改相應的類,就能做出相應的調整
example
統計一個文本文件里面有少個英文單詞
》反例
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;
}
假設,此時需求調整為統計文本中的中文字符數量,那么上述方法已經不適用該需求,需要重寫上述方法,這樣會大大降低開發效率。而且與【高內聚,低耦合】的思想背道而馳。
所以,根據SRP對上述代碼進行優化
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(" ");
}
/**
* 計算字符總數,并輸出單詞以及詞頻
* @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;
}
根據職責對 方法/類/框架 進行劃分,能夠提高一個程序的可擴展性,同時降低了代碼的耦合
單一職責原則可以看做是低耦合、高內聚在面向對象原則上的引申,將職責定義為引起變化的原因,以提高內聚性來減少引起變化的原因。
職責過多,可能引起它變化的原因就越多,這將導致職責依賴,相互之間就產生影響,從而大大損傷其內聚性和耦合度。