类之单一职责原则

//z 2012-4-17 15:02:07 PM IS2120@CSDN
0. 面向对象设计的5原则(SOLID)
•   Single Responsibility Principle     单一职责原则
•   Open Closed Principle        开闭原则
•   Liskov Substitution Principle     里氏替换原则
•   Interface Segregation Principle    接口隔离原则
•   Dependency Inversion Principle    依赖反转原则

//z 2012-4-17 15:02:07 PM IS2120@CSDN
1. SRP 是什么?
SRP : Single Responsibility Principle
类应具有单一职责

2. 什么是职责?
行为;功能;角色;
2.1 职责的实现:由类的属性和方法来承担
2.2 单一职责:一个类只扮演一个角色,只做一件事情
(精细分工是现代社会的标志之一)

3. 使用SRP的目的
高内聚;低耦合

4. 多个职责有什么不好?
职责之间会相互影响;为使用某一功能而引入其他不需要的功能;对类的修改会牵涉太多
(尽可能保持小、窄、轻、快;适当的粒度更利于复用)

5. 如何区分不同的职责?
有些显而易见;更多的需要积累经验,很难较好划分。
(我们面对更多的是较为明确的需求;而职责的划分涉及了实现)

6. SRP
6.1 单一职责
6.1.1 完全做一件事
6.1.2 做好这件事
6.1.3 只做这件事

6.2 应该有一个并且只有一个原因来对类进行变更
6.3 每一个职责应该是一个独立的类;每个职责对应变更的一个维度
6.4 实际导致变更时来源单一

6.5 经验之谈(Rule of thumb)
6.5.1 能用25个字就描述清楚一个类。
6.5.2 如果试图去做太多的事情,类、接口、函数总倾向于膨胀
6.5.3 保持代码简洁有效。onlyAndOnlyOnce,Do the simplest thing that could possibly work.


7. 实例
7.1 Rect
Rect
-->Draw
-->Area
7.2 不同职责划分
Draw属于GUI
Area属于计算几何
应该划分开
//z 2012-4-17 15:02:07 PM IS2120@CSDN

//z 2012-4-17 15:07:48 PM IS2120@CSDN
8. 关于 SRP 的对话
Single Responsibility Principle poster

一个无所不能的类从长远来看会是麻烦的根源之一。
It says,"just because you can implement all the features in a single device,you shouldn't". Why? Because it adds a lot of manageability
problems for you in the long run.

Let me tell you the principle in Object Oriented terms.
"There should never be more than one reason for a class to change."
Or,differently said: "A class should have one and only one responsibility".

Farhana: Can you please explain?

根据不同的职责而划分成独立的类。
Shubho: Sure,this principle says that if you have a class that has more than one reason to change (or has more than one overall
responsibility),you need to split the class into multiple classes based upon their responsibility.

Farhana: Hmm... does that mean that I can't have multiple methods in a single class?

类中的方法应该是为了同一个目的(职责)。
Shubho: Not at all. Rather,you surely can have multiple methods in a single class. The issue is,they have to meet a single purpose. Now,
why is splitting important?

每个职责都是变更的一个维度
如果类具有一个以上的职责容易耦合

It's important because:
Each responsibility is an axis of change.
Code becomes coupled if classes have more than one responsibility.

例举了Bob的例子(RECT)
Farhana: Could you please give me an example?

Shubho: Sure,take a look at the following class hierarchy. Actually,this example is taken from Uncle Bob,so thanks to him again.
Class hierarchy showing violation of SRP principle

Here,the Rectangle class does the following:
It calculates the value of the rectangular area.
It renders the rectangle in the UI.

And,two applications are using this Rectangle class:
A computational geometry application uses this class to calculate the area
A graphical application uses this class to draw a rectangle in the UI

This is violating the SRP (Single Responsibility Principle)!

Farhana: How?

Shubho: You see,the Rectangle class is actually performing two different things. It is calculating the area in one method,and it is
returning a GUI representation of the rectangle in another method. This leads to some interesting problems:

We must include the GUI in the computational geometry application. While deploying the geometry application,we must include the GUI
library.
A change to the Rectangle class for the graphical application may lead to a change,build,and test for the computational geometry
application,and vice-versa.

Farhana: It's getting interesting. So I guess we should break up the class based on its responsibilities,right?

Shubho: Exactly. Can you predict what we should do?

Farhana: Sure,let me try. Following is what we might need to do:

Separate the responsibilities into two different classes,such as:

Rectangle: This class should define the area() method.
RectangleUI: This class should inherit the Rectangle class and define the Draw() method.

Shubho: Perfect. In this case,the Rectangle class will be used by the computational geometry application,and the RectangleUI class will
be used by the graphical application. We could even separate the classes into two separate DLLs,and that will allow us not to touch the
other in case a change is needed to be implemented in one.

适当的粒度有利于重用,便于管理。
Farhana: Thanks,I think I understand SRP. One thing,SRP seems to be an idea of breaking things into molecular parts so that it becomes
reusable and can be managed centrally. So,shouldn't we apply SRP in the method level as well? I mean,we might have written methods that
have many lines of code for doing multiple things. These methods might be violating SRP,right?

每个方法也应该有单一的职责。这样方便方法的重用。同时如果需要变更时,也许只需要变更一小片的代码。 Shubho: You got it right. You should break down your methods so that each method does a particular work. That will allow you to re-use methods,and in case a change is required,you are able to do the change by modifying minimal amount of code.

相关文章

什么是设计模式一套被反复使用、多数人知晓的、经过分类编目...
单一职责原则定义(Single Responsibility Principle,SRP)...
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强...
适配器模式将一个类的接口转换成客户期望的另一个接口,使得...
策略模式定义了一系列算法族,并封装在类中,它们之间可以互...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,...