深入解理单一职责原则

2019-02-17  本文已影响0人  AlgoPeek

写在前面

在敏捷开发中,大师们总结和提炼了很多设计原则,为了便于记忆,将其最基本的5条原则根据其首字母简写为SOLID(稳固的,可靠的),其中:

灵活运用这些原则将有助于消除设计中的臭味,并为当前特性集构建出更好的设计。本文将主要讨论单一职责原则SRP

定义

这条原则最先被称之为内聚性(cohesion)。并把内聚性定义为:一个模块的组成元素之间的功能相关性

在敏捷开发中,单一职责原则定义为:

就一个类或模块而言,应该仅有一个引起它变化的原因

解读

单一:单一是指任务应该具体独立性,对一个类而言,应该只做一件事情。
职责:我们把职责定义为“变化的原因”(a reason for change)。如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个职责,而职责太多通常会导致耦合。
变化:变化是指对现有代码的修改。重构中提供了很多原则和方法指导如何在不改变软件可观察行为的前提下改善其内部结构

实例

考虑这样一个实例,为了屏蔽系统相关性,对系统socket API的封装,接口定义如下:

class Socket 
{
public:
    virtual int connect(const std::string& addr) = 0;
    virtual int close() = 0;
    virtual int send(const char* buf, int size) = 0;
    virtual int recv(char* buf, int size) = 0;    
}

可能很多人都做过类似的设计,这个接口看起来合理,它的确能提供一个socket所需要的基本功能,但这个接口中却包含了两个职责:第一个职责是连接管理,第二个职责是数据通信。connect和close接口用于连接处理,而send和recv接口用于数据通信。

我们应该将这两个职责分开吗?这个依赖于应用程序的变化方式,如果应用程序变化影响连接函数的签名,那么这个设计就具有僵化性臭味,因为调用send和recv的类必须要重新编译部署才能发布。同样,对send或recv的修改也会影响到调用connect和close的类。这个时候,我们有理由进行职责分离:

另一方便,如果应用程序的变化总是导致这两个职责同时变化,那么这两个职责是内聚的,我们没有理由分离它们,分离它们反而造成不必须的复杂性臭味。

从这个例子中我们可以看出:变化的轴线仅当变化发生时才具有真正的意义。如果没有征兆,那么去应用SRP,或者任何其它原则都是不明智的

总结

单一职责原则(SRP)是所有原则中最简单的原则之一,也是最难正确运用的原则之一,它是所有其它原则的基础。我们会自然地把职责结合在一起,软件设计真正要做的许多内容就是发现职责并把那些职责相互分离。实际上,其余原则都会以不同途径的方式回到这个问题上。

参考

  1. Agile Software Development Principles, Patterns, and Practices
  2. Think you understand the Single Responsibility Principle?
  3. Understanding SOLID Principles: Single Responsibility
  4. Single responsibility principle
上一篇下一篇

猜你喜欢

热点阅读