- 單一職責原則(Single Reponsibility Principle,SRP)
- 里氏替換原則(Liskov Substitution Principle,LSP)
- 依賴倒置原則(Dependence Inversion Principle,DIP)
- 接口隔離原則(Interface Segregation Principe,ISP)
- 迪米特法則(Law of Demeter,LOD)
- 開閉原則(Open Closed Principle,OCP)
單一職責原則 SRP:
Single Reponsibility Principle,簡稱:SRP
一個類只負責一項職責。換種說法,就一個類而言,應該只有一個引起它變化的原因。
問題由來:類T負責兩個不同的職責:職責P1,職責P2。當由於職責P1需求發生改變而需要修改類T時,有可能會導致原本運行正常的職責P2功能發生故障。
解決方案:遵循單一職責原則。分別建立兩個類T1、T2,使T1完成職責P1功能,T2完成職責P2功能。這樣,當修改類T1時,不會使職責P2發生故障風險;同理,當修改T2時,也不會使職責P1發生故障風險。
單一職責的成本:類變多了;上端需要了解更多的類
衡量着使用:
- 如果類相對穩定,擴展變化少,而且邏輯簡單,違背單一職責也沒關係
- 一個類不要讓他太“累”
- 如果不同的職責,總是一起變化,這種是一定要分開的
舉例
一個簡單的例子,動物的故事,代碼如下:
public class Animal
{
protected string _Name = null;
public Animal(string name)
{
this._Name = name;
}
public void Action()
{
if (this._Name.Equals("雞"))
{
Console.WriteLine($"{this._Name} flying");
}
else if (this._Name.Equals("魚"))
{
Console.WriteLine($"{this._Name} swimming");
}
//……
}
}
動物類,呼吸方法中分別寫了雞和魚的活動方式,雞活動是飛、魚活動是游泳,當出現其他動物時Action類就不穩定了,就得不斷的修改此方法,不斷的 if…else… 。因此,製造了不穩定性,若方法內業務複雜,容錯率就非常低了。
倘若將代碼改寫一下。設置一個抽象類Animal。魚類AnimalFish和雞類AnimalChicken分別繼承自動物類。類的複雜性降低了,可讀性也同時提高了,最重要的是職責劃分也明確了。當然,也就更容易維護了。
代碼如下:
public abstract class Animal //動物類 ——— 抽象類
{
protected string _Name = null;
public Animal(string name)
{
this._Name = name;
}
public abstract void Breath();
public abstract void Action();
}
public class AnimalFish : Animal //魚類
{
public AnimalFish(string name) : base(name)
{}
public override void Breath()
{
Console.WriteLine($"{this._Name} 呼吸水");
}
public override void Action()
{
Console.WriteLine($"{this._Name} swimming");
}
}
public class AnimalChicken : Animal //雞類
{
public AnimalChicken(string name) : base(name)
{}
public override void Breath()
{
Console.WriteLine($"{this._Name} 呼吸空氣");
}
public override void Action()
{
Console.WriteLine($"{this._Name} flying");
}
}
class Program
{
static void Main(string[] args)
{
{
Animal animal = new AnimalChicken("雞");
animal.Breath();
animal.Action();
}
{
Animal animal = new AnimalFish("魚");//呼吸水
animal.Breath();
animal.Action();
}
}
}