开闭原则代码示例
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();}
}
一目了然。
原文:(45 封私信 / 10 条消息) C# 实例解释面向对象编程中的开闭原则 - 知乎