本文档整理了面向对象设计的核心设计原则,并配以 Python 示例代码,旨在提高软件的可维护性、可复用性和灵活性。
定义:一个类或模块应当有且只有一个引起它变化的原因。简单来说,一个类只负责一项职责。
好处:
Python 示例:
# 违反 SRP 的写法:一个类既负责统计又负责输出
class Report:
def __init__(self, data):
self.data = data
def calculate_summary(self):
return sum(self.data) / len(self.data)
def export_pdf(self):
print("Exporting to PDF...")
# 遵循 SRP 的写法:将统计和输出分离
class Report:
def __init__(self, data):
self.data = data
def calculate_summary(self):
return sum(self.data) / len(self.data)
class PDFExporter:
def export(self, report):
print(f"Exporting summary {report.calculate_summary()} to PDF...")
定义:软件实体(类、模块、函数等)应当对扩展开放,对修改封闭。即在不修改原有代码的基础上,通过扩展来增加新功能。
好处:
Python 示例:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * (self.radius ** 2)
def calculate_total_area(shapes):
return sum(shape.area() for shape in shapes)
定义:子类必须能够替换掉它们的父类,且程序的行为保持不变。
核心:子类不能违反父类定义的契约(协议)。
Python 示例:
class Bird:
def fly(self):
print("Flying...")
class Sparrow(Bird):
def fly(self):
print("Sparrow flying...")
# 鸵鸟不会飞,如果强行继承 Bird 并重写 fly 抛错,则违反 LSP
class Ostrich(Bird):
def fly(self):
raise Exception("Ostrich cannot fly")
# 重构:将飞行的行为提取出来
class Bird(ABC):
pass
class FlyingBird(Bird):
def fly(self):
print("Flying...")
class Sparrow(FlyingBird):
pass
class Ostrich(Bird):
pass
定义:
好处:
Python 示例:
from abc import ABC, abstractmethod
class MessageSender(ABC):
@abstractmethod
def send(self, message):
pass
class EmailSender(MessageSender):
def send(self, message):
print(f"Sending email: {message}")
class NotificationService:
def __init__(self, sender: MessageSender):
self.sender = sender # 依赖于抽象
def notify(self, message):
self.sender.send(message)
定义:不应该强迫客户端依赖于它们不使用的接口。接口应当尽量细化,一个类对另一个类的依赖应该建立在最小的接口上。
Python 示例:
from abc import ABC, abstractmethod
# 违反 ISP:一个接口包含了所有动作
class Worker(ABC):
@abstractmethod
def work(self): pass
@abstractmethod
def eat(self): pass
# 遵循 ISP:拆分为更细的接口
class Workable(ABC):
@abstractmethod
def work(self): pass
class Eatable(ABC):
@abstractmethod
def eat(self): pass
class Robot(Workable):
def work(self):
print("Robot working...")
class Human(Workable, Eatable):
def work(self):
print("Human working...")
def eat(self):
print("Human eating...")
定义:尽量使用组合(Composition)或聚合(Aggregation),少用继承(Inheritance)。
核心:继承会破坏封装性(白盒复用),而组合通过委托实现功能复用(黑盒复用),耦合度更低。
Python 示例:
class Engine:
def start(self):
print("Engine starting...")
class Car:
def __init__(self):
self.engine = Engine() # 组合
def start(self):
print("Car starting...")
self.engine.start()
定义:一个对象应当对其他对象有尽可能少的了解。只与直接的朋友通信。
直接的朋友:
这些设计原则(SOLID + CARP + LoD)是设计模式的基石。在实际开发中,应根据具体业务场景灵活应用,过度设计往往适得其反,核心目标是:高内聚、低耦合。