概述: SOLID 原则是一组五项设计原则,旨在使软件设计更易于理解、灵活和易于维护。如果正确应用这些原则,可以产生干净而健壮的代码。在本文中,我们将深入探讨每个 SOLID 原则,并提供 C# 中的实际示例。单一责任原则 (SRP)单一责任原则指出,一个类应该只有一个改变的理由。换句话说,一个类应该有一个单一的责任。合规示例:public class Order { public void CreateOrder(OrderDetails orderDetails) { // Create an order based on the provided deta
SOLID 原则是一组五项设计原则,旨在使软件设计更易于理解、灵活和易于维护。如果正确应用这些原则,可以产生干净而健壮的代码。在本文中,我们将深入探讨每个 SOLID 原则,并提供 C# 中的实际示例。
单一责任原则 (SRP)
单一责任原则指出,一个类应该只有一个改变的理由。换句话说,一个类应该有一个单一的责任。
推荐示例:
public classOrder
{
publicvoidCreateOrder(OrderDetails orderDetails)
{
// Create an order based on the provided details
}
}
public classOrderPrinter
{
publicvoidPrintOrder(Order order)
{
// Print the order
}
}
不推荐示例:
public classOrder
{
publicvoidCreateOrder(OrderDetails orderDetails)
{
// Create an order based on the provided details
// And print the order in this method
}
}
在合规示例中,该类负责创建订单,该类负责打印订单。但是,在冲突示例中,类有两个职责,这使得维护变得更加困难。OrderOrderPrinterOrder
开/闭原理 (OCP)
开放/封闭原则指出,软件实体(类、模块、函数等)应该开放以进行扩展,但对修改应该关闭。
推荐示例:
publicabstract classShape
{
publicabstractdoubleArea();
}
public classCircle : Shape
{
publicdouble Radius { get; set; }
publicoverridedoubleArea() => Math.PI \* Radius \* Radius;
}
public classRectangle : Shape
{
publicdouble Width { get; set; }
publicdouble Height { get; set; }
publicoverridedoubleArea() => Width \* Height;
}
不推荐示例:
public classAreaCalculator
{
publicdoubleCalculateArea(object shape)
{
if (shape isCircle circle)
{
return Math.PI * circle.Radius * circle.Radius;
}
elseif (shape isRectangle rectangle)
{
return rectangle.Width * rectangle.Height;
}
// Adding new shapes requires modifying this class
return0;
}
}
在合规示例中,层次结构是开放的,可以扩展,因为您可以通过创建新的子类来轻松添加新形状,而无需修改现有代码。相比之下,冲突示例要求每次添加新形状时修改类。ShapeAreaCalculator
里氏替代原则 (LSP)
Liskov 替换原则指出,超类的对象应该可以用子类的对象替换,而不会影响程序的正确性。
推荐示例:
public classBird
{
publicvirtualvoidFly() { /* Common flying behavior */ }
}
public classSparrow : Bird
{
publicoverridevoidFly() { /* Sparrow-specific flying behavior */ }
}
public classOstrich : Bird
{
publicoverridevoidFly() { /* Ostrich-specific behavior (non-flying) */ }
}
不推荐示例:
public classBird
{
publicvoidFly() { /* Common flying behavior */ }
}
public classOstrich : Bird
{
publicnewvoidFly() { /* Ostrich-specific behavior (non-flying) */ }
}
在兼容的示例中,and 类都扩展了类并根据需要重写了方法。在违规示例中,我们必须使用关键字来隐藏基类方法,这违反了 Liskov 替换原则。SparrowOstrichBirdFlynew
接口隔离原则 (ISP)
接口隔离原则指出,不应强制客户端依赖它们不使用的接口。
推荐示例:
publicinterfaceIWorker
{
voidWork();
}
publicinterfaceIEater
{
voidEat();
}
public classWorker : IWorker
{
publicvoidWork() { /* Working behavior */ }
}
public classSuperWorker : IWorker, IEater
{
publicvoidWork() { /* Working behavior */ }
publicvoidEat() { /* Eating behavior */ }
}
不推荐示例:
publicinterfaceIWorker
{
voidWork();
voidEat();
}
public classWorker : IWorker
{
publicvoidWork() { /* Working behavior */ }
publicvoidEat() { /* Eating behavior (unnecessary for this class) */ }
}
在兼容的示例中,该类同时实现 和 接口,而该类仅实现 .在冲突示例中,类被强制实现该方法,即使它不需要它。SuperWorkerIWorkerIEaterWorkerIWorkerWorkerEat
依赖关系反转原理 (DIP)
依赖倒置原则指出,高级模块不应依赖于低级模块。两者都应该依赖于抽象。
推荐示例:
publicinterfaceIMessageSender
{
voidSendMessage(string message);
}
public classEmailSender : IMessageSender
{
publicvoidSendMessage(string message)
{
// Send the message via email
}
}
public classNotificationService
{
privateIMessageSender _messageSender;
publicNotificationService(IMessageSender messageSender)
{
_messageSender = messageSender;
}
publicvoidSendNotification(string message)
{
_messageSender.SendMessage(message);
}
}
不推荐示例:
public classEmailSender
{
publicvoidSendEmail(string email, string message)
{
// Send an email
}
}
public classNotificationService
{
privateEmailSender _emailSender;
publicNotificationService(EmailSender emailSender)
{
_emailSender = emailSender;
}
publicvoidSendNotification(string email, string message)
{
_emailSender.SendEmail(email, message);
}
}
在兼容示例中,取决于接口,这允许轻松替换不同的消息发送实现。在冲突示例中,与类紧密耦合,因此更难更改消息发送机制。
结论
理解和应用 SOLID 原则可以生成更易于维护和可扩展的代码。通过遵循这些原则,您可以创建更易于测试、重构和扩展的软件,最终产生更强大、适应性更强的代码库。
如果你喜欢我的文章,请给我一个赞!谢谢