六大设计原则------单一职责原则

单一职责原则

单一职责原则 Single Responsibility Principle 简称SRP

什么是类的单一职责原则:

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

(应该有且仅有一个原因引起类的变更)

例子:

通常企业级项目都会设计到权限控制模块,而权限控制模块又会涉及到用户、权限、角色这三个部分。

而针对这三个部分,基本上使用的是RBAC模型(Role-Based Access Control),也就是基于角色的访问控制。

通过分配和取消角色来控制用户的权限,使用户和权限分离。

那么针对用户模块,我们需要对用户进行管理、修改用户信息、增加角色、修改角色等操作,那么我们先来看把上述这些操作都写在同一个接口(类)中,是什么情况。

用户信息维护类图:

这里写图片描述

上述类图设计不合理的地方:

用户的属性和用户的行为没有分开。

理由:

用户的属性和行为都能够改变User类,违背了单一职责原则。

改进方案:

把用户的信息抽取成一个BO(Business Object,业务对象),把用户的行为抽取成一个Biz(Business Logic,业务逻辑)。

职责划分后的类图:

这里写图片描述

示例代码:

User user = new UserImpl();
UserBo userBo = (UserBo)user;
//赋值
userBo.setPassword(“abc”);
//行为
UserBiz userBiz = (UserBiz)new UserBiz();
userBiz.deleteUser();

在实际运用上,我们更倾向于使用两个不同的类和接口:

项目中经常采用的SRP类图

这里写图片描述

第二个例子:

模拟电话通话的业务:

电话通话的时候有4个动作发生: 拨号、通话、回应、挂机

那么根据这些动作,我们写一个电话接口:

Public interface Phone {

//拨通电话
public void dial(String phoneNumber);

//通话
public void chat(Object o);

//通话完毕,挂电话
public void hangup();

}

通常情况下,我们都会这么设计接口,但是这个接口有缺陷:

这个接口负责了两个职责:

1、协议管理(拨通电话、挂电话)
2、数据传送(通话)

所以,会有两个原因导致这个接口或实现类影响变化,一个是协议管理的变化,一个是数据传送的变化(因为上网也会传送数据),所以这个接口违背了单一职责原则。

处理:拆分成两个接口

这里写图片描述

上述这个类图,完全满足了单一职责原则的要求,每个接口职责分明,结构清晰.

但是也有缺陷:

一个手机类(Phone)要把ConnectionManager和DataTransfer组合在一块才能使用。而组合是一种强耦合关系,你和我有共同的生命周期,这样的强耦合关系还不如使用接口实现的方式,而且还增加了类的复杂性,多了两个类。

再次修改类图:

这里写图片描述

分析一下这个类图:

1、一个类实现了两个接口,把两个职责融合在一个类中。这样做虽然Phone有两个原因引起变化,但是我们是面向接口编程,我们对外公布的是接口而不是实现类。


总结:

单一职责原则的好处:

1、类的复杂性降低,实现什么职责都有清晰明确的定义

2、可读性提高,复杂性降低

3、可维护性提高,可读性提高

4、变更引起的风险降低


单一职责适用于接口、类,同时也适用于方法,也就是说,一个方法尽可能做一件事情。


但是单一职责原则很难在项目中得到体现,因为在项目中需要考虑环境,考虑工作量,考虑人员的技术水平,考虑硬件的资源情况,等等。最终的结果往往违背单一职责原则。所以,在项目中,我们要尽量做到单一职责原则。

猜你喜欢

转载自blog.csdn.net/zxzzxzzxz123/article/details/78283792