SOLID 原则:单一职责原则 -> 是什么、为什么和怎么做。






4.87/5 (16投票s)
SOLID 原则:单一职责原则,C# 中的一个简单例子
介绍
本文将解释单一职责原则 (SRP),并展示一个 C# 中的简单例子。
背景
什么
一个类永远不应该有不止一个改变它的理由。SRP 是 SOLID 原则中最简单的,但也是最难做对的原则之一。将职责收集和聚集在一个地方是很常见的事情,并且会自然而然地发生。从彼此分离这些职责是软件设计的真正意义所在。
为什么?
当一个类有多个职责时,也有更多的触发器和原因去改变这个类。在这个上下文中,一个职责等同于“一个改变的原因”。对一个职责的更改可能会损害或抑制该类满足其他职责的能力。这种耦合会导致脆弱的设计,这些设计在更改时会以意想不到的方式崩溃。如果一个类有多个职责,那么这些职责就会耦合在一起。此外,当一个(功能性)职责被分成多个类时,所有属于该职责的类都必须更改。它们被困在变化的链条中。始终尝试给每个类赋予其自身独特的职责。
如何
可以通过为每个职责定义一个类或一个接口来分离职责。这没有任何区别,一个类可以被看作只是代码的容器,比如一个文件或一个库。重要的是职责通过抽象分离,因此可以由该接口的不同使用者实现。
Using the Code
以下 C# 示例展示了一个名为“RectangleShape
”的类,它实现了两种方法,一种计算其矩形面积,另一种绘制矩形。当面积计算由于某种原因发生变化或绘制方法需要更改时,例如使用了另一种填充颜色,则整个类都在更改之下。此外,如果属性被修改,它会影响这两种方法。在代码更改之后,该类必须作为一个整体再次进行测试。显然,更改这个类的原因不止一个。
问题
/// <summary>
/// Class calculates the area and can also draw it on a windows form object.
/// </summary>
public class RectangleShape
{
public int Height{ get; set; }
public int Width { get; set; }
public int Area()
{
return Width * Height;
}
public void Draw(Form form)
{
SolidBrush myBrush = new SolidBrush(System.Drawing.Color.Red);
Graphics formGraphics = form.CreateGraphics();
formGraphics.FillRectangle(myBrush, new Rectangle(0, 0, Width, Height);
}
}
通常,上述类由像这样的使用者客户端类使用
/// <summary>
/// Consumes the RectangleShape */
/// </summary>
public class GeometricsCalculator
{
public void CalculateArea(RectangleShape rectangleShape)
{
int area = rectangleShape.Area();
}
}
/// <summary>
//// Consumes the RectangleShape */
/// </summary>
public class GraphicsManager
{
public Form form {get;set;}
public void DrawOnScreen(RectangleShape rectangleShape)
{
rectangleShape.Draw(form);
}
}
解决方案
接下来的类展示了如何分离不同的职责。使用基本编码,不考虑其他 SOLID 原则。它只是展示了如何处理 SRP 原则。RectangleDraw
类现在使用 RectangleShape
实例和一个 Form
对象。
/// <summary>
/// Class calculates the rectangle's area.
/// </summary>
public class RectangleShape
{
public int Height { get; set; }
public int Width { get; set; }
public int Area()
{
return Width * Height;
}
}
/// <summary>
/// Class draws a rectangle on a windows form object.
/// </summary>
public class RectangleDraw
{
public void Draw(Form form, RectangleShape rectangleShape)
{
SolidBrush myBrush = new SolidBrush(System.Drawing.Color.Red);
Graphics formGraphics = form.CreateGraphics();
formGraphics.FillRectangle(myBrush,
new Rectangle(0, 0, rectangleShape.Width,rectangleShape.Height));
}
}
以下代码展示了如何使用这两个类
/// <summary>
/// Consumes the RectangleShape */
/// </summary>
public class GeometricsCalculator
{
public void CalculateArea(RectangleShape rectangleShape)
{
int area = rectangleShape.Area();
}
}
/// <summary>
/// Consumes the RectangleDraw and RectangleShape */
/// </summary>
public class GraphicsManager
{
public Form form { get; set; }
public void DrawOnScreen(RectangleDraw rectangleDraw, RectangleShape rectangleShape)
{
rectangleDraw.Draw(form, rectangleShape);
}
}
玩得开心!