当前位置: 代码迷 >> 开发方法 >> 面向对象设计原则的“单一职责”怎么理解
  详细解决方案

面向对象设计原则的“单一职责”怎么理解

热度:10030   发布时间:2013-02-26 00:00:00.0
面向对象设计原则的“单一职责”如何理解?
“单一职责”说起来容易,在实际设计中却很难把握。
什么才算是单一职责?
一个类处理一个用例,还是一个类处理用例中的一个流程?
说比如用户管理,有添加,修改,删除。。。。
是把用户管理作为一个类,
还是添加,修改,删除都作为一个类


------解决方案--------------------------------------------------------
设计模式中的原则
1.OCP开闭原则
2.里氏代换LSP
3.依赖倒转DIP
4.接口隔离ISP
5.合成聚合复用CARP
6.迪米特法则LoD


“还是添加,修改,删除都作为一个类 ”
这些都是method,都是行为,只能是类的一部分啊

在实际设计过程中,一个用例只能对应一个控制类,这是你想说的吗?
------解决方案--------------------------------------------------------
还要考虑具体应用环境
有一个“度”的问题
------解决方案--------------------------------------------------------
引用楼主 netbtw 的帖子:
“单一职责”说起来容易,在实际设计中却很难把握。
什么才算是单一职责?
一个类处理一个用例,还是一个类处理用例中的一个流程?
说比如用户管理,有添加,修改,删除。。。。
是把用户管理作为一个类,
还是添加,修改,删除都作为一个类

------解决方案--------------------------------------------------------
单一原则说的是能够引起一个类变化的因素只有一种。
添加,修改,删除往往出现对数据的操作。是一种本质上相同的行为,应该封装在一个类。
这个类在三层结构里往往是数据访问层,最后一点,类和用例没有完全的对应关系,只有相关关系。
每个用户都有用户管理的这个行为,可以笼统的认为是一个抽象的共同体,不过这不同于我们常见的实体类罢了!因此,可以抽象为一个类来管理所有用户的数据!
个人认为项目中分解对象,抽象分析异同才是关键的,才是为后面的设计做铺垫的关键。
呵呵~~拙劣希望对你有用。
------解决方案--------------------------------------------------------
引用楼主 netbtw 的帖子:
“单一职责”说起来容易,在实际设计中却很难把握。
什么才算是单一职责?
一个类处理一个用例,还是一个类处理用例中的一个流程?
说比如用户管理,有添加,修改,删除。。。。
是把用户管理作为一个类,
还是添加,修改,删除都作为一个类


------解决方案--------------------------------------------------------
设计类时考虑高内聚,低耦合,同时即不能把类设计的过小,也不能过大,度啊,楼上说的好。
------解决方案--------------------------------------------------------
楼上某位已经提到了,单一职责是指引起这个类变化的原因应当是单一。理想情况下,我们希望每个类只在一个维度上响应变化,或者说响应一个维度上的变化。比如,数据访问层(DAO)的User,它应当封装不同的数据访问环境,当数据访问环境变化时,我们不需要修改User类的使用者。User类只应当具有同数据访问最直接相关的职责,而不应当具有其他的逻辑。同时,不应当把其他对象的访问作为User类的职责,否则其他对象的变化就可能引起User类的修改。

尽可能使职责单一同时意味着这个类具有相对少的方法,相对少的依赖,意味着高内聚,低耦合,因此更容易测试,修改,重用,以及被其他人理解。如果系统中都是这样的类,那么系统的维护成本就会比较低。
------解决方案--------------------------------------------------------
Robert C. Martin对SRP的解释是:Each class should have one and only one reason to change.

按照这个解释来分清各种曲解概念其实很明显。我记得最初提出“用例”时,许多人奇怪为什么用例没有分支?!其实,一旦有分支就应该区分成多个用例了。就是这么回事!人们往往习惯用一个比较空洞的动词来描述任务,然后再分解、说明任务的内涵。而用例分析要求人们尽管可以尽量概括任务,但是不应该分支。

如果在一个“积木世界”游戏中机器人把一个箱子从A地搬到B地,那么你的描述中这个B就应该是地面和箱子的共同的抽象接口,而不应该区分
 
if(B is 地面) then ..... else if(B is 箱子) then ....

这样的含糊不清的职责结果。

------解决方案--------------------------------------------------------
任何动作都会引起对象状态的改变,描述职责时不要隐藏矛盾,而要简简单单地描述对象状态改变,不要设置任何条件。如果发觉同一用例根据条件不同而得到不同的对象状态,那么你定义此用例时就是夸张了,造成了内部矛盾。
------解决方案--------------------------------------------------------
比较容易被好事者诟病的是这个“职责”的粒度粗细问题。有人说是一个职责,而有人把此一个职责硬说成是两个顺序职责,而是后者就说“看,职责过多了吧!”。我对此说法无所谓,觉得无关痛痒。职责粒度定义时的大小不是单一职责要强加约束的,实际上不同人对职责的认识可大可小,关键就是对结果职责的认识不存在分支,这才是关键。