优秀的编程知识分享平台

网站首页 > 技术文章 正文

开发中的SOLID 模式

nanyue 2025-03-03 19:35:08 技术文章 10 ℃

SOLID 模式并不是一种单一的设计模式,而是由罗伯特·C·马丁(Robert C. Martin)在 21 世纪早期引入的五个面向对象编程和设计的基本原则的缩写,这五个原则旨在使软件系统更加易于维护、扩展和理解。以下是对 SOLID 中每个原则的详细介绍:

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

  • 定义:一个类应该只有一个引起它变化的原因。也就是说,一个类应该只负责一项职责。
  • 示例:假设有一个 User 类,它既负责用户信息的存储,又负责用户信息的验证和用户信息的持久化(如保存到数据库)。按照单一职责原则,我们应该将这些职责分离。可以创建一个 UserInfo 类来负责用户信息的存储,一个 UserValidator 类来负责用户信息的验证,一个 UserRepository 类来负责用户信息的持久化。
# 负责用户信息存储
class UserInfo:
    def __init__(self, name, email):
        self.name = name
        self.email = email

# 负责用户信息验证
class UserValidator:
    def validate(self, user_info):
        if not user_info.name or not user_info.email:
            return False
        return True

# 负责用户信息持久化
class UserRepository:
    def save(self, user_info):
        # 模拟保存到数据库
        print(f"Saving user {user_info.name} with email {user_info.email} to database.")

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

  • 定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着当需要添加新功能时,应该通过扩展现有代码来实现,而不是修改现有的代码。
  • 示例:假设有一个图形绘制程序,最初只有绘制圆形的功能。如果按照开闭原则设计,当需要添加绘制矩形的功能时,不应该修改原有的绘制圆形的代码。可以通过抽象出一个 Shape 基类,让圆形和矩形类继承自该基类,并实现各自的绘制方法。
from abc import ABC, abstractmethod

# 抽象基类
class Shape(ABC):
    @abstractmethod
    def draw(self):
        pass

# 圆形类
class Circle(Shape):
    def draw(self):
        print("Drawing a circle.")

# 矩形类
class Rectangle(Shape):
    def draw(self):
        print("Drawing a rectangle.")

# 绘制函数
def draw_shape(shape):
    shape.draw()

circle = Circle()
rectangle = Rectangle()

draw_shape(circle)
draw_shape(rectangle)

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

  • 定义:子类对象能够替换其父类对象,而程序的行为不会发生改变。也就是说,子类应该能够完全替代父类,并且不会破坏程序的正确性。
  • 示例:假设有一个 Bird 类,其中有一个 fly 方法。Sparrow 类继承自 Bird 类,并重写了 fly 方法。而 Ostrich 类虽然也继承自 Bird 类,但鸵鸟不会飞,所以不应该重写 fly 方法或者抛出异常,否则就违反了里氏替换原则。可以通过抽象出一个 FlyingBird 类来解决这个问题。
from abc import ABC, abstractmethod

# 抽象鸟类
class Bird(ABC):
    @abstractmethod
    def make_sound(self):
        pass

# 会飞的鸟类
class FlyingBird(Bird):
    @abstractmethod
    def fly(self):
        pass

# 麻雀类
class Sparrow(FlyingBird):
    def fly(self):
        print("Sparrow is flying.")

    def make_sound(self):
        print("Chirp chirp!")

# 鸵鸟类
class Ostrich(Bird):
    def make_sound(self):
        print("Boom boom!")

def make_bird_fly(bird):
    if isinstance(bird, FlyingBird):
        bird.fly()

sparrow = Sparrow()
ostrich = Ostrich()

make_bird_fly(sparrow)
# make_bird_fly(ostrich)  # 不会报错,因为鸵鸟不是 FlyingBird 类型

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

  • 定义:客户端不应该依赖它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。
  • 示例:假设有一个 Worker 接口,其中包含 work 和 eat 方法。但有些工人只需要工作,不需要吃饭(如机器人)。按照接口隔离原则,应该将 Worker 接口拆分为 Workable 和 Eatable 两个接口。
from abc import ABC, abstractmethod

# 工作接口
class Workable(ABC):
    @abstractmethod
    def work(self):
        pass

# 吃饭接口
class Eatable(ABC):
    @abstractmethod
    def eat(self):
        pass

# 人类工人类
class HumanWorker(Workable, Eatable):
    def work(self):
        print("Human worker is working.")

    def eat(self):
        print("Human worker is eating.")

# 机器人类
class RobotWorker(Workable):
    def work(self):
        print("Robot worker is working.")

human = HumanWorker()
robot = RobotWorker()

human.work()
human.eat()
robot.work()
# robot.eat()  # 会报错,因为 RobotWorker 没有实现 eat 方法

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

  • 定义:高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。
  • 示例:假设有一个 Light 类表示电灯,一个 Switch 类表示开关。如果 Switch 类直接依赖 Light 类,那么当需要添加其他电器(如风扇)时,就需要修改 Switch 类。按照依赖倒置原则,可以抽象出一个 Device 接口,让 Light 类和 Fan 类实现该接口,Switch 类依赖 Device 接口。
from abc import ABC, abstractmethod

# 设备接口
class Device(ABC):
    @abstractmethod
    def turn_on(self):
        pass

    @abstractmethod
    def turn_off(self):
        pass

# 电灯类
class Light(Device):
    def turn_on(self):
        print("Light is on.")

    def turn_off(self):
        print("Light is off.")

# 风扇类
class Fan(Device):
    def turn_on(self):
        print("Fan is on.")

    def turn_off(self):
        print("Fan is off.")

# 开关类
class Switch:
    def __init__(self, device):
        self.device = device

    def operate(self):
        self.device.turn_on()
        self.device.turn_off()

light = Light()
fan = Fan()

light_switch = Switch(light)
fan_switch = Switch(fan)

light_switch.operate()
fan_switch.operate()

遵循 SOLID 原则可以提高代码的可维护性、可扩展性和可测试性,使软件系统更加健壮和灵活。

最近发表
标签列表