單一職責原則(Simple Responsibility Principle ,SRP)是指不要存在多於一個導致類變更的原因。假如有一個類負責兩個職責,一旦需求發生變更,修改其中一個職責的邏輯代碼,就有可能導致另一個職責的發生問題。如此,該類就有兩個導致類變更的原因。
解決方式:將兩個職責用兩個類來實現,進行解耦。這樣的設計在後期需求變更時,對維護互不影響,而且可以降低類的複雜度,提高類的可讀性,也提高了系統的可維護性。總的來說,就是一個類、接口、或方法只負責一項職責。
1.舉個例子,網上的一些視頻課程,有直播課程和錄播課程。直播課程不能快退和快進,而錄播課程可以反覆觀看。先創建一個 Course 類:
public class Course{
public void study(String courseName){
if("直播課".equals(courseName)){
System.out.println(courseName +"不能快進");
}else{
System.out.println(courseName +"可以反覆觀看");
}
}
}
調用一下:
public static void main(String [] args){
Course course = new Course();
course.study("直播課");
course.study("錄播課");
}
2.從上面的Course 類的代碼來看,Course 類承擔了兩種處理邏輯。假設現在要對直播和錄播課程進行加密,但這兩種課程的加密方式是不同的,因此在修改代碼的邏輯時勢必會相互影響,容易帶來不可控的風險。所以需要對這兩種職責進行解耦。分別新建兩個類:LiveCourse 和 ReplayCourse.
public class LiveCourse{
public void study(String courseName){
System.out.println(courseName +"不能快進");
}
}
public class ReplayCourse{
public void study(String courseName){
System.out.println(courseName +"可以反覆觀看");
}
}
調用一下:
public static void main(String [] args){
LiveCourse liveCourse = new LiveCourse();
liveCourse.study("直播課");
ReplayCourse replayCourse = new ReplayCourse();
replayCourse.study("錄播課");
}
3.隨着業務的發展,視頻課程觀看的人員分爲vip和普通用戶。vip可以獲取視頻流,普通用戶只能查看課程基本信息。那麼在控制課程層面至少有兩個職責,我們可以將展示職責和管理職責分離開來,都實現同一個抽象依賴,設計一個頂層接口,創建ICourse接口:
public interface ICourse{
//獲取基本信息
String getCourseNmae();
//獲取視頻流
byte[] getCourseVideo();
//學習課程
void studyCourse();
//退款
void refundCourse();
}
我們可以將這個接口分爲兩個接口:
public interface ICourseInfo{
//獲取基本信息
String getCourseNmae();
//獲取視頻流
byte[] getCourseVideo();
}
public interface ICourseManager{
//學習課程
void studyCourse();
//退款
void refundCourse();
}
4.下面來看一下方法層的單一職責設計:
private void modifyUserInfo(String userNmae,String address){
userName = "Jack";
address = "USA";
}
這個類還可以寫成這樣:
private void modifyUserInfo(String userNmae,String... fileds){
userName = "Jack";
}
private void modifyUserInfo(String userNmae,String address,boolean bool){
if(bool){
}else{
}
userName = "Jack";
address = "USA";
}
但是這樣,modifyUserInfo方法明顯承擔了多個職責,顯然不符合單一職責,來修改一下:
private void modifyUserName(String userNmae){
userName = "Jack";
}
private void modifyUserInfo(String address){
address = "USA";
}
修改之後,開發起來更簡單,維護起來也容易。