单一职责原则(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";
}
修改之后,开发起来更简单,维护起来也容易。