单一责任准则的界说

单一责任准则(Single Responsibility Principle,SRP)是面向对象规划中最基本、最重要的准则之一。它的界说如下:

“一个类应该只要一个引起它变化的原因” 或许 “一个类或许模块只担任完成一个责任”。

简单来说,SRP 准则便是要求一个类或模块只担任一项责任,不要存在多个引起类变化的原因。也便是说,一个类或模块应该只要一个单一的功用或责任。假如一个类或模块存在多种责任,那么它的规划便是存在缺点的。

为什么要遵从 SRP 准则?

遵从 SRP 准则有以下几个优点:

  1. 更简单保护和管理。当一个类或模块只要一个责任时,它的代码愈加明晰明晰,更简单阅读、修正和测验,降低了代码保护本钱。
  2. 更好的重用性。单一责任的类或模块更简单被其他代码重用,因为它的功用更为明晰,愈加独立。
  3. 更好的扩展性。单一责任的类或模块更简单扩展,增加新的功用时不会对原有功用造成影响。

下面经过一个简单的 Golang 实战事例来说明 SRP 准则的运用。

假定咱们正在为一个电商网站编写购物车的代码,购物车能够添加、修正、删去产品,咱们先来看一下不恪守 SRP 准则的代码:

typeCartstruct{
items[]*Item
}
func(c*Cart)AddItem(i*Item){
c.items=append(c.items,i)
}
func(c*Cart)RemoveItem(i*Item){
forj,item:=rangec.items{
ifitem.ID==i.ID{
c.items=append(c.items[:j],c.items[j+1:]...)
break
}
}
}
func(c*Cart)UpdateItem(i*Item){
for_,item:=rangec.items{
ifitem.ID==i.ID{
item.Quantity=i.Quantity
break
}
}
}
func(c*Cart)Checkout()float64{
vartotalfloat64
for_,item:=rangec.items{
total+=item.Price*float64(item.Quantity)
}
returntotal
}

上面的代码完成了购物车的添加、修正、删去产品以及结算的操作。可是这个 Cart 结构体并不只要一个责任,它是既担任购物车的信息管理,又担任结算函数的核算。

这样一来,假如核算函数的算法改变了,那么 Cart 结构体也需求跟着变化。假如购物车的信息管理和结算函数的责任别离,这种问题就会得到解决。

再来看一下运用了“单一准则”规划后的代码:

typeCartstruct{
items[]*Item
}
func(c*Cart)AddItem(i*Item){
c.items=append(c.items,i)
}
func(c*Cart)RemoveItem(i*Item){
forj,item:=rangec.items{
ifitem.ID==i.ID{
c.items=append(c.items[:j],c.items[j+1:]...)
break
}
}
}
func(c*Cart)UpdateItem(i*Item){
for_,item:=rangec.items{
ifitem.ID==i.ID{
item.Quantity=i.Quantity
break
}
}
}
typeCheckoutstruct{
cart*Cart
}
funcNewCheckout(c*Cart)*Checkout{
return&Checkout{c}
}
func(co*Checkout)Calculate()float64{
vartotalfloat64
for_,item:=rangeco.cart.items{
total+=item.Price*float64(item.Quantity)
}
returntotal
}

上面的代码将核算函数的责任别离出去,放到结算类 Checkout 中。这样做的优点是:

  1. Cart 结构体只担任购物车的信息管理,责任划分更为明晰;
  2. Checkout 结构体只担任核算结账金额,责任也更为明晰;
  3. 两个结构体的代码都更简单保护和重用。

怎样判别类的责任是否满足单一?

提到判别一个类的责任是否满足单一,其实并没有一个十分明晰的、能够量化的标准答案。可是规划准则也不能含糊不清、模棱两可。

在面向对象编程中,一个类应该专心于完成一个明晰的责任,并且尽或许接近于只专心于履行这个责任。这样做有助于使代码愈加明晰、易于保护和扩展。

下面是一些能够协助你判别一个类的责任是否单一的办法:

  1. 责任影响规模

假如一个类有多个责任,那么当一个责任发生变化时,或许会影响其他责任的完成。这样做会导致代码不稳定,难以保护和扩展。因而,经过单一责任准则,咱们能够确保每个类只专心于一件事情。

  1. 类是否具有高内聚性

假如一个类具有高内聚性,说明该类的一切成员都是为了完成同一个目标而存在的。假如一个类具有低内聚性,说明该类的成员或许难以组织在一起,或许存在很多不相关的操作。因而,经干预自己这个类是否具有高内聚性,咱们能够判别这个类的责任是否单一。

  1. 类是否具有低耦合性

一个类应该尽或许少地依靠其他类或模块。假如一个类具有高耦合性,那么当其他类或模块发生变化时,或许会影响到该类的完成。因而,经干预自己这个类是否具有低耦合性,咱们能够判别这个类的责任是否单一。

  1. 接口是否明晰

一个类的接口应该是明晰、简单明晰的。假如一个类具有多个责任,那么它的接口或许会变得复杂难明,难以保护和运用。因而,经过观察这个类的接口是否明晰,咱们能够判别这个类的责任是否单一。

  1. 类中的代码行数

假如一个类中代码、函数或属性过多,会影响代码的可读性和可保护性,就需求考虑对类进行拆分;

总之,一个类的责任是否单一是很重要的,在规划和完成过程中需求认真思考和掌握。经过上述的办法,能够协助开发者更好地判别一个类的责任是否单一,并进步代码的质量和保护性。

总结

总之,SRP 是软件开发中十分重要的一个准则,遵从 SRP 能够让代码愈加简单保护、管理、复用和扩展。

在实践开发中,咱们要时间关注每个类或模块的责任是否单一,遵从 SRP 准则是进步代码质量的十分有用的方式。