系统设计时应时刻考虑设计模式基础原则
目录
- :star2:单一职责原则 (Single Responsibility Principle, SRP)
- :star2:开放-封闭原则 (Open-Closed Principle, OCP)
- :star2:依赖倒转原则 (Dependency Inversion Principle, DIP)
- :star2:里氏代换原则 (Liskov Substitution Principle, LSP)
- :star2:迪米特原则 (Law of Demeter, LoD)
🌟单一职责原则 (Single Responsibility Principle, SRP)
定义:一个类应该只有一个引起变化的原因。
含义:每个类只负责完成一种功能。如果一个类承担了多种职责,则这些职责之间可能会互相影响,导致代码难以维护。
优点:
降低类的复杂性。
提高代码的可读性和可维护性。
更容易进行单元测试。
示例:
// 违反单一职责原则
public class ReportManager {
public void GenerateReport() { /* 生成报表逻辑 */ }
public void PrintReport() { /* 打印报表逻辑 */ }
}
// 符合单一职责原则
public class ReportGenerator {
public void GenerateReport() { /* 生成报表逻辑 */ }
}
public class ReportPrinter {
public void PrintReport() { /* 打印报表逻辑 */ }
}
🌟开放-封闭原则 (Open-Closed Principle, OCP)
定义:软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。
含义:在不修改原有代码的情况下,通过扩展功能满足新的需求。
优点:
减少因为修改代码引发的错误。
提升代码的灵活性和可扩展性。
示例:
// 违反开放-封闭原则
public class PaymentProcessor {
public void ProcessPayment(string paymentType) {
if (paymentType == "CreditCard") { /* 信用卡支付逻辑 */ }
else if (paymentType == "PayPal") { /* PayPal 支付逻辑 */ }
}
}
// 符合开放-封闭原则
public interface IPayment {
void Process();
}
public class CreditCardPayment : IPayment {
public void Process() { /* 信用卡支付逻辑 */ }
}
public class PayPalPayment : IPayment {
public void Process() { /* PayPal 支付逻辑 */ }
}
public class PaymentProcessor {
public void ProcessPayment(IPayment payment) {
payment.Process();
}
}
🌟依赖倒转原则 (Dependency Inversion Principle, DIP)
定义:高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
含义:通过依赖接口或抽象类,减少模块之间的耦合。
优点:
提高代码的灵活性和可测试性。
减少模块之间的依赖。
示例:
// 违反依赖倒转原则
public class Keyboard {
public void Type() { /* 输入逻辑 */ }
}
public class Computer {
private Keyboard _keyboard = new Keyboard();
}
// 符合依赖倒转原则
public interface IInputDevice {
void Type();
}
public class Keyboard : IInputDevice {
public void Type() { /* 输入逻辑 */ }
}
public class Computer {
private IInputDevice _inputDevice;
public Computer(IInputDevice inputDevice) {
_inputDevice = inputDevice;
}
}
🌟里氏代换原则 (Liskov Substitution Principle, LSP)
定义:子类应该能够替换基类,并且在应用中表现一致。
含义:确保子类不会破坏基类的功能。在实现继承时,子类必须能够正确替代父类。
优点:
保证系统的行为一致性。
避免因继承引入错误。
示例:
// 违反里氏代换原则
public class Rectangle {
public virtual void SetWidth(int width) { }
public virtual void SetHeight(int height) { }
}
public class Square : Rectangle {
public override void SetWidth(int width) { /* 改变行为,导致宽高不一致 */ }
}
// 符合里氏代换原则
public abstract class Shape {
public abstract int Area();
}
public class Rectangle : Shape {
public int Width { get; set; }
public int Height { get; set; }
public override int Area() => Width * Height;
}
public class Square : Shape {
public int Side { get; set; }
public override int Area() => Side * Side;
}
🌟迪米特原则 (Law of Demeter, LoD)
定义:一个对象应该对其他对象有最少的了解。
含义:尽量减少类之间的直接耦合,通过中间类或方法传递信息。
优点:
降低对象之间的耦合性。
提高代码的模块化。
示例:
// 违反迪米特原则
public class Engine {
public void Start() { }
}
public class Car {
public Engine Engine { get; set; }
}
public class Driver {
public void Drive(Car car) {
car.Engine.Start(); // Driver 直接访问 Engine
}
}
// 符合迪米特原则
public class Engine {
public void Start() { }
}
public class Car {
private Engine _engine = new Engine();
public void StartEngine() {
_engine.Start();
}
}
public class Driver {
public void Drive(Car car) {
car.StartEngine(); // Driver 通过 Car 访问 Engine
}
}