C#七大设计原则
·
C#的七大设计原则是面向对象编程中非常重要的指导原则,它们帮助开发者创建可维护、可扩展、灵活的代码。下面我将详细解释这些原则并提供示例。
SOLID原则
1. 单一职责原则 (Single Responsibility Principle, SRP)
定义:一个类应该只有一个引起它变化的原因,即一个类只负责一项职责。
示例:
// 不符合SRP
public class User
{
public void Register() { /* 注册逻辑 */ }
public void Login() { /* 登录逻辑 */ }
public void WriteLog() { /* 日志记录 */ }
}
// 符合SRP
public class User
{
public void Register() { /* 注册逻辑 */ }
public void Login() { /* 登录逻辑 */ }
}
public class Logger
{
public void WriteLog() { /* 日志记录 */ }
}
2. 开放封闭原则 (Open-Closed Principle, OCP)
定义:软件实体应该对扩展开放,对修改关闭。
示例:
// 不符合OCP
public class AreaCalculator
{
public double CalculateArea(object shape)
{
if (shape is Rectangle)
{
Rectangle r = (Rectangle)shape;
return r.Width * r.Height;
}
else if (shape is Circle)
{
Circle c = (Circle)shape;
return 3.14 * c.Radius * c.Radius;
}
// 每次新增形状都需要修改这个类
return 0;
}
}
// 符合OCP
public abstract class Shape
{
public abstract double CalculateArea();
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double CalculateArea()
{
return Width * Height;
}
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double CalculateArea()
{
return 3.14 * Radius * Radius;
}
}
3. 里氏替换原则 (Liskov Substitution Principle, LSP)
定义:子类必须能够替换其基类而不影响程序的正确性。
示例:
// 不符合LSP
public class Bird
{
public virtual void Fly() { Console.WriteLine("Flying"); }
}
public class Penguin : Bird
{
public override void Fly()
{
throw new NotSupportedException("Penguins can't fly");
}
}
// 符合LSP
public abstract class Bird
{
public abstract void Move();
}
public class FlyingBird : Bird
{
public override void Move() { Console.WriteLine("Flying"); }
}
public class Penguin : Bird
{
public override void Move() { Console.WriteLine("Swimming"); }
}
4. 接口隔离原则 (Interface Segregation Principle, ISP)
定义:客户端不应该被迫依赖于它不使用的方法。
示例:
// 不符合ISP
public interface IWorker
{
void Work();
void Eat();
void Sleep();
}
public class HumanWorker : IWorker
{
public void Work() { /* 工作 */ }
public void Eat() { /* 吃饭 */ }
public void Sleep() { /* 睡觉 */ }
}
public class RobotWorker : IWorker
{
public void Work() { /* 工作 */ }
public void Eat() { throw new NotImplementedException(); }
public void Sleep() { throw new NotImplementedException(); }
}
// 符合ISP
public interface IWorkable
{
void Work();
}
public interface IFeedable
{
void Eat();
}
public interface IRestable
{
void Sleep();
}
public class HumanWorker : IWorkable, IFeedable, IRestable
{
public void Work() { /* 工作 */ }
public void Eat() { /* 吃饭 */ }
public void Sleep() { /* 睡觉 */ }
}
public class RobotWorker : IWorkable
{
public void Work() { /* 工作 */ }
}
5. 依赖倒置原则 (Dependency Inversion Principle, DIP)
定义:高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
示例:
// 不符合DIP
public class LightBulb
{
public void TurnOn() { Console.WriteLine("LightBulb on"); }
}
public class Switch
{
private LightBulb _bulb;
public Switch() { _bulb = new LightBulb(); }
public void Press() { _bulb.TurnOn(); }
}
// 符合DIP
public interface ISwitchableDevice
{
void TurnOn();
}
public class LightBulb : ISwitchableDevice
{
public void TurnOn() { Console.WriteLine("LightBulb on"); }
}
public class Fan : ISwitchableDevice
{
public void TurnOn() { Console.WriteLine("Fan on"); }
}
public class Switch
{
private ISwitchableDevice _device;
public Switch(ISwitchableDevice device) { _device = device; }
public void Press() { _device.TurnOn(); }
}
其他两大原则
6. 合成复用原则 (Composite Reuse Principle, CRP)
定义:优先使用对象组合而非继承来达到复用的目的。
示例:
// 不符合CRP - 使用继承
public class Engine
{
public void Start() { Console.WriteLine("Engine started"); }
}
public class Car : Engine
{
public void Drive() { Start(); Console.WriteLine("Car driving"); }
}
// 符合CRP - 使用组合
public class Engine
{
public void Start() { Console.WriteLine("Engine started"); }
}
public class Car
{
private Engine _engine;
public Car() { _engine = new Engine(); }
public void Drive() { _engine.Start(); Console.WriteLine("Car driving"); }
}
7. 迪米特原则 (Law of Demeter, LoD)
定义:一个对象应该对其他对象保持最少的了解,只与直接的朋友通信。
示例:
// 不符合LoD
public class Paper
{
public string Content { get; set; }
}
public class Printer
{
public void Print(Paper paper)
{
Console.WriteLine(paper.Content);
}
}
public class Person
{
public Paper Paper { get; set; }
}
public class Office
{
public void PrintDocument(Person person)
{
Printer printer = new Printer();
// 直接访问person的paper的content,违反了迪米特原则
printer.Print(person.Paper);
}
}
// 符合LoD
public class Paper
{
public string Content { get; set; }
public void Print()
{
Console.WriteLine(Content);
}
}
public class Person
{
private Paper _paper;
public Person(Paper paper) { _paper = paper; }
public void PrintDocument()
{
_paper.Print();
}
}
public class Office
{
public void PrintDocument(Person person)
{
person.PrintDocument();
}
}
七大设计原则总结表
| 原则名称 | 英文名称 | 核心思想 | 主要目的 | C#实现方式 | 常见应用场景 |
|---|---|---|---|---|---|
| 单一职责原则 | Single Responsibility Principle (SRP) | 一个类只负责一项职责 | 降低类的复杂度,提高可读性和可维护性 | 将功能拆分到不同的类中 | 用户管理、日志记录、数据处理等 |
| 开放封闭原则 | Open-Closed Principle (OCP) | 对扩展开放,对修改关闭 | 提高代码的可扩展性和稳定性 | 使用抽象类、接口和多态 | 支付系统、插件架构、算法实现等 |
| 里氏替换原则 | Liskov Substitution Principle (LSP) | 子类必须能替换基类 | 确保继承的正确性,避免程序错误 | 正确使用继承,不破坏基类行为 | 形状计算、动物行为、设备控制等 |
| 接口隔离原则 | Interface Segregation Principle (ISP) | 客户端不应依赖不使用的接口 | 降低接口的复杂性,提高灵活性 | 将大接口拆分为小接口 | 工作流系统、权限管理、设备操作等 |
| 依赖倒置原则 | Dependency Inversion Principle (DIP) | 依赖抽象而非具体实现 | 降低模块间的耦合度 | 使用依赖注入、接口编程 | 数据库访问、服务调用、配置管理等 |
| 合成复用原则 | Composite Reuse Principle (CRP) | 优先使用组合而非继承 | 提高代码的灵活性和复用性 | 使用组合关系代替继承关系 | 引擎系统、UI组件、功能模块等 |
| 迪米特原则 | Law of Demeter (LoD) | 只与直接的朋友通信 | 降低类之间的耦合度 | 通过方法调用而非直接访问属性 | 系统集成、第三方库使用、模块通信等 |
这些设计原则不是孤立的,它们相互关联、相互支持。在实际开发中,应该根据具体情况灵活应用这些原则,而不是生搬硬套。合理使用这些原则可以帮助我们设计出更加健壮、灵活和可维护的软件系统。
更多推荐


所有评论(0)