[S] Single Responsibility Principle (單一職責原則) 認為一個對象應該僅只有一個單一的職責 復制代碼 namespace SingleResponsibilityPrinciple { class DataAccess { void InsertData() { Console.WriteLine("數據插入成功"); } // 錯誤的設計,不符合 單一職責原則 //void WriteLog() //{ // Console.WriteLine("日志插入成功"); //} } // 應該把不同的職責交給不同的對象處理 class Logger { void WriteLog() { Console.WriteLine("日志插入成功"); } } } 復制代碼 [o] Open Close Principle (開閉原則) 認為軟件應該是對擴展開放的,而對修改是關閉的 復制代碼 namespace OpenClosePrinciple { abstract class DataProvider { public abstract void OpenConnection(); public abstract void CloseConnection(); public abstract void ExecuteCommand(); } // MS SQL class SqlDataProvider:DataProvider { public override void OpenConnection() { Console.WriteLine("打開Sql數據連接"); } public override void CloseConnection() { Console.WriteLine("關閉Sql數據連接"); } public override void ExecuteCommand() { Console.WriteLine("執行Sql數據命令"); } } // ORACLE class OracleDataProvider:DataProvider { public override void OpenConnection() { Console.WriteLine("打開Oracle數據連接"); } public override void CloseConnection() { Console.WriteLine("關閉Oracle數據連接"); } public override void ExecuteCommand() { Console.WriteLine("執行Oracle數據命令"); } } class Start { void Invoke() { DataProvider dataProvider = new SqlDataProvider(); dataProvider.OpenConnection(); dataProvider.ExecuteCommand(); dataProvider.CloseConnection(); dataProvider = new OracleDataProvider(); dataProvider.OpenConnection(); dataProvider.ExecuteCommand(); dataProvider.CloseConnection(); } } } 復制代碼 [L] Liskov Substitution Principle(裡氏替換原則) 認為程序中的對象應該是可以在不改變程序正確性的前提下被它的子類所替換的 復制代碼 namespace LiskovSubstitutionPrinciple { class Rectangle { protected int width = 0; protected int height = 0; public virtual void SetWidth(int width) { this.width = width; } public virtual void SetHeight(int height) { this.height = height; } public virtual int GetArea() { return this.width * this.height; } } class Square : Rectangle { public override void SetHeight(int height) { this.height = height; this.width = height; } public override void SetWidth(int width) { this.height = width; this.width = width; } } class Start { public static Rectangle CreateInstance(int condition = 1) { if (condition == 1) { return new Rectangle(); } else { return new Square(); } } public static void Invoke() { Rectangle rectangleObject = CreateInstance(); rectangleObject.SetHeight(10); rectangleObject.SetWidth(20); rectangleObject.GetArea(); } } } 復制代碼 [I] Interface Segregation Principle(接口分離原則) 認為多個特定客戶端接口要好於一個寬泛用途的接口,也有單一職責的意思 復制代碼 namespace InterfaceSegregationPrinciple { interface IDataProvider { void OpenConnection(); void CloseConnection(); } interface ISqlDataProvider : IDataProvider { void ExecuteSqlCommand(); } interface IOracleDataProvider : IDataProvider { void ExecuteOracleCommand(); } class SqlDataProvider : ISqlDataProvider { public void ExecuteSqlCommand() { Console.WriteLine("執行Sql數據命令"); } public void OpenConnection() { Console.WriteLine("打開Sql數據連接"); } public void CloseConnection() { Console.WriteLine("關閉Sql數據連接"); } } class OracleDataProvider : IOracleDataProvider { public void ExecuteOracleCommand() { Console.WriteLine("執行Oracle數據命令"); } public void OpenConnection() { Console.WriteLine("打開Oracle數據連接"); } public void CloseConnection() { Console.WriteLine("關閉Oracle數據連接"); } } class Start { public void Invoke() { ISqlDataProvider sqlDataProvider = new SqlDataProvider(); sqlDataProvider.OpenConnection(); sqlDataProvider.ExecuteSqlCommand(); sqlDataProvider.CloseConnection(); IOracleDataProvider oracleDataprovider = new OracleDataProvider(); oracleDataprovider.OpenConnection(); oracleDataprovider.ExecuteOracleCommand(); oracleDataprovider.CloseConnection(); } } } 復制代碼 [D] Dependency Inversion Principle(依賴反轉原則) 認為一個方法應該遵從依賴於抽象而不是一個實例,控制反轉,依賴注入是該原則的一種實現 復制代碼 namespace DependencyInversionPrinciple { interface IBankAccount { long BankNumber { get; set; } // 卡號 decimal Balance { get; set; } // 余額 } // 轉賬人 interface ITransferSource : IBankAccount { void CutPayment(decimal value); } // 收款人 interface ITransferDestination : IBankAccount { void AddMoney(decimal value); } class BankAccout : IBankAccount, ITransferSource, ITransferDestination { public long BankNumber { get; set; } public decimal Balance { get; set; } public void CutPayment(decimal value) { Balance -= value; } public void AddMoney(decimal value) { Balance += value; } } class TransferAmount { public decimal Amount { get; set; } public void Transfer(ITransferSource source, ITransferDestination dest) { source.CutPayment(Amount); dest.AddMoney(Amount); } } class Start { void Invoke() { ITransferSource source = new BankAccout { Balance = 10000, BankNumber = 111 }; ITransferDestination dest = new BankAccout { Balance = 1, BankNumber = 222 }; TransferAmount transfer = new TransferAmount(); transfer.Amount = 9999; // 轉多少錢 transfer.Transfer(source, dest); // 開始轉賬 // 這是用依賴反轉的思維做一個銀行轉賬的功能,使銀行賬戶可以依賴ITransferSource,ITransferDestination // 而不是以前直接 BankAccout account = new BankAccout();大大增加了賬戶這個核心對象的靈活性 // 這個例子基本上有SOLID原則的所有身影 } } // 附上一個普通版的 做下對比,用中文名做變量,通俗易懂吧 class 銀行賬戶 { public int 卡號 { get; set; } public decimal 余額 { get; set; } public void 存入(decimal value) { 余額 += value; } public void 支出(decimal value) { 余額 -= value; } } class 銀行轉賬操作 //ATM { public 銀行賬戶 轉賬人 { get; set; } public 銀行賬戶 收款人 { get; set; } public decimal 金額 { get; set; } public void 轉賬() { 轉賬人.支出(金額); 收款人.存入(金額); } } class Start1 { public void Main() { 銀行賬戶 張三 = new 銀行賬戶 { 卡號 = 111, 余額 = 10000 }; 銀行賬戶 李四 = new 銀行賬戶 { 卡號 = 222, 余額 = 5 }; 銀行轉賬操作 轉賬 = new 銀行轉賬操作(); 轉賬.金額 = 1000; 轉賬.轉賬人 = 張三; 轉賬.收款人 = 李四; 轉賬.轉賬(); } } } 復制代碼 SOLID設計原則是個老生常談的話題了,在博客園居然沒找到良好的代碼實現,所以就自己參考網上的資料寫了這麼一篇博客,技術含量不高,給新手看的,包括我,個人認為掌握了這五點設計原則,並熟練運用於自己的系統中還是得花點時間的。反正我的觀點就是:業務領域驅動設計原則。如果你不熟悉業務領域,你根本發揮不了這其中的優點,你會認為這樣做反而麻煩了,但是又對於什麼設計原則什麼設計模式出於崇高的敬意,把網上書上的那些例子照著敲一遍二遍三遍。。。你會的也只不過是會寫各種原則,模式的代碼模板而已。so,學習設計模式的好方法是先弄懂一套業務領域的邏輯,然後在用你學到的設計模式的思想去挑刺兒。領域驅動模式設計給了我很大的啟發,先敬畏業務領域,再敬畏軟件設計,最後敬畏代碼。當然平時也要用敬畏之心去看待事物。