单一职责原则-敲代码你不能只自己爽,大家爽才是真的爽

Posted 李子捌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单一职责原则-敲代码你不能只自己爽,大家爽才是真的爽相关的知识,希望对你有一定的参考价值。

有经典,有干货,微信搜索【李子捌】关注这个每日更新的程序员


简介

单一职责原则(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");

单一职责原则总结

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



有经典,有干货,微信搜索【李子捌】关注这个每日更新的程序员。

在这里插入图片描述

以上是关于单一职责原则-敲代码你不能只自己爽,大家爽才是真的爽的主要内容,如果未能解决你的问题,请参考以下文章

如何定义一个类——单一职责原则

设计模式-单一职责原则

设计模式之单一职责原则(SRP)

面向对象设计原则一:单一职责原则(SRP)

深入浅出设计模式——单一职责原则

面向对象设计七大原则