網站首頁 編程語言 正文
在面向對象編程中,SOLID?是五個設計原則的首字母縮寫,旨在使軟件設計更易于理解、靈活和可維護。這些原則是由美國軟件工程師和講師羅伯特·C·馬丁(Robert Cecil Martin)提出的許多原則的子集,在他2000年的論文《設計原則與設計模式》中首次提出。
SOLID 原則包含:
- S:單一功能原則(single-responsibility principle)
- O:開閉原則(open-closed principle)
- L:里氏替換原則(Liskov substitution principle)
- I:接口隔離原則(Interface segregation principle)
- D:依賴反轉原則(Dependency inversion principle)
本文我們來介紹開閉原則。
開閉原則
在面向對象編程領域中,開閉原則?(open-closed principle, OCP)?規定“軟件中的對象(類,模塊,函數等等)應該對于擴展是開放的,而對于修改是封閉的”,這意味著一個實體是允許在不改變它的源代碼的前提下變更它的行為。該特性在產品化的環境中是特別有價值的,在這種環境中,改變源代碼需要代碼審查,單元測試以及諸如此類的用以確保產品使用品質的過程。遵循開閉原則的代碼在擴展時并不發生改變,因此無需這些過程。
具體到類,也就是說,在不修改類本身代碼的情況下,應該是可以擴展它的行為的。
C# 示例
讓我們回顧一下上一篇文章單一功能原則中提到的?AreaCalculator?類,
class AreaCalculator { private List<object> _shapes; public AreaCalculator(List<object> shapes) { _shapes = shapes; } /// <summary> /// 計算所有形狀的面積總和 /// </summary> /// <returns></returns> public double Sum() { List<double> areas = new List<double>(); foreach (var item in _shapes) { if (item is Square s) { areas.Add(Math.Pow(s.SideLength, 2)); } else if (item is Circle c) { areas.Add(Math.PI * Math.Pow(c.Radius, 2)); } } return areas.Sum(); } }
對于上面的計算方法,考慮這樣一種場景,用戶想要計算一些其它形狀的面積總和,比如三角形、矩形、五邊形等等…… 您將不得不反復編輯此類以添加更多的?if/else
?塊,這就違反了開閉原則。
改進
一個更好的做法是,將計算每個形狀的面積的邏輯從?AreaCalculator?類中移除,并將其添加到對應每個形狀的類中。我們可以定義一個帶有?CalcArea
?方法的接口?IShape,然后讓每個形狀都實現這個接口。
接口?IShape:
interface IShape { /// <summary> /// 計算面積 /// </summary> /// <returns></returns> double CalcArea(); }
修改后的?Square?和?Circle?類:
/// <summary> /// 正方形 /// </summary> class Square : IShape { public Square(double length) { SideLength = length; } public double SideLength { get; init; } public double CalcArea() { return Math.Pow(SideLength, 2); } } /// <summary> /// 圓形 /// </summary> class Circle : IShape { public Circle(double radius) { Radius = radius; } public double Radius { get; init; } public double CalcArea() { return Math.PI * Math.Pow(Radius, 2); } }
AreaCalculator?類也要對應做一些修改:
class AreaCalculator { private List<IShape> _shapes; public AreaCalculator(List<IShape> shapes) { _shapes = shapes; } /// <summary> /// 計算面積總和 /// </summary> /// <returns></returns> public double Sum() { List<double> areas = new List<double>(); foreach (var item in _shapes) { areas.Add(item.CalcArea()); } return areas.Sum(); } }
此時,如果我們有一個新的形狀需要進行計算,我們可以直接添加一個實現了接口?IShape?的新類,而無需修改?AreaCalculator?類的代碼,比如添加一個長方形類:
/// <summary> /// 長方形 /// </summary> class Rectangle : IShape { public Rectangle(double width, double height) { Width = width; Height = height; } public double Width { get; init; } public double Height { get; init; } public double CalcArea() { return Width * Height; } }
處理輸出格式的?SumCalculatorOutputter?類同樣無需修改:
class SumCalculatorOutputter { protected AreaCalculator _calculator; public SumCalculatorOutputter(AreaCalculator calculator) { _calculator = calculator; } public string String() { return $"Sum of the areas of provided shapes: {_calculator.Sum()}"; } public string JSON() { var data = new { Sum = _calculator.Sum() }; return System.Text.Json.JsonSerializer.Serialize(data); } }
然后,我們修改?Main
?方法中的代碼來測試一下:
static void Main(string[] args) { var shapes = new List<IShape> { new Circle(2), new Square(5), new Rectangle(2,3) }; var areaCalculator = new AreaCalculator(shapes); var outputer = new SumCalculatorOutputter(areaCalculator); Console.WriteLine(outputer.JSON()); Console.WriteLine(outputer.String()); }
運行一下,輸出結果為:
{"Sum":43.56637061435917}
Sum of the areas of provided shapes: 43.56637061435917
現在,這些類的設計,既遵循了單一功能原則,又遵循了開閉原則。
總結
本文我介紹了 SOLID 原則中的開閉原則?(open-closed principle),并通過 C# 代碼示例簡明地詮釋了它的含意和實現,希望對您有所幫助。
參考文檔:
https://www.digitalocean.com/community/conceptual_articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
原文鏈接:https://www.cnblogs.com/ittranslator/p/SOLID-open-closed-principle.html
相關推薦
- 2022-04-18 python全面解析接口返回數據_python
- 2022-01-25 項目啟動的時候報Exception in thread main 錯誤解決方法
- 2022-10-31 解讀Python腳本的常見參數獲取和處理方式_python
- 2022-03-26 .Net?Core微服務rpc框架GRPC通信基礎_基礎應用
- 2023-06-16 pytest中的fixture基本用法_python
- 2022-05-22 使用Redis實現點贊取消點贊的詳細代碼_Redis
- 2022-06-01 python畫立方體--魔方_python
- 2022-08-16 Oracle數據庫事務的開啟與結束詳解_oracle
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支