C#面向對象編程中的開閉原則是什么
這篇“C#面向對象編程中的開閉原則是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C#面向對象編程中的開閉原則是什么”文章吧。
開閉原則
在面向對象編程領域中,開閉原則?(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
現在,這些類的設計,既遵循了單一功能原則,又遵循了開閉原則。
以上就是關于“C#面向對象編程中的開閉原則是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注蝸牛博客行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:niceseo99@gmail.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。
評論