单一职责原则-This is sometimes hard to see

简介: 单一职责原则(Single Responsibility Principle,简称SRP),指的是不要存在一个以上导致类变更的原因。There should never be more than one reason for a class to change.

简介

单一职责原则(Single Responsibility Principle,简称SRP),指的是不要存在一个以上导致类变更的原因。

There should never be more than one reason for a class to change.

单一职责原则的优点

  1. 类的复杂性降低,清晰定义类的职责
  2. 可读性提高、复杂性降低
  3. 可维护性高
  4. 有效降低变更的风险;如果一个接口的单一职责做的好,一个接口修改只对响应的实现类有影响,对其他的接口无影响,这样会大大降低变更的风险

单一职责原则使用场景

  1. 模块
  2. 接口、类
  3. 方法

单一职责原则解决实际问题

使用场景

做过项目的人都接触过项目中的人员和资源权限问题,基本上都是采用RBAC模型(Role-Based Acess Control)基于角色的访问控制,通过分配和取消角色来完成用户权限的授予和取消,是的用户(动作主体)和权限(资源的行为)分离。

此时我们需要定义一个用户接口IUserInfo,假如我们将用户管理、修改用户信息、角色管理等信息都封装到这个接口当中。那么此时的接口定义将会如下所示:

public interface IUserInfo {


   /**

    * 用户属性相关

    */

   void setPassword(String password);

   String getPassword();

   void setUserName(String userName);

   String getUserName();

   void setAddress(String address);

   String getAddress();

   

   /**

    * 用户行为相关

    */

   boolean changePassword(String oldPassword, String newPassword);

   boolean deleteUser(String userId);

   boolean addOrg(IUserBo userBo, int orgId);

   boolean addRole(IUserBo userBo, int roleId);

   

}


此时的用户信息维护类图如下所示:

这里有一个非常明显的缺点就是,我们将用户的基本属性处理和用户的行为处理放到了一个接口中维护,这样直接导致将用户的基本属性或者用户的行为发生变更的时候,都会导致我们的IUserInfo接口和UserInfo实现类都会发生改变,这种设计不仅增大了系统的耦合度也给项目维护带来了更高的维护成本,是非常不可取的。

解决办法

我们将IUserInfo接口抽象为两个接口,分别是用户属性相关接口IUserBO,行为相关接口IUserBiz,修改后的代码如下所示:

IUserBO接口定义

/**

* <p>

*      用户属性相关(Business Object)

* </p>

*

* @Author: Liziba

* @Date: 2021/6/20 11:11

*/

public interface IUserBO {


   void setPassword(String password);

   String getPassword();

   void setUserName(String userName);

   String getUserName();

   void setAddress(String address);

   String getAddress();


}

IUserBiz接口定义

/**

* <p>

*      用户行为相关

* </p>

*

* @Author: Liziba

* @Date: 2021/6/20 11:26

*/

public interface IUserBiz {


   boolean changePassword(String oldPassword, String newPassword);

   boolean deleteUser(String userId);

   boolean addOrg(int orgId);

   boolean addRole(int roleId);


}

IUserInfo接口定义

public interface IUserInfo extends IUserBiz, IUserBO{


   /**

    * 用户属性相关

    */

   void setPassword(String password);

   String getPassword();

   void setUserName(String userName);

   String getUserName();

   void setAddress(String address);

   String getAddress();


   /**

    * 用户行为相关

    */

   boolean changePassword(String oldPassword, String newPassword);

   boolean deleteUser(String userId);

   boolean addOrg(int orgId);

   boolean addRole(int roleId);


}


此时的用户信息维护类图如下所示:

此时的UserInfo对象,既可以当做IUserBiz对象,也可以当做IUserBO对象,因为UserInfo分别实现了IUserBiz接口和IUserBO接口。此时的IUserBiz接口和IUserBO接口是满足单一职责原则的,因为他们分别负责的是用户属性相关和用户行为相关的职责,并不相互耦合交叉。

修改前和修改后的调用方式

修改前

IUserInfo userInfo = new UserInfo();

userInfo.setAddress("中国广东深圳");

userInfo.deleteUser("10000000001");

修改后

IUserInfo userInfo = new UserInfo();

IUserBO userBO = (IUserBO)userInfo;

userBO.setAddress("中国广东深圳");


IUserBiz userBiz = (IUserBiz)userInfo;

userBiz.deleteUser("10000000001");


单一职责原则总结

单一职责原则不仅仅适用于接口,对于类、方法乃至包或者模块都应该遵守单一职责原则的设计,如果设计完全不吻合单一职责原则,不仅会给后续开发和维护带来高额成本也非常不利于开发本人对于系统设计和架构思维方式的提升。我们在开发一个项目不仅仅是一个的事情,尽量要往多一步多一版本思考,不能只快乐自己而给他人埋下太多定时炸弹。但是话又说回来,要想做到一个系统或者一个模块中的全部接口、类和方法完全符合单一职责原则,这基本上也是不可能的事情,大多数情况下,单一职责原则的设计会导致接口、类和方法的剧增,此时我们在设计的时候就应该多方面的去考虑了;总之,我们最少要做到一个接口只搞一件事,也就是建议接口一定要做到单一职责原则设计,而其他的也尽量要往这方面靠。

目录
相关文章
|
机器学习/深度学习 人工智能 项目管理
【机器学习】集成学习——Stacking模型融合(理论+图解)
【机器学习】集成学习——Stacking模型融合(理论+图解)
6066 1
【机器学习】集成学习——Stacking模型融合(理论+图解)
|
分布式数据库 Hbase 存储
带你读《HBase原理与实践》之一:HBase概述
Apache HBase是基于Apache Hadoop构建的一个高可用、高性能、多版本的分布式NoSQL数据库,是Google BigTable的开源实现,通过在廉价服务器上搭建大规模结构化存储集群,提供海量数据高性能的随机读写能力。
|
9月前
|
存储 算法 Java
G1原理—1.G1回收器的分区机制
本文深入探讨了G1垃圾回收器的多个核心概念与实现细节,包括分区(Region)管理、新生代动态扩展机制以及停顿预测模型。首先分析了G1中Region大小的计算规则及其对性能的影响,强调Region大小需为2的幂次以优化内存分配效率并避免碎片化。其次介绍了新生代内存分配方式及动态扩展流程,通过自由分区列表调整新生代大小以平衡GC时间和程序运行时间。最后重点解析了基于衰减算法的停顿预测模型,该模型利用历史GC数据加权平均来精准预测每次GC所需时间,从而确保满足用户设定的停顿时间目标。这些机制共同作用,使G1能够在大内存场景下实现高效垃圾回收与低延迟表现。
406 10
G1原理—1.G1回收器的分区机制
|
12月前
|
机器学习/深度学习 人工智能 边缘计算
24/7全时守护:AI视频监控技术的深度实现与应用分享
本文深入解析了AI视频监控系统在车间安全领域的技术实现与应用,涵盖多源数据接入、边缘计算、深度学习驱动的智能分析及高效预警机制,通过具体案例展示了系统的实时性、高精度和易部署特性,为工业安全管理提供了新路径。
2955 7
|
存储 消息中间件 缓存
|
SQL 存储 JSON
Flink+Paimon+Hologres 构建实时湖仓数据分析
本文整理自阿里云高级专家喻良,在 Flink Forward Asia 2023 主会场的分享。
72514 8
Flink+Paimon+Hologres 构建实时湖仓数据分析
|
存储 SQL 分布式计算
|
监控 算法 Java
JVM 调优之 glibc 引发的内存泄露
Pmap 提供了进程的内存映射,pmap 命令用于显示一个或多个进程的内存状态。其报告进程的地址空间和内存状态信息
JVM 调优之 glibc 引发的内存泄露
|
Java Python Windows
Python pip 源设置成国内源,阿里云源,清华大学源,最方便的方式,都在这里了
Python pip 源设置成国内源,阿里云源,清华大学源,最方便的方式,都在这里了
79964 1

热门文章

最新文章