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;
}
根据职责对 方法/类/框架 进行划分,能够提高一个程序的可扩展性,同时降低了代码的耦合
单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。
职责过多,可能引起它变化的原因就越多,这将导致职责依赖,相互之间就产生影响,从而大大损伤其内聚性和耦合度。