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();
}
}
一目了然。