单一职责原则

什么是单一职责原则

什么是单一职责原则?

 

单一职责原则的英文名称是Single Responsibility Principle,简称SRP。SRP的原话解释是:There should never be more than one reason for a class to change.

也就是说一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。

这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。

 

什么是职责?

 

SRP中,把职责定义为"变化的原因"。如果你能想到N个动机去改变一个类,那么这个类就具有多于一个的职责。这里说的"变化的原因",只有实际发生时

才有意义。可能预测到会有多个原因引起这个类的变化,但这仅仅是预测,并没有真的发生,这个类仍可看做具有单一职责,不需要分离职责。比如我们生活

当中用的筷子,我们吃饭的时候既把筷子当作是刀来使用,用它来分割食物,也把筷子当做叉来使用,将食物夹到碗中或口中。在这其中,筷子既有分割食物的

职责,也有移动食物的职责,而西餐用的刀就只有分割食物的职责,叉只有移动食物的职责。我们可以根据具体的情况,可以把筷子看作是吃饭工具的职责,也

可以讲筷子看作具有分割食物与移动食物两个职责。所以说职责不是一成不变的,我们需要根据具体的情况来划分职责,决定职责颗粒度的大小。

 

具体实践

 

我们有时去国外出差,需要去银行兑换美元、欧元等等, 不同种类的钞票对应不同的汇率,汇率也会有所波动。类的设计如下,

 

class Exchange

{

private double _exchangeRate;

 

/// <summary>

/// 汇率换算

/// </summary>

/// <param name="type"></param>

/// <returns></returns>

public double GetExchangeRate(string type)

{

switch (type)

{

case "Dollar"://美元

return 0.15;

 

case "Euro"://欧元

return 0.08;

}

return 1;

}

 

public double ExchangeMoney(double money,string type)

{

return money * GetExchangeRate(type);

}

}

 

初看不会发现有什么问题,因为我们平时也是这样写的。我们认真看后会发现,当汇率发生变化时,我们需要修改Exchange类,当我们需要新增钞票台币时,

我们也需要修改Exchange类,而单一职责原则规定,只有一个变化的原因引起类的改变,因此违背了单一职责原则。此时就需要我们通过设计来实现单一职责原则了。

 

public class Money

{

public double ExchangeRate;

}

 

class Euro:Money

{

public Euro()

{

ExchangeRate = 0.08;

}

}

 

class Exchange

{

public double ExchangeMoney(double money,Money type)

{

return money * type.ExchangeRate;

}

}

 

上述设计,Money为基类,有属性ExchangeRate表示汇率,当新增一种钞票台币时,我们只需要新增一个类,继承自Money。当某种钞票的汇率发生变化时,

我们只需要在对应的类中修改对应类的汇率。每一个类只有在汇率发生变化时,才需要改变。满足单一职责原则,只有一个变化的原因能使类发生变化。

 

单一职责的好处

 

  • 类的复杂性降低,实现什么职责都有清晰明确的定义;
  • 可读性提高,复杂度降低,可读性提高;
  • 可维护性提高,可读性提高,维护更容易;
  • 适应变更的能力更强,自然风险就降低了;

 

总结

 

如果我们能对接口、类、方法都做到单一职责原则那当然是最好,但是每个类都实现单一职责原则,则需要使用组合模式,这会引起类间的耦合过重、类的

数量增加,这也增加了设计的复杂性。对于单一职责原则,建议是接口一定要做到单一职责原则,类的设计尽量做到只有一个原因引起变化。

posted @ 2014-06-08 12:52  ForOne  阅读(765)  评论(0编辑  收藏  举报