设计原则之单一职责–为什么要设计成单一职责
单一职责原则(Single Responsibility Principle) SRP
的意思是,就一个类而言,应该仅有一个引起他变化的原因。
这个原则的英文描述是A class or module should have a single reponsibility
。一个类或者模块只有一个职责。
为什么要使用单一职责
借用大话设计模式
一书中使用的例子。比如现在科技高度发达,手机
成为了日常使用中不可替代的产品。手机的功能很多,可以拍照,可以上网,可以打电话,聊天,打游戏等。假设我们没有手机,那么我们拍照需要摄像机,打游戏需要游戏机,听歌需要mp3,但是现在不用带这么多东西,只需要一个手机就搞定了。觉得很方便。但是呢,手机的拍照功能并没有单反好,游戏性能和游戏数量也比不上ps4和xbox以及ns。
如果放在代码中就是你的所有代码都写在一起,像一团乱麻一样。严重影响了可读性,扩展性,维护性等。相信没有人喜欢看到这样的代码。所以这就是单一职责
。对代码要有结构,要清晰明了,其实代码中到处都体现了这个原则。比如mvc
的分层架构,比如前后端分离,比如docker
的兴起,比如我们日常使用的框架也分离了我们的职责,使得我们只需要关注一些实现就好了。再生活中也有比如公司分成了各个部门,人类分成了男人女人,由各个职业。每个人只需要关注自己的事情,简单明了。这就是单一职责的好处。
如果一个类承担的职责
过多,就等于把这些职责耦合在一起,一个变化会引起其他意想不到的变化,使得整个程序脆弱不堪。我们经常说要写高内聚,低耦合
的代码,如果违反了单一职责那么就只能写出高耦合的代码了。
如何使用单一职责
如果你能想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。如果类的职责多了,我们就需要把他们分离开来,当然了,这个原则比较具有主观性。有的人觉得这个类不是单一职责,有的人觉得是单一职责。
判断是否单一职责要结合具体的业务场景和使用,如果你有多个引起这个类变化的地方,那么就需要重新考虑一下这个类是否符合单一职责了。
在我们平常开发中,没必要一开始纠结是否符合单一职责,随着开发的演进,程序越来越庞大,我们需要随着业务的发展将类分的越来越细才好,要持续重构。一定不要等到已经往一个类里面塞了很多代码才考虑划分成单一职责。那样的话拆分起来很费劲而且耗时耗力。在添加新功能的时候要想一想这个功能应该添加到哪里,是否符合单一职责。
开发中可以根据下面几点来判断是否满足单一职责:
- 类中的代码过多,影响了代码的可读性和维护性。
- 和这个类有依赖关系的类比较多,耦合过高。
- 比较难给类命名,不清楚这个类是干啥的了。
- 类中大量的方法都是集中操作类的某几个属性。
类的职责是否越单一越好
显然不是的,如果一个类过于职责单一,比如加密类,有一个加密方法和解密方法。
class hash {
public function encode() {
//...
}
public function decode() {
//...
}
}
如果我们执着于单一职责,要把这个类拆分成两个类。一个加密类一个解密类。
class hashDecode{
public function decode() {
}
}
class hashEncode{
public function encode() {
}
}
如果这时候根据新的需求,我们的加密算法需要改变,那么解密算法也需要改变,我们要同时改变两个类,如果忘记其中一个,那么整个程序就会崩溃。我们的最终目标是写出高内聚低耦合
的代码。而不是生搬硬套某一个设计原则或者设计模式。设计原则是总结出来指导我们进行程序设计的方针。合理使用可以使得我们的程序更加健壮。
参考资料:
- 大话设计模式
- 极客时间设计模式之美