使用单一职责原则解决实际问题
本节介绍如何使用单一职责原则解决问题。
例如,在 新宝库中,用户分为普通用户和VIP用户。普通用户不能阅读学习收费文章,VIP用户可以任意反复阅读,功能职责不一样。
首先创建用户类 User。
下面我们对职责进行分离解耦,分别创建 CommonUser 和 VipUser。
CommonUser 类的代码如下。
设计一个顶层接口 Course。
CourseInfo 接口的代码如下。
下面来看方法层面的单一职责设计。有时候,我们通常会把一个方法写成下面这样。
例如,在 新宝库中,用户分为普通用户和VIP用户。普通用户不能阅读学习收费文章,VIP用户可以任意反复阅读,功能职责不一样。
首先创建用户类 User。
package net.biancheng.c.srp; public class User { public void study(String userType) { if ("common".equals(userType)) { System.out.println("不能阅读收费文章"); } else { System.out.println("可以任意反复阅读收费文章"); } } }下面编写客户端测试代码,无论是普通用户还是VIP会员,都调用 study() 方法的逻辑。
public static void main(String[] args) { User user = new User(); user.study("common"); user.study("vip"); }从上面代码看,User 类承担了两种处理逻辑。假如现在对用户进行加密,那么普通用户和VIP会员的加密逻辑是不一样的,必须修改代码。而修改代码逻辑势必会相互影响,容易带来不可控的风险。
下面我们对职责进行分离解耦,分别创建 CommonUser 和 VipUser。
CommonUser 类的代码如下。
package net.biancheng.c.srp; public class CommonUser { public void study(String userType) { System.out.println(userType + "不能阅读收费文章"); } }VipUser 类的代码如下。
package net.biancheng.c.srp; public class VipUser { public void study(String userType) { System.out.println(userType + "任意阅读收费文章"); } }客户端代码如下,将普通会员的处理逻辑调用 CommonUser 类,VIP 会员的处理逻辑调用 VipUser 类。
public static void main(String[] args) { CommonUser commonUser = new CommonUser(); commonUser.study("common"); VipUser vipUser = new VipUser(); vipUser.study("vip"); }对于教程方面,我们要对教程做权限。普通学员只能获得教程的基本信息,VIP 用户可以获得阅读权限。所以在控制教程层面,至少有两个职责,我们可以把展示职责和管理职责分离开,都实现同一个抽象依赖。
设计一个顶层接口 Course。
package net.biancheng.c.srp; public interface Course { //获取教程的基本信息 String getCourseTitle(); //获得阅读权限 byte[] getReadPow(); //学习教程 void studyCourse(); //退款 void refundCourse(); }这里可以把 Course 接口拆分成两个接口,创建一个接口 CourseInfo 和 CourseManager。
CourseInfo 接口的代码如下。
package net.biancheng.c.srp; public interface CourseInfo { //获取教程的基本信息 String getCourseTitle(); //获得阅读权限 byte[] getReadPow(); }CourseManager 接口的代码如下。
package net.biancheng.c.srp; public interface CourseManager { //学习教程 void studyCourse(); //退款 void refundCourse(); }类图如下:
private void modifyUserInfo(String userName, String url) { userName = "新宝库"; url = "https://www.xinbaoku.com/"; }或者是这样。
private void modifyUserInfo(String userName, String pwd, String url) { userName = "新宝库"; pwd = "123456"; url = "https://www.xinbaoku.com/"; }显然上面两种写法的 modifyUserInfo() 方法都承担了多个职责,既可以修改 userName,也可以修改 url,甚至更多,但是这样设计明显不符合单一职责原则,我们做出如下修改,把这个方法拆成两个。
private void modifyUserName(String userName) { userName = "新宝库" } private void modifyUrl(String url) { url = "https://www.xinbaoku.com/" }代码在修改之后,开发和维护都会变得更加简单和容易。在实际项目中,代码会存在依赖、组合、聚合关系,在项目开发过程中还会受到项目的规模、周期、技术人员水平、对进度把控的影响,导致很多类都不能满足单一职责原则。但是,我们在编写代码的过程中,应尽可能地让接口和方法保持单一职责,这样对项目后期的维护是有很大帮助的。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算