掌握 SOLID 让你的代码更优雅、更易维护!

SOLID 是面向对象编程(OOP)的五大设计原则,它有助于编写 可维护、可扩展、可读性高 的代码。


🌟 SOLID 五大原则

原则含义关键点
S - 单一职责原则(SRP)一个类只做一件事,只对一个变化原因负责降低耦合,提高可维护性
O - 开闭原则(OCP)对扩展开放,对修改关闭通过 新增代码 而不是修改已有代码来扩展功能
L - 里氏替换原则(LSP)子类可以替换父类,程序逻辑不变继承要符合父类行为
I - 接口隔离原则(ISP)接口要小而精,不要让类实现不需要的接口避免臃肿的接口
D - 依赖倒置原则(DIP)依赖抽象,而不是具体实现降低耦合,提高扩展性

🔹 1. 单一职责原则(SRP - Single Responsibility Principle)

“一个类只负责一件事”

❌ 不遵循 SRP(违反单一职责)

class Report:
    def generate_report(self):
        print("生成报告")
    
    def save_to_file(self):
        print("将报告保存到文件")
    
    def send_email(self):
        print("发送报告邮件")

📌 问题

  • 这个类既负责生成报告、又负责存储、还负责发送邮件,职责太多,导致耦合严重。

✅ 遵循 SRP(拆分类)

class ReportGenerator:
    def generate(self):
        print("生成报告")

class ReportSaver:
    def save(self):
        print("将报告保存到文件")

class ReportSender:
    def send(self):
        print("发送报告邮件")

改进:拆分成多个单一职责类,每个类只负责一件事,更易维护。


🔹 2. 开闭原则(OCP - Open/Closed Principle)

“对扩展开放,对修改关闭”
添加新功能时,尽量不修改已有代码,而是扩展它!

❌ 违反 OCP(修改已有代码)

class PaymentProcessor:
    def pay(self, method):
        if method == "credit_card":
            print("使用信用卡支付")
        elif method == "paypal":
            print("使用 PayPal 支付")

📌 问题

  • 如果要增加 “微信支付”,就必须修改 pay() 方法,违反 OCP

✅ 遵循 OCP(使用抽象扩展)

from abc import ABC, abstractmethod

class PaymentMethod(ABC):
    @abstractmethod
    def pay(self):
        pass

class CreditCardPayment(PaymentMethod):
    def pay(self):
        print("使用信用卡支付")

class PayPalPayment(PaymentMethod):
    def pay(self):
        print("使用 PayPal 支付")

class PaymentProcessor:
    def __init__(self, method: PaymentMethod):
        self.method = method
    
    def process_payment(self):
        self.method.pay()

改进新增支付方式 只需 创建新类,而不需要修改 PaymentProcessor 代码。


🔹 3. 里氏替换原则(LSP - Liskov Substitution Principle)

“子类必须能替换父类,而不会破坏程序逻辑”

❌ 违反 LSP(子类破坏父类逻辑)

class Bird:
    def fly(self):
        print("我会飞")

class Penguin(Bird):
    def fly(self):
        raise Exception("企鹅不会飞!")

📌 问题

  • Penguin 继承了 Bird,但它不能飞,如果代码依赖 Bird.fly(),就可能崩溃!

✅ 遵循 LSP(合理的继承关系)

class Bird:
    pass

class FlyingBird(Bird):
    def fly(self):
        print("我会飞")

class NonFlyingBird(Bird):
    def walk(self):
        print("我不会飞,但我会走")

class Sparrow(FlyingBird):
    pass

class Penguin(NonFlyingBird):
    pass

改进

  • Bird 拆分成 会飞的鸟不会飞的鸟,避免 Penguin.fly() 崩溃。

🔹 4. 接口隔离原则(ISP - Interface Segregation Principle)

“接口要小而精,不要让类实现不需要的接口”

❌ 违反 ISP(接口太大)

class Animal:
    def eat(self):
        pass

    def fly(self):
        pass  # 🐶 狗不会飞,但必须实现它(无意义)

class Dog(Animal):
    def eat(self):
        print("狗在吃东西")

    def fly(self):
        raise Exception("狗不会飞")

📌 问题

  • Dog 被迫实现 fly() 方法,这个方法对它毫无意义!

✅ 遵循 ISP(拆分接口)

class Eatable:
    def eat(self):
        pass

class Flyable:
    def fly(self):
        pass

class Dog(Eatable):
    def eat(self):
        print("狗在吃东西")

class Bird(Eatable, Flyable):
    def eat(self):
        print("鸟在吃东西")

    def fly(self):
        print("鸟在飞")

改进

  • Dog 只实现 EatableBird 既能 eat() 又能 fly()避免不必要的方法

🔹 5. 依赖倒置原则(DIP - Dependency Inversion Principle)

“高层模块不应该依赖低层模块,而应该依赖抽象”

❌ 违反 DIP(依赖具体实现)

class MySQLDatabase:
    def connect(self):
        print("连接 MySQL")

class UserRepository:
    def __init__(self):
        self.db = MySQLDatabase()  # 直接依赖 MySQL

    def get_user(self):
        self.db.connect()
        print("查询用户")

📌 问题

  • UserRepository 绑定了 MySQLDatabase,如果换成 PostgreSQL,就必须修改 UserRepository

✅ 遵循 DIP(依赖抽象)

from abc import ABC, abstractmethod

class Database(ABC):
    @abstractmethod
    def connect(self):
        pass

class MySQLDatabase(Database):
    def connect(self):
        print("连接 MySQL")

class PostgreSQLDatabase(Database):
    def connect(self):
        print("连接 PostgreSQL")

class UserRepository:
    def __init__(self, db: Database):
        self.db = db  # 依赖抽象(接口)

    def get_user(self):
        self.db.connect()
        print("查询用户")

改进

  • UserRepository 依赖 Database 接口,可以随时换数据库,而不用改 UserRepository 代码。

📌 总结

原则关键思想示例
S - 单一职责一个类只做一件事生成报告 ≠ 存储 ≠ 发送
O - 开闭原则扩展新功能时,不修改原代码PaymentProcessor 依赖抽象支付方式
L - 里氏替换子类可以替换父类,不影响程序运行Penguin 不能 fly()
I - 接口隔离接口要小,不强迫类实现不需要的功能Dog 没有 fly()
D - 依赖倒置依赖抽象,而不是具体实现UserRepository 依赖 Database

🚀 掌握 SOLID 让你的代码更优雅、更易维护!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值