是指不要存在多于一个导致类变更的原因。
假 设我们有一个 Class 负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能会导 致 另一个职责的功能发生故障。 这样一来,这个 Class 存在两个导致类变更的原因。如何解决这个问题呢? 我们就要给两个职责分别用两个 Class 来实现,进行解耦。后期需求变更维护互不影响。这样的设计, 可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。总体来说就是一 个 Class/Interface/Method 只负责一项职责。
Demo:
课程分为直播课和录播课,直播课不能快进和 快退,录播可以可以任意的反复观看,功能职责不一样。
public class Course {
public void study(String courseName) {
if ("直播课".equals(courseName)) {
System.out.println("不能快进和 快退");
} else if ("录播课".equals(courseName)) {
System.out.println("可以反复观看");
}
}
}
// 测试类
public class MainTest {
public static void main(String[] args) {
Course course = new Course();
course.study("直播课");
course.study("录播课");
}
}
其实Course类承担了2个职责,如果现在要对课程进行加密,那么直播课和录 播课的加密逻辑都不一样,必须要修改代码。
所以要进行解耦。
public class LiveCourse {
public void study(String courseName) {
System.out.println(courseName + "不能快进快退");
}
}
public class ReplyCourse {
public void study(String courseName) {
System.out.println(courseName + "可以反复观看");
}
}
//测试类
public class MainTest {
public static void main(String[] args) {
LiveCourse liveCourse = new LiveCourse();
liveCourse.study("直播课");
ReplyCourse replyCourse = new ReplyCourse();
replyCourse.study("录播课");
}
}
业务继续发展,课程要做权限。没有付费的学员可以获取课程基本信息,已经付费的学员可以获得 视频流,即学习权限。那么对于控制课程层面上至少有两个职责。我们可以把展示职责和管理职责分离 开来,都实现同一个抽象依赖。设计一个顶层接口,
创建 ICourse 接口
public interface ICourse {
// 获取课程基本信息
String getCourseInfo();
// 获取视频流
byte[] getCourseVideo();
// 学习课程
void studyCourse();
//退款
void refundCourse();
}
上面那个接口我们可以分为2个接口
public interface ICourseInfo {
// 获取课程基本信息
String getCourseName();
// 获取视频流
byte[] getCourseVideo();
}
public interface ICourseManager {
// 学习课程
void studyCourse();
//退款
void refundCourse();
}
看下方法层面的单一职责
修改用户信息
private void modifyUserInfo(String userName,String address){
userName = "parking";
address = "beijing";
}
其实这个方法就不满足单一职责原则,要么修改用户名,要么修改地址,拆开2个方法
private void modifyUserName(String userName){
userName = "parking";
}
private void modifyAddress(String address){
address = "beijing";
}
这修改之后,开发起来简单,维护起来也容易。
但是,我们在实际开发中会项目依赖,组合,聚合 这些关系,还有还有项目的规模,周期,技术人员的水平,对进度的把控,很多类都不符合单一职责。 但是,我们在编写代码的过程,尽可能地让接口和方法保持单一职责
注意:学习设计模式要站在设计者的角度,开发者的角度不好学