SRP - 单一责任原则
SOLID 中的 S 代表单一责任原则(SRP)。
** 在这种情况下,责任意味着改变的原因,因此该原则规定一个类应该只有一个改变的理由。
Robert C. Martin 在 2014 年 9 月 10 日的耶鲁管理学院讲座中表示如下
你还可以说,不要将因不同原因而更改的函数放在同一个类中。
要么
不要在课堂上混淆顾虑
申请 SRP 的原因:
更改类时,可能会影响与该类其他职责相关的功能。将责任保持在较低水平可以最大限度地降低副作用的风险。
不好的例子
我们有一个接口 IWallet 和一个实现 IWallet 的 Wallet 类。钱包持有我们的钱和品牌,此外它应该打印我们的钱作为字符串表示。该类由…使用
- 一个网络服务
- 一个文本作者,用欧元将钱打印成文本文件。
SRP 在这里受到了侵犯,因为我们有两个问题:
- 存钱和品牌
- 钱的代表。
C#示例代码
public interface IWallet
{
void setBrand(string brand);
string getBrand();
void setMoney(decimal money);
decimal getMoney();
string printMoney();
}
public class Wallet : IWallet
{
private decimal m_Money;
private string m_Brand;
public string getBrand()
{
return m_Brand;
}
public decimal getMoney()
{
return m_Money;
}
public void setBrand(string brand)
{
m_Brand = brand;
}
public void setMoney(decimal money)
{
m_Money = money;
}
public string printMoney()
{
return m_Money.ToString();
}
}
好例子
为了避免违反 SRP,我们从钱包类中删除了 printMoney
方法并将其放入 Printer 类中。Printer 类现在负责打印,Wallet 现在负责存储值。
C#示例代码
public interface IPrinter
{
void printMoney(decimal money);
}
public class EuroPrinter : IPrinter
{
public void printMoney(decimal money)
{
//print euro
}
}
public class DollarPrinter : IPrinter
{
public void printMoney(decimal money)
{
//print Dollar
}
}
public interface IWallet
{
void setBrand(string brand);
string getBrand();
void setMoney(decimal money);
decimal getMoney();
}
public class Wallet : IWallet
{
private decimal m_Money;
private string m_Brand;
public string getBrand()
{
return m_Brand;
}
public decimal getMoney()
{
return m_Money;
}
public void setBrand(string brand)
{
m_Brand = brand;
}
public void setMoney(decimal money)
{
m_Money = money;
}
}