您好,登錄后才能下訂單哦!
這篇“C#面向對象編程中的開閉原則是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“C#面向對象編程中的開閉原則是什么”文章吧。
在面向對象編程領域中,開閉原則 (open-closed principle, OCP) 規定“軟件中的對象(類,模塊,函數等等)應該對于擴展是開放的,而對于修改是封閉的”,這意味著一個實體是允許在不改變它的源代碼的前提下變更它的行為。該特性在產品化的環境中是特別有價值的,在這種環境中,改變源代碼需要代碼審查,單元測試以及諸如此類的用以確保產品使用品質的過程。遵循開閉原則的代碼在擴展時并不發生改變,因此無需這些過程。
具體到類,也就是說,在不修改類本身代碼的情況下,應該是可以擴展它的行為的。
讓我們回顧一下上一篇文章單一功能原則中提到的 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#面向對象編程中的開閉原則是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。