C# 设计模式的七大原则
1、单一职责原则-SRP (Single Responsibility Principle)
单一职责原则要求一个类应该只有一个引起变化的原因,即一个类只负责一项功能。这有助于保持类的简洁性和可维护性,降低代码的复杂度。
点击查看 ->【SRP】举例代码
// 交通工具类
public class Vehicle
{
public string Brand { get; set; } // 品牌
public string Model { get; set; } // 型号
public void GasUp(double liters)
{
// 加油的实现
}
}
// 遵循SRP的实现:
// 分离汽车的品牌和型号
public class CarModel
{
public string Brand { get; set; }
public string Model { get; set; }
}
// 分离汽车的加油功能
public class CarGasStation
{
public void GasUp(CarModel carModel, double liters)
{
// 加油的实现
}
}
2、开放封闭原则-OCP(Open Closed Principle)
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。
点击查看 ->【OCP】举例代码
// 定义一个动物接口
public interface IAnimal
{
void MakeSound();
}
// 实现一个具体的动物类 - 狗
public class Dog : IAnimal
{
public void MakeSound()
{
Console.WriteLine("汪汪汪!");
}
}
// 实现一个具体的动物类 - 猫
public class Cat : IAnimal
{
public void MakeSound()
{
Console.WriteLine("喵喵喵!");
}
}
// 使用动物的方法
public class Zoo
{
public void FeedAnimals(IAnimal[] animals)
{
foreach (var animal in animals)
{
animal.MakeSound();
}
}
}
// 在客户端代码中使用
public class Program
{
static void Main(string[] args)
{
IAnimal[] animals = new IAnimal[] { new Dog(), new Cat() };
Zoo zoo = new Zoo();
zoo.FeedAnimals(animals);
}
}
3、里氏替换原则-LSP(Liskov Substitution Principle)
是面向对象设计的基本原则之一。其核心思想是:任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开放封闭原则”的补充。实现“开放封闭原则”的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以“里氏替换原则”是对实现抽象化的具体步骤的规范。
点击查看 ->【LSP】举例代码
// 长方形
public class Rectangle
{
protected int width; // 宽
protected int height; // 高
public virtual int Area() // 计算面积
{
return width * height;
}
}
// 正方形
public class Square : Rectangle
{
public Square(int size)
{
width = size;
height = size;
}
public override int Area()
{
return width * height; // 这里不能保证正确性,因为width和height可能被外部修改,导致不相等
}
}
//在这个例子中,Square类继承自Rectangle类,但是Square类中的Area方法不符合里氏代换原则,因为它可能返回错误的面积值(如果width和height不相等)
//修改后满足LSP的代码可以是:
public class Rectangle
{
public virtual int Area()
{
return width * height;
}
protected int width;
protected int height;
}
public class Square : Rectangle
{
private int side;
public Square(int size)
{
side = size;
}
public override int Area()
{
return side * side; // 正确返回正方形的面积
}
}
4、依赖反转原则-DIP(Dependence Inversion Principle)
是面向对象编程中的一个基本原则,其核心思想是:要依赖于抽象,不要依赖于具体实现。简单来说,就是要尽量使用接口或抽象类进行变量的类型声明、方法的参数声明、方法的返回类型声明,以及数据类型的转换等,而不是具体的类。
点击查看 ->【DIP】举例代码
// 假设有一个发送消息的接口
public interface ISender
{
void Send(string message);
}
// 具体的邮件发送器
public class EmailSender : ISender
{
public void Send(string message)
{
// 实现发送邮件的逻辑
Console.WriteLine("Email sent with message: " + message);
}
}
// 具体的短信发送器
public class SmsSender : ISender
{
public void Send(string message)
{
// 实现发送短信的逻辑
Console.WriteLine("SMS sent with message: " + message);
}
}
// 使用发送器的类
public class Notifier
{
private ISender sender;
public Notifier(ISender sender)
{
this.sender = sender;
}
public void SendNotification(string message)
{
sender.Send(message);
}
}
// 客户端代码
public class Program
{
public static void Main(string[] args)
{
// 使用具体的发送器实例化Notifier
Notifier notifier = new Notifier(new EmailSender());
notifier.SendNotification("Welcome to our service!");
// 可以很容易地更换发送器而不影响其他代码
notifier = new Notifier(new SmsSender());
notifier.SendNotification("Welcome to our service!");
}
}
5、接口隔离原则-ISP(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
点击查看 ->【ISP】举例代码
// 假设有一个庞大的接口
public interface IHugeInterface
{
void Method1();
void Method2();
void Method3();
void Method4();
// ... 其他方法
}
// 使用接口隔离原则重构上面的接口
public interface IInterface1
{
void Method1();
void Method2();
}
public interface IInterface2
{
void Method3();
void Method4();
}
// 实现类只需要实现它需要的接口
public class MyClass : IInterface1, IInterface2
{
public void Method1() { /* 实现 */ }
public void Method2() { /* 实现 */ }
public void Method3() { /* 实现 */ }
public void Method4() { /* 实现 */ }
}
//在这个例子中,IHugeInterface 接口包含了很多方法,但是 MyClass 只需要实现它需要的方法。通过定义多个小接口 IInterface1 和 IInterface2,MyClass 可以只实现它所需要的方法,这样就满足了接口隔离原则。
6、最少知道原则-LKP(Least Knowledge Principle)
又叫做【迪米特法则-LOD(Law Of Demeter)】,为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
点击查看 ->【LKP】举例代码
public class Computer {
private CPU cpu;
public Computer() {
cpu = new CPU();
}
public void Start() {
cpu.Process();
}
}
public class CPU {
public void Process() {
Console.WriteLine("CPU is processing.");
}
}
public class User {
public static void Main(string[] args) {
Computer computer = new Computer();
computer.Start();
}
}
//在这个例子中,Computer 类应该尽可能少地了解 CPU 类的实现细节。Computer 类只需要知道 CPU 类提供了一个 Process 方法用于处理任务,而不需要知道 CPU 是如何处理的。这样的设计遵循了最少知识原则,因为 Computer 类尽量减少了对 CPU 类内部细节的了解。
7、合成复用原则-CRP(Composite Reuse Principle)
原则是尽量使用 合成/聚合/组合 的方式,而不是使用继承。
点击查看 ->【CRP】举例代码
public class Component
{
public void Operation()
{
Console.WriteLine("这是一个基础操作。");
}
}
public class CompositeClass
{
private Component _component;
public CompositeClass()
{
_component = new Component();
}
public void OperationWrapper()
{
Console.WriteLine("这是一个封装操作的方法。");
_component.Operation();
}
}
class Program
{
static void Main(string[] args)
{
CompositeClass composite = new CompositeClass();
composite.OperationWrapper();
}
}
//在这个例子中,CompositeClass 类中包含了一个 Component 类的实例 _component。CompositeClass 类通过其方法 OperationWrapper() 封装了对 _component.Operation() 的调用,同时还添加了一些额外的处理逻辑。这样,CompositeClass 复用了 Component 类的功能,而不是通过继承来强制实现。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具