单一职责原则|设计原则

简介: 本文带大家学习和了解第一种设计原则,单一职责原则

前置知识

  • 有项目编写经历
  • 听说过设计模式

前言

我们经常有听过设计模式,也明白设计模式对项目和代码设计逻辑的重要性。但是你是否知道,所有的设计模式,无论是经典的23种设计模式之内,或者23种之外的,其实他们都是基于最基本的6种设计原则展开的。理解6种设计原则,我们可以从根源更好的理解23种经典的设计模式。甚至待到你的经验炉火纯青之时,可以创造出自己的一种设计模式。

本文带大家学习和了解第一种设计原则,单一职责原则

单一职责原则

定义:就一个类而言,应该仅有一个引起它变化的原因。应该只有一个职责。  每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。

上文的定义源自百度,其意思简单来说为:一个类或者模块只承担一个职责

单一职责指的是到哪个程度的单一?

单一职责原则实际上很好理解,但是其边界我们却难以判定。

那么,一个类完成一个业务功能是单一职责,还是一个类完成一个业务功能中某个流程步骤的功能称之为单一职责?

同时单一职责描述的是类和模块,那么类可以被称之为模块吗?还是说多个类才能祖成一个模块?我们实际中的单一职责应该针对某个类,还是针对多个类组成的模块呢?

要回答上述的这些问题,需要我们对单一职责有更加深的理解。

事实上,对于 单一职责原则 这种较为难以界定实际边界的规则,我们对其的定义应该是随着业务的变化而变化的,其定义应该是动态化的。

当业务需求小的时候,我们认为模块是类的抽象化表达,那么一个类能完成的一个功能块,我们也称之为模块。那我们的单一职责自然也是一个类而已。

当业务需求变大了,我们抽取出多个类一起完成某个功能,那我们认为这个功能涉及到的类合起来实现的为一个模块。但是这个时候,单一职责并非就全指整个模块了,对于整个模块,单一职责的评判是该模块是否实现的是单一的一个大功能,没有去实现其他的功能。对于其中的类,我们需要看是否包含其他业务领域的操作,如果包含,且存在该领域的业务,那么我们应该把这些关于其他业务领域的代码拆解出来,成为一个新的类;而如果包含,但目前不存在该领域的业务,那这个类也可认为是足够单一的类了。

举个例子:

某个功能类中包含订单和地址的信息和操作

但是目前并不需要关于订单或者地址的功能,那么该功能类可认为是符合单一职责原则了

若是目前有涉及订单和地址的业务,我们就需要把订单和地址单独出来成为一个类,这样子才算符合单一职责

所以说,单一职责的范围,取决于我们的业务范围

所以我们代码是否单一,都是基于当前的业务来说的,我们要维护代码符合该原则,就需要不断地持续重构

我们可以先写一个粗粒度的类,满足业务需求。随着业务的发展,如果粗粒度的类越来越庞大,代码越来越多,这个时候,我们就可以将这个粗粒度的类,拆分成几个更细粒度的类。这就是所谓的持续重构

那么基于当前编程界的实际经验,我们有哪些清晰的原则判断是否符合单一原则呢?

我们可以从以下方面判断

类中的代码行数、函数或属性过多,会影响代码的可读性和可维护性,我们就需要考虑对类进行拆分;

类依赖的其他类过多,或者依赖类的其他类过多,不符合高内聚、低耦合的设计思想,我们就需要考虑对类进行拆分;

私有方法过多,我们就要考虑能否将私有方法独立到新的类中,设置为 public 方法,供更多的类使用,从而提高代码的复用性;

比较难给类起一个合适名字,很难用一个业务名词概括,或者只能用一些笼统的 Manager、Context 之类的词语来命名,这就说明类的职责定义得可能不够清晰;

类中大量的方法都是集中操作类中的某几个属性,比如,在 UserInfo 例子中,如果一半的方法都是在操作 address 信息,那就可以考虑将这几个属性和对应的方法拆分出来。

我们设计的类越单一就一定越好吗?

实际上并非如此,单一的范围是有限度的,我们将单一职责的规定过于细化的时候,想让每一个小功能都更单一时候,会适得其反,导致代码易用性遭到破坏。

我们设计的时候,把一些其中功能相关性较大的类,为了单一职责,而把其拆开为多个类。反而导致代码内聚性和可维护性减低。

所以说,我们是否要设置的更加单一,还是要以实际的操作和功能来判断

不管是应用设计原则还是设计模式,最终的目的还是提高代码的可读性、可扩展性、复用性、可维护性等。我们在考虑应用某一个设计原则是否合理的时候,也可以以此作为最终的考量标准

单一职责原则通过避免设计大而全的类,避免将不相关的功能耦合在一起,来提高类的内聚性。同时,类职责单一,类依赖的和被依赖的其他类也会变少,减少了代码的耦合性,以此来实现代码的高内聚、低耦合。但是,如果拆分得过细,实际上会适得其反,反倒会降低内聚性,也会影响代码的可维护性


相关文章
|
8月前
|
设计模式 关系型数据库 数据安全/隐私保护
软件架构设计原则之单一职责原则
单一职责(Simple Responsibility Pinciple,SRP)是指不要存在多于一个导致类变更的原因。假设我们有一个类负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能导致另一个职责的功能发生故障。这样一来,这个类就存在两个导致类变更的原因。如何解决这个问题呢?将两个职责用两个类来实现,进行解耦。后期需求变更维护互不影响。这样的设计,可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。总体来说,就是一个类、接口或方法只负责一项职责。
66 0
软件架构设计原则之单一职责原则
|
3月前
|
设计模式 存储 NoSQL
【设计模式】软件设计原则-单一职责原则
【1月更文挑战第12天】【设计模式】软件设计原则-单一职责原则
|
8月前
|
设计模式 人工智能 Java
软件架构设计原则之依赖倒置原则
依赖倒置原则(Dependence Inversion Principle,DIP)是指设计代码结构时,高层模块不应该依赖低层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。通过依赖倒置,可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并且能够降低修改程序所造成的风险。接下来看一个案例,还是以Course(课程)为例,先来创建一个类Tom:
62 0
|
3月前
|
设计模式 关系型数据库
【设计模式】软件设置原则-开闭原则
【1月更文挑战第12天】【设计模式】软件设置原则-开闭原则
|
8月前
|
设计模式 关系型数据库
软件架构设计原则之迪米特法则
迪米特原则(Law of Demeter LoD)是指一个对象应该对其他对象保持最少的了解,又叫最少知道原则(Least Knowledge Principle,LKP),尽量降低类与类之间的耦合度。迪米特原则主要强调:只和朋友交流,不和陌生人说话。出现在成员变量、方法的输入、输出参数中的类都可以称为成员朋友类,而出现在方法体内部的类不属于朋友类。
68 1
|
8月前
|
设计模式 关系型数据库
软件架构设计原则之接口隔离原则
接口隔离原则符合我们常说的高内聚、低耦合的设计思想,可以使类具有很好的可读性、可扩展性和可维护性。我们在设计接口的时候,要多花时间去思考,要考虑业务模型,包括对以后有可能发生变更的地方还要做一些预判。所以,对于抽象、对于业务模型的理解是非常重要的。下面我们来看一段代码,对一个动物行为进行抽象描述。
58 0
|
8月前
|
设计模式 关系型数据库
软件架构设计原则之里氏替换原则
里氏替换原则(Liskov Substitution Principle,LSP)是指如果对每一个类型为T1的对象o1,都有类型为T2的对象O2,使得以T1定义的所有程序P在所有的对象O1都替换成O2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型。
55 0
|
10月前
|
设计模式 安全 Java
设计原则之接口隔离原则
设计原则之接口隔离原则
48 0
设计原则之接口隔离原则
|
10月前
|
设计模式 安全 Java
设计原则之依赖倒置原则
设计原则之依赖倒置原则
56 0
设计原则之依赖倒置原则
|
Java API 开发工具
接口隔离原则|设计原则
今天为大家带来的依旧是 设计原则 的知识: 接口隔离原则