| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- from abc import ABC, abstractmethod
- from typing import List, Protocol
- """
- Lec 3: 设计原则 (Design Principles)
- 这些代码示例展示了 SOLID 原则及其他核心设计原则在 Python 中的实现。
- """
- # -----------------------------------------------------------------------------
- # 1. 单一职责原则 (Single Responsibility Principle, SRP)
- # -----------------------------------------------------------------------------
- class Report:
- """负责数据逻辑的类"""
- def __init__(self, data: List[float]):
- self.data = data
- def calculate_summary(self) -> float:
- return sum(self.data) / len(self.data) if self.data else 0.0
- class PDFExporter:
- """负责 PDF 导出的类"""
- def export(self, report: Report, filepath: str):
- summary = report.calculate_summary()
- print(f"[PDF] 导出摘要: {summary} 到文件: {filepath}")
- class HTMLExporter:
- """负责 HTML 导出的类"""
- def export(self, report: Report, filepath: str):
- summary = report.calculate_summary()
- print(f"[HTML] 导出摘要: {summary} 到文件: {filepath}")
- # -----------------------------------------------------------------------------
- # 2. 开放-封闭原则 (Open-Closed Principle, OCP)
- # -----------------------------------------------------------------------------
- class Shape(ABC):
- @abstractmethod
- def area(self) -> float:
- pass
- class Rectangle(Shape):
- def __init__(self, width: float, height: float):
- self.width = width
- self.height = height
- def area(self) -> float:
- return self.width * self.height
- class Circle(Shape):
- def __init__(self, radius: float):
- self.radius = radius
- def area(self) -> float:
- import math
- return math.pi * (self.radius ** 2)
- def print_areas(shapes: List[Shape]):
- """对扩展开放:可以添加新形状而无需修改此函数"""
- for shape in shapes:
- print(f"Shape area: {shape.area()}")
- # -----------------------------------------------------------------------------
- # 3. 里氏替换原则 (Liskov Substitution Principle, LSP)
- # -----------------------------------------------------------------------------
- class Bird(ABC):
- pass
- class FlyingBird(Bird):
- @abstractmethod
- def fly(self):
- pass
- class NonFlyingBird(Bird):
- pass
- class Sparrow(FlyingBird):
- def fly(self):
- print("麻雀正在飞翔...")
- class Ostrich(NonFlyingBird):
- def run(self):
- print("鸵鸟正在奔跑...")
- # -----------------------------------------------------------------------------
- # 4. 依赖倒置原则 (Dependency Inversion Principle, DIP)
- # -----------------------------------------------------------------------------
- class MessageSender(ABC):
- @abstractmethod
- def send(self, message: str):
- pass
- class EmailSender(MessageSender):
- def send(self, message: str):
- print(f"发送邮件通知: {message}")
- class SMSSender(MessageSender):
- def send(self, message: str):
- print(f"发送短信通知: {message}")
- class NotificationService:
- def __init__(self, sender: MessageSender):
- # 依赖于抽象接口 MessageSender,而不是具体的 EmailSender 或 SMSSender
- self.sender = sender
- def notify(self, message: str):
- self.sender.send(message)
- # -----------------------------------------------------------------------------
- # 5. 接口隔离原则 (Interface Segregation Principle, ISP)
- # -----------------------------------------------------------------------------
- class Workable(Protocol):
- def work(self) -> None: ...
- class Eatable(Protocol):
- def eat(self) -> None: ...
- class Human(Workable, Eatable):
- def work(self) -> None:
- print("人类在工作...")
- def eat(self) -> None:
- print("人类在吃饭...")
- class Robot(Workable):
- def work(self) -> None:
- print("机器人在工作...")
- # -----------------------------------------------------------------------------
- # 6. 合成/聚合复用原则 (Composite/Aggregate Reuse Principle, CARP)
- # -----------------------------------------------------------------------------
- class Engine:
- def start(self):
- print("发动机已启动")
- class Car:
- def __init__(self, engine: Engine):
- # 使用组合而非继承
- self.engine = engine
- def start(self):
- print("汽车准备出发...")
- self.engine.start()
- # -----------------------------------------------------------------------------
- # 7. 迪米特法则 (Law of Demeter, LoD)
- # -----------------------------------------------------------------------------
- class Teacher:
- def command(self, group_leader):
- # 老师只下令给组长,不直接接触学生
- group_leader.count_students()
- class GroupLeader:
- def __init__(self, students):
- self.students = students
- def count_students(self):
- print(f"学生总人数: {len(self.students)}")
- # -----------------------------------------------------------------------------
- # 演示运行
- # -----------------------------------------------------------------------------
- if __name__ == "__main__":
- print("--- SRP ---")
- my_report = Report([10.5, 20.0, 15.5])
- pdf_exp = PDFExporter()
- pdf_exp.export(my_report, "data.pdf")
- print("\n--- OCP ---")
- shapes = [Rectangle(10, 5), Circle(7)]
- print_areas(shapes)
- print("\n--- LSP ---")
- sparrow = Sparrow()
- sparrow.fly()
- print("\n--- DIP ---")
- service = NotificationService(SMSSender())
- service.notify("您有一条新消息")
- print("\n--- ISP ---")
- worker = Robot()
- worker.work()
- print("\n--- CARP ---")
- engine = Engine()
- my_car = Car(engine)
- my_car.start()
- print("\n--- LoD ---")
- students = ["Alice", "Bob", "Charlie"]
- leader = GroupLeader(students)
- teacher = Teacher()
- teacher.command(leader)
|