SRP - 單一責任原則

SOLID 中的 S 代表單一責任原則(SRP)。

** 在這種情況下,責任意味著改變的原因,因此該原則規定一個類應該只有一個改變的理由。

Robert C. Martin 在 2014 年 9 月 10 日的耶魯管理學院講座中表示如下

你還可以說,不要將因不同原因而更改的函式放在同一個類中。

要麼

不要在課堂上混淆顧慮

申請 SRP 的原因:

更改類時,可能會影響與該類其他職責相關的功能。將責任保持在較低水平可以最大限度地降低副作用的風險。

不好的例子

我們有一個介面 IWallet 和一個實現 IWallet 的 Wallet 類。錢包持有我們的錢和品牌,此外它應該列印我們的錢作為字串表示。該類由…使用

  1. 一個網路服務
  2. 一個文字作者,用歐元將錢列印成文字檔案。

StackOverflow 文件

SRP 在這裡受到了侵犯,因為我們有兩個問題:

  1. 存錢和品牌
  2. 錢的代表。

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();
    }
}

好例子

StackOverflow 文件

為了避免違反 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;
    }
}