SOLID原則是面向對象編程和面向對象設計的頭五大原則。學習及應用這五大原則可以構建一個易於維護和擴展的應用程序,我們一起看看到底是那五大原則。
- S--單一責任原則(SRP) --Single Responsibility Principle
- O--開放封閉原則(OCP)-- Open-Closed Principle
- L--里式替換原則(LSP)-- Liskov Substitution Principle
- I –- 接口分離原則(ISP)--Interface Segregation Principle
- D–-依賴倒置原則(DIP)-- Dependency Inversion Principle
一、單一責任原則(SRP)
單一責任原則指出當需要修改某個類的時候原因有且只有一個。也就是說一個類應該只負責一件事情。當這個類需要去做其他的事情的時候,就需要分解這個類。如果把多個功能放在一個類中要它負責,
那么各個功能之間會形成關聯,改變其中一個功能可能會牽連其他的功能的改變,這樣有需要花費時間和人力對其他功能的改變進行測試,保證其他功能的完整。
Ex:
一個有關長方形的類,長、寬、面積。后來需要增加正方形,就繼續使用長方形的類,使用的時候長=寬。這一種情況違背了SRP原則,一個類只負責一件事情,這個時候應該新建一個正方形的類。
二、開放封閉原則(OCP)
開放封閉原則指的是程序模塊應該遵循關閉修改,開放擴展。這里與單一責任原則很好的聯系在了一起。一個類只負責一件事情。在程序模塊中當業務更改或新增的時候不應該更改現有的代碼行為,
應該轉向開放擴展。其中一個方法是通過抽象方法,然后繼承已達到擴展的想法。
Ex:
還是上面那個例子,最開始是計算長方形的面積,然后增加了正方形面積的計算。遵循關閉修改開放擴展的原則,不修改現有的代碼行為。將計算方法抽象繼承已擴展。新加正方形計算方法。
public interface Calculate { decimal CalculateArea(decimal longs, decimal wide=0); } public class Rectangle : Calculate { public decimal CalculateArea(decimal longs,decimal wide) { decimal s = longs * wide; return s; } } public class Square : Calculate { public decimal CalculateArea(decimal longs, decimal wide) { decimal s = longs * longs; return s; } }
三、里氏替換原則(LSP)
子類型必須可替代其基類型 –一個對象出現的地方都可以由其子類代替並且不會出錯,即是符合里氏替換原則的。
Ex:
狗和鳥同時都具備很多相同特征,可以走、跑、叫,以鳥作為基類,狗作為子類,會出現子類不能替換基類的情況,基類鳥可以飛,但是子類狗不能。這樣不就符合里氏替換原則。可以考慮以狗走位基類,鳥作為子類,然后鳥擴展一個飛的屬性。或者兩者都作為子類,抽象出一個基類,動物類。滿足子類可以任意替換基類的情況都是符合里氏替換原則的。
class Program { static void Main(string[] args) { Animal animal = new Dog(); Console.WriteLine(animal.Walk()); Console.WriteLine(animal.Run()); Console.WriteLine(animal.Fly()); Console.WriteLine(animal.MakeNoise()); Console.ReadLine(); } } public class Animal { public string Walk() { return "Move feet"; } public string Run() { return "Move feet quickly"; } public virtual string Fly() { return null; } public virtual string MakeNoise() { return null; } } public class Dog : Animal { public override string MakeNoise() { return "Bark"; } } public class Bird : Animal { public override string MakeNoise() { return "Chirp"; } public override string Fly() { return "Flag wings"; } }
四、接口分離原則(ISP)
接口分離原則—client不應該被強迫依賴它不使用的方法,表明方法是分開或者隔離的。這個原則還強制實現高凝聚力,讓您更好地理解,更強大的類和低耦合,更容易維護,更容易抵抗變化(即不太可能引入錯誤)。
Ex:
public interface Animal { string Run(); string Fly(); } public class Dog : Animal { public string Fly() { return string.Empty; } public string Run() { return "小狗,快跑"; } } public class Bird : Animal { public string Fly() { return "小鳥,快飛"; } public string Run() { return "小鳥,快跑"; } }
在這段代碼中,鳥和狗同時繼承了動物,但是在狗實現接口的時候,Fly方法沒有做任何操作。這里顯然違背了接口分離原則,強迫了Dog類依賴了其Fly方法。
改進方法,可以將動物接口修改成兩個接口,AnimalFly接口和AnimalRun接口。這樣就遵循了其規則
五、依賴倒置原則(DIP)
依賴倒置原則-也是最后一個原則了。其原則指出—一個高級模塊不應依賴於低級模塊,兩個都應該取決於抽象。抽象不應該依賴具體細節,細節應該依賴於抽象。
在這里可以發現依賴倒置原則和前幾天講過的依賴注入的原則十分相似。
六、總結
SRP |
單一職責原則 |
一個類應只負責一件事情 |
OCP |
開放封閉原則 |
封閉修改,開放擴展 |
LSP |
里氏替換原則 |
一個對象可由其子類代替 |
ISP |
接口分離原則 |
客戶不應被強迫依賴它不使用的方法 |
DIP |
依賴反轉原則 |
抽象不依賴具體,具體依賴於抽象 |
S.O.L.I.D 原則是非常有價值的五大原則,在創建和設計一個應用的時候應用這些原則,你會創建一個非常優秀的項目。
歡迎大家掃描下方二維碼,和我一起學習更多的知識😊