您的位置:首页 > 其它

单一职责原则

2017-02-10 16:59 295 查看

单一职能原则

单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。该原则由罗伯特·C·马丁(Robert C. Martin)于《敏捷软件开发:原则、模式和实践》一书中给出的。马丁表示此原则是基于汤姆·狄马克(Tom DeMarco)和Meilir Page-Jones的著作中的内聚性原则发展出的。

所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。百度百科

ps:文章经常会引用百度百科而不是维基百科,是因为笔者英文水平一般 -_-!!!

软件开发过程中常说的高内聚低耦合就是单一职责的前身,那么单一职责到底如何体现呢,下面通过一段代码来解释说明

public class  Animal{
public void Move(string name){
console.wirte(name+"行走在路上");
}
//重载不赘述
……
}
public class Client{
Animal animal = new Animal();
animal.Move("马");
animal.Move("人");
}


以上一段代码明确 Animal是一个类,这个类应该包含Move,那么如果当我们用传入参数“鱼”这个方法的输出就出现了问题,难道是美人鱼么^0^.

那么我们可以想到增加一个枚举作为参数,再类中进行判断,如果传入鱼类(不管是鲨鱼,鲸鱼还是海豚)就输出“游在水里”不就OK了么。这样做当然是没有问题的,但是,再增加鸟类呢,是不是就要修改枚举类型和修改Animal类的Move方法了呢?这就违背了开放关闭原则,将来在出现其他类中的生物实例化的时候会影响到这个类的变化,这样就是因为Animal类的职责不单一导致的。

那么应该如何处理呢?

创建一个接口,IAnimal,声明Move方法,再创建子类,Person,Fish,Bird等类继承IAnimal,每个类都实现自己的Move行为,就算将来出现了新物种,只要增加新的类就好了,不会影响原来的任何类和行为。



重点在这里

如何定义单一职责:在各个公司、项目组经常听见关于单一职责的问题争论不休,争论的内容无非就是XXX类的职责是否单一,该职责还能够拆分或者是XXX类和XXX类可以合并,减少代码量和维护成本,虽然违反了单一职责,但是这个不会更复杂了,可以这样合并。

[b]讨论的问题1:XXX类是否职责单一[/b]

这是很难界定的问题,想要确定,那么就先要确定项目的大小和功能的划分粒度以及类的最小粒度,只有明确了这三点,才能确定XXX类是否职责单一。

推荐方法:确定项目大小可以根据代码量或者实体类的数量进行确定。将项目中遇到的所有名词都罗列出来,进行筛选,得到有效核心的名词,如果这些名词包含内容很多,可以继续拆分,直到所有人(大部分)举手表决认为已经不需要拆分。次级别就是最小粒度了,非核心名词可以采取次一级别的粒度进行划分。

比如:一个铁路项目中的名词:火车,这个名词明显还需要继续拆分,因为不同的火车的价格,维护甚至是轨道都不同,区别太大,而且将来可能会出现磁悬浮火车,空中火车或者出现怀旧的特慢火车。

[b]讨论的问题2:是否可以违背单一职责原则[/b]

关于这个问题我不再总结,网上有很多很到位的总结,引用一下

A.只有逻辑足够简单,才可以在代码级别上违背SRP;

B.只有类中方法数量足够少,才可以在方法级别上违背SRP;引用地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息