文章
Python 23种设计模式
一、创建型模式 (5种)
1. 单例模式 (Singleton)
意图:确保一个类只有一个实例,并提供全局访问点。
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
print("Creating the singleton instance")
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
def show_message(self):
print("Hello, I am a Singleton!")
# 使用示例
if __name__ == "__main__":
# 创建单例对象
singleton1 = Singleton()
singleton1.show_message()
# 再次获取实例,验证是否为同一个对象
singleton2 = Singleton()
singleton2.show_message()
print(f"Is same instance? {singleton1 is singleton2}")
2. 工厂方法模式 (Factory Method)
意图:定义一个创建对象的接口,但让子类决定实例化哪个类。
from abc import ABC, abstractmethod
# 产品接口
class Product(ABC):
@abstractmethod
def use(self):
pass
# 具体产品A
class ConcreteProductA(Product):
def use(self):
print("Using Product A")
# 具体产品B
class ConcreteProductB(Product):
def use(self):
print("Using Product B")
# 工厂接口
class Factory(ABC):
@abstractmethod
def create_product(self) -> Product:
pass
def some_operation(self):
product = self.create_product()
product.use()
# 具体工厂A
class ConcreteFactoryA(Factory):
def create_product(self) -> Product:
return ConcreteProductA()
# 具体工厂B
class ConcreteFactoryB(Factory):
def create_product(self) -> Product:
return ConcreteProductB()
# 使用示例
if __name__ == "__main__":
factory_a = ConcreteFactoryA()
factory_a.some_operation()
factory_b = ConcreteFactoryB()
factory_b.some_operation()
3. 抽象工厂模式 (Abstract Factory)
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
from abc import ABC, abstractmethod
# 抽象产品A
class AbstractProductA(ABC):
@abstractmethod
def use(self):
pass
# 抽象产品B
class AbstractProductB(ABC):
@abstractmethod
def eat(self):
pass
# 具体产品A1
class ProductA1(AbstractProductA):
def use(self):
print("Using Product A1")
# 具体产品A2
class ProductA2(AbstractProductA):
def use(self):
print("Using Product A2")
# 具体产品B1
class ProductB1(AbstractProductB):
def eat(self):
print("Eating Product B1")
# 具体产品B2
class ProductB2(AbstractProductB):
def eat(self):
print("Eating Product B2")
# 抽象工厂
class AbstractFactory(ABC):
@abstractmethod
def create_product_a(self) -> AbstractProductA:
pass
@abstractmethod
def create_product_b(self) -> AbstractProductB:
pass
# 具体工厂1
class ConcreteFactory1(AbstractFactory):
def create_product_a(self) -> AbstractProductA:
return ProductA1()
def create_product_b(self) -> AbstractProductB:
return ProductB1()
# 具体工厂2
class ConcreteFactory2(AbstractFactory):
def create_product_a(self) -> AbstractProductA:
return ProductA2()
def create_product_b(self) -> AbstractProductB:
return ProductB2()
# 使用示例
if __name__ == "__main__":
factory1 = ConcreteFactory1()
product_a1 = factory1.create_product_a()
product_b1 = factory1.create_product_b()
product_a1.use()
product_b1.eat()
factory2 = ConcreteFactory2()
product_a2 = factory2.create_product_a()
product_b2 = factory2.create_product_b()
product_a2.use()
product_b2.eat()
4. 建造者模式 (Builder)
意图:将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。
from abc import ABC, abstractmethod
# 产品类
class Computer:
def __init__(self):
self.cpu = None
self.ram = None
self.storage = None
self.gpu = None
def __str__(self):
return f"Computer(cpu={self.cpu}, ram={self.ram}, storage={self.storage}, gpu={self.gpu})"
# 抽象建造者
class ComputerBuilder(ABC):
@abstractmethod
def build_cpu(self):
pass
@abstractmethod
def build_ram(self):
pass
@abstractmethod
def build_storage(self):
pass
@abstractmethod
def build_gpu(self):
pass
@abstractmethod
def get_computer(self) -> Computer:
pass
# 具体建造者 - 游戏电脑
class GamingComputerBuilder(ComputerBuilder):
def __init__(self):
self.computer = Computer()
def build_cpu(self):
self.computer.cpu = "Intel i9"
def build_ram(self):
self.computer.ram = "32GB DDR4"
def build_storage(self):
self.computer.storage = "1TB SSD + 2TB HDD"
def build_gpu(self):
self.computer.gpu = "NVIDIA RTX 3080"
def get_computer(self) -> Computer:
return self.computer
# 具体建造者 - 办公电脑
class OfficeComputerBuilder(ComputerBuilder):
def __init__(self):
self.computer = Computer()
def build_cpu(self):
self.computer.cpu = "Intel i5"
def build_ram(self):
self.computer.ram = "16GB DDR4"
def build_storage(self):
self.computer.storage = "512GB SSD"
def build_gpu(self):
self.computer.gpu = "Integrated Graphics"
def get_computer(self) -> Computer:
return self.computer
# 指挥者
class ComputerDirector:
def construct(self, builder: ComputerBuilder) -> Computer:
builder.build_cpu()
builder.build_ram()
builder.build_storage()
builder.build_gpu()
return builder.get_computer()
# 使用示例
if __name__ == "__main__":
director = ComputerDirector()
# 构建游戏电脑
gaming_builder = GamingComputerBuilder()
gaming_computer = director.construct(gaming_builder)
print("Gaming Computer:", gaming_computer)
# 构建办公电脑
office_builder = OfficeComputerBuilder()
office_computer = director.construct(office_builder)
print("Office Computer:", office_computer)
5. 原型模式 (Prototype)
意图:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
import copy
from abc import ABC, abstractmethod
# 抽象原型类
class Shape(ABC):
def __init__(self):
self.id = None
self.type = None
@abstractmethod
def draw(self):
pass
def clone(self):
return copy.deepcopy(self)
def get_type(self):
return self.type
def get_id(self):
return self.id
def set_id(self, id):
self.id = id
# 具体原型类 - 矩形
class Rectangle(Shape):
def __init__(self):
super().__init__()
self.type = "Rectangle"
def draw(self):
print("Inside Rectangle::draw() method.")
# 具体原型类 - 圆形
class Circle(Shape):
def __init__(self):
super().__init__()
self.type = "Circle"
def draw(self):
print("Inside Circle::draw() method.")
# 原型管理器
class ShapeCache:
_shape_map = {}
@classmethod
def get_shape(cls, shape_id):
cached_shape = cls._shape_map.get(shape_id)
return cached_shape.clone()
@classmethod
def load_cache(cls):
circle = Circle()
circle.set_id("1")
cls._shape_map[circle.get_id()] = circle
rectangle = Rectangle()
rectangle.set_id("2")
cls._shape_map[rectangle.get_id()] = rectangle
# 使用示例
if __name__ == "__main__":
ShapeCache.load_cache()
cloned_shape1 = ShapeCache.get_shape("1")
print("Shape:", cloned_shape1.get_type())
cloned_shape1.draw()
cloned_shape2 = ShapeCache.get_shape("2")
print("Shape:", cloned_shape2.get_type())
cloned_shape2.draw()
# 验证是否为不同对象
print("Are shapes same?", cloned_shape1 is cloned_shape2)
二、结构型模式 (7种)
6. 适配器模式 (Adapter)
意图:将一个类的接口转换成客户希望的另外一个接口。
from abc import ABC, abstractmethod
# 目标接口
class MediaPlayer(ABC):
@abstractmethod
def play(self, audio_type: str, file_name: str):
pass
# 适配者接口
class AdvancedMediaPlayer(ABC):
@abstractmethod
def play_vlc(self, file_name: str):
pass
@abstractmethod
def play_mp4(self, file_name: str):
pass
# 具体适配者 - VLC播放器
class VlcPlayer(AdvancedMediaPlayer):
def play_vlc(self, file_name: str):
print(f"Playing vlc file. Name: {file_name}")
def play_mp4(self, file_name: str):
pass
# 具体适配者 - MP4播放器
class Mp4Player(AdvancedMediaPlayer):
def play_vlc(self, file_name: str):
pass
def play_mp4(self, file_name: str):
print(f"Playing mp4 file. Name: {file_name}")
# 适配器类
class MediaAdapter(MediaPlayer):
def __init__(self, audio_type: str):
if audio_type.lower() == "vlc":
self.advanced_music_player = VlcPlayer()
elif audio_type.lower() == "mp4":
self.advanced_music_player = Mp4Player()
def play(self, audio_type: str, file_name: str):
if audio_type.lower() == "vlc":
self.advanced_music_player.play_vlc(file_name)
elif audio_type.lower() == "mp4":
self.advanced_music_player.play_mp4(file_name)
# 具体目标类 - 音频播放器
class AudioPlayer(MediaPlayer):
def play(self, audio_type: str, file_name: str):
if audio_type.lower() == "mp3":
print(f"Playing mp3 file. Name: {file_name}")
elif audio_type.lower() in ("vlc", "mp4"):
media_adapter = MediaAdapter(audio_type)
media_adapter.play(audio_type, file_name)
else:
print(f"Invalid media. {audio_type} format not supported")
# 使用示例
if __name__ == "__main__":
audio_player = AudioPlayer()
audio_player.play("mp3", "beyond the horizon.mp3")
audio_player.play("mp4", "alone.mp4")
audio_player.play("vlc", "far far away.vlc")
audio_player.play("avi", "mind me.avi")
7. 桥接模式 (Bridge)
意图:将抽象部分与实现部分分离,使它们都可以独立地变化。
from abc import ABC, abstractmethod
# 实现部分接口
class DrawAPI(ABC):
@abstractmethod
def draw_circle(self, radius: int, x: int, y: int):
pass
# 具体实现A
class RedCircle(DrawAPI):
def draw_circle(self, radius: int, x: int, y: int):
print(f"Drawing Circle[ color: red, radius: {radius}, x: {x}, y: {y}]")
# 具体实现B
class GreenCircle(DrawAPI):
def draw_circle(self, radius: int, x: int, y: int):
print(f"Drawing Circle[ color: green, radius: {radius}, x: {x}, y: {y}]")
# 抽象部分
class Shape:
def __init__(self, draw_api: DrawAPI):
self.draw_api = draw_api
def draw(self):
pass
# 扩展抽象部分 - 圆形
class Circle(Shape):
def __init__(self, x: int, y: int, radius: int, draw_api: DrawAPI):
super().__init__(draw_api)
self.x = x
self.y = y
self.radius = radius
def draw(self):
self.draw_api.draw_circle(self.radius, self.x, self.y)
# 使用示例
if __name__ == "__main__":
red_circle = Circle(100, 100, 10, RedCircle())
green_circle = Circle(200, 200, 20, GreenCircle())
red_circle.draw()
green_circle.draw()
8. 组合模式 (Composite)
意图:将对象组合成树形结构以表示"部分-整体"的层次结构
from abc import ABC, abstractmethod
from typing import List
# 组件接口
class Employee(ABC):
@abstractmethod
def show_employee_details(self):
pass
# 叶子节点 - 开发人员
class Developer(Employee):
def __init__(self, name: str, position: str):
self.name = name
self.position = position
def show_employee_details(self):
print(f"Developer: {self.name}, Position: {self.position}")
# 叶子节点 - 经理
class Manager(Employee):
def __init__(self, name: str, position: str):
self.name = name
self.position = position
def show_employee_details(self):
print(f"Manager: {self.name}, Position: {self.position}")
# 组合类 - 部门
class Department(Employee):
def __init__(self, name: str):
self.name = name
self.employees: List[Employee] = []
def add_employee(self, employee: Employee):
self.employees.append(employee)
def remove_employee(self, employee: Employee):
self.employees.remove(employee)
def show_employee_details(self):
print(f"Department: {self.name}")
for employee in self.employees:
employee.show_employee_details()
# 使用示例
if __name__ == "__main__":
dev1 = Developer("John", "Senior Developer")
dev2 = Developer("David", "Junior Developer")
engineering = Department("Engineering")
engineering.add_employee(dev1)
engineering.add_employee(dev2)
man1 = Manager("Mike", "Engineering Manager")
man2 = Manager("Sophia", "HR Manager")
hr = Department("Human Resources")
hr.add_employee(man2)
company = Department("Company")
company.add_employee(man1)
company.add_employee(engineering)
company.add_employee(hr)
company.show_employee_details()
9. 装饰器模式 (Decorator)
意图:动态地给一个对象添加一些额外的职责。
from abc import ABC, abstractmethod
# 组件接口
class Car(ABC):
@abstractmethod
def assemble(self):
pass
# 具体组件
class BasicCar(Car):
def assemble(self):
print("Basic Car.")
# 装饰器抽象类
class CarDecorator(Car):
def __init__(self, car: Car):
self.car = car
def assemble(self):
self.car.assemble()
# 具体装饰器 - 运动型
class SportsCar(CarDecorator):
def assemble(self):
super().assemble()
print("Adding features of Sports Car.")
# 具体装饰器 - 豪华型
class LuxuryCar(CarDecorator):
def assemble(self):
super().assemble()
print("Adding features of Luxury Car.")
# 使用示例
if __name__ == "__main__":
sports_car = SportsCar(BasicCar())
sports_car.assemble()
print()
sports_luxury_car = SportsCar(LuxuryCar(BasicCar()))
sports_luxury_car.assemble()
10. 外观模式 (Facade)
意图:为子系统中的一组接口提供一个一致的界面。
# 子系统A
class CPU:
def freeze(self):
print("CPU freeze")
def jump(self, position: int):
print(f"CPU jump to {position}")
def execute(self):
print("CPU execute")
# 子系统B
class Memory:
def load(self, position: int, data: str):
print(f"Memory load at {position}")
# 子系统C
class HardDrive:
def read(self, lba: int, size: int) -> str:
print(f"HardDrive read {size} bytes from {lba}")
return "data"
# 外观类
class ComputerFacade:
BOOT_ADDRESS = 0x00000000
BOOT_SECTOR = 0x00000000
SECTOR_SIZE = 512
def __init__(self):
self.processor = CPU()
self.ram = Memory()
self.hd = HardDrive()
def start(self):
self.processor.freeze()
self.ram.load(self.BOOT_ADDRESS, self.hd.read(self.BOOT_SECTOR, self.SECTOR_SIZE))
self.processor.jump(self.BOOT_ADDRESS)
self.processor.execute()
# 使用示例
if __name__ == "__main__":
computer = ComputerFacade()
computer.start()
11. 享元模式 (Flyweight)
意图:运用共享技术有效地支持大量细粒度的对象。
import random
from typing import Dict
# 享元接口
class Shape:
def draw(self, x: int, y: int, radius: int):
pass
# 具体享元类
class Circle(Shape):
def __init__(self, color: str):
self.color = color
def draw(self, x: int, y: int, radius: int):
print(f"Circle: Draw() [Color: {self.color}, x: {x}, y: {y}, radius: {radius}]")
# 享元工厂
class ShapeFactory:
_circle_map: Dict[str, Circle] = {}
@classmethod
def get_circle(cls, color: str) -> Circle:
circle = cls._circle_map.get(color)
if circle is None:
circle = Circle(color)
cls._circle_map[color] = circle
print(f"Creating circle of color: {color}")
return circle
# 使用示例
if __name__ == "__main__":
colors = ["Red", "Green", "Blue", "White", "Black"]
for _ in range(20):
circle = ShapeFactory.get_circle(random.choice(colors))
circle.draw(random.randint(0, 100), random.randint(0, 100), 100)
12. 代理模式 (Proxy)
意图:为其他对象提供一种代理以控制对这个对象的访问。
from abc import ABC, abstractmethod
# 接口
class Image(ABC):
@abstractmethod
def display(self):
pass
# 真实对象
class RealImage(Image):
def __init__(self, file_name: str):
self.file_name = file_name
self._load_from_disk()
def _load_from_disk(self):
print(f"Loading {self.file_name}")
def display(self):
print(f"Displaying {self.file_name}")
# 代理类
class ProxyImage(Image):
def __init__(self, file_name: str):
self.file_name = file_name
self.real_image = None
def display(self):
if self.real_image is None:
self.real_image = RealImage(self.file_name)
self.real_image.display()
# 使用示例
if __name__ == "__main__":
image = ProxyImage("test_10mb.jpg")
# 图像将从磁盘加载
image.display()
print()
# 图像不需要从磁盘加载
image.display()
三、行为型模式 (11种)
13. 责任链模式 (Chain of Responsibility)
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系
from abc import ABC, abstractmethod
# 抽象处理器
class Logger(ABC):
INFO = 1
DEBUG = 2
ERROR = 3
def __init__(self, level: int):
self.level = level
self.next_logger = None
def set_next_logger(self, next_logger):
self.next_logger = next_logger
def log_message(self, level: int, message: str):
if self.level <= level:
self.write(message)
if self.next_logger is not None:
self.next_logger.log_message(level, message)
@abstractmethod
def write(self, message: str):
pass
# 具体处理器 - 控制台日志
class ConsoleLogger(Logger):
def write(self, message: str):
print(f"Standard Console::Logger: {message}")
# 具体处理器 - 错误日志
class ErrorLogger(Logger):
def write(self, message: str):
print(f"Error Console::Logger: {message}")
# 具体处理器 - 文件日志
class FileLogger(Logger):
def write(self, message: str):
print(f"File::Logger: {message}")
# 使用示例
if __name__ == "__main__":
def get_chain_of_loggers() -> Logger:
error_logger = ErrorLogger(Logger.ERROR)
file_logger = FileLogger(Logger.DEBUG)
console_logger = ConsoleLogger(Logger.INFO)
error_logger.set_next_logger(file_logger)
file_logger.set_next_logger(console_logger)
return error_logger
logger_chain = get_chain_of_loggers()
logger_chain.log_message(Logger.INFO, "This is an information.")
print()
logger_chain.log_message(Logger.DEBUG, "This is a debug level information.")
print()
logger_chain.log_message(Logger.ERROR, "This is an error information.")
14. 命令模式 (Command)
意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。
from abc import ABC, abstractmethod
from typing import List
# 命令接口
class Order(ABC):
@abstractmethod
def execute(self):
pass
# 请求类
class Stock:
def __init__(self):
self.name = "ABC"
self.quantity = 10
def buy(self):
print(f"Stock [ Name: {self.name}, Quantity: {self.quantity} ] bought")
def sell(self):
print(f"Stock [ Name: {self.name}, Quantity: {self.quantity} ] sold")
# 具体命令 - 买入
class BuyStock(Order):
def __init__(self, stock: Stock):
self.stock = stock
def execute(self):
self.stock.buy()
# 具体命令 - 卖出
class SellStock(Order):
def __init__(self, stock: Stock):
self.stock = stock
def execute(self):
self.stock.sell()
# 调用者
class Broker:
def __init__(self):
self.order_list: List[Order] = []
def take_order(self, order: Order):
self.order_list.append(order)
def place_orders(self):
for order in self.order_list:
order.execute()
self.order_list.clear()
# 使用示例
if __name__ == "__main__":
abc_stock = Stock()
buy_stock_order = BuyStock(abc_stock)
sell_stock_order = SellStock(abc_stock)
broker = Broker()
broker.take_order(buy_stock_order)
broker.take_order(sell_stock_order)
broker.place_orders()
15. 解释器模式 (Interpreter)
意图:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
from abc import ABC, abstractmethod
# 表达式接口
class Expression(ABC):
@abstractmethod
def interpret(self, context: str) -> bool:
pass
# 终结符表达式
class TerminalExpression(Expression):
def __init__(self, data: str):
self.data = data
def interpret(self, context: str) -> bool:
return self.data in context
# 或表达式
class OrExpression(Expression):
def __init__(self, expr1: Expression, expr2: Expression):
self.expr1 = expr1
self.expr2 = expr2
def interpret(self, context: str) -> bool:
return self.expr1.interpret(context) or self.expr2.interpret(context)
# 与表达式
class AndExpression(Expression):
def __init__(self, expr1: Expression, expr2: Expression):
self.expr1 = expr1
self.expr2 = expr2
def interpret(self, context: str) -> bool:
return self.expr1.interpret(context) and self.expr2.interpret(context)
# 使用示例
if __name__ == "__main__":
# 规则:Robert 和 John 是男性
def get_male_expression() -> Expression:
robert = TerminalExpression("Robert")
john = TerminalExpression("John")
return OrExpression(robert, john)
# 规则:Julie 是一个已婚的女性
def get_married_woman_expression() -> Expression:
julie = TerminalExpression("Julie")
married = TerminalExpression("Married")
return AndExpression(julie, married)
is_male = get_male_expression()
is_married_woman = get_married_woman_expression()
print("John is male?", is_male.interpret("John"))
print("Julie is a married woman?", is_married_woman.interpret("Married Julie"))
16. 迭代器模式 (Iterator)
意图:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
from abc import ABC, abstractmethod
from typing import List
# 迭代器接口
class Iterator(ABC):
@abstractmethod
def has_next(self) -> bool:
pass
@abstractmethod
def next(self):
pass
# 容器接口
class Container(ABC):
@abstractmethod
def get_iterator(self) -> Iterator:
pass
# 具体容器
class NameRepository(Container):
def __init__(self):
self.names = ["Robert", "John", "Julie", "Lora"]
def get_iterator(self) -> Iterator:
return NameIterator(self)
# 具体迭代器
class NameIterator(Iterator):
def __init__(self, repository: NameRepository):
self.repository = repository
self.index = 0
def has_next(self) -> bool:
return self.index < len(self.repository.names)
def next(self):
if self.has_next():
item = self.repository.names[self.index]
self.index += 1
return item
return None
# 使用示例
if __name__ == "__main__":
names_repository = NameRepository()
iterator = names_repository.get_iterator()
while iterator.has_next():
name = iterator.next()
print(f"Name: {name}")
17. 中介者模式 (Mediator)
意图:用一个中介对象来封装一系列的对象交互。
from abc import ABC, abstractmethod
from datetime import datetime
# 中介者接口
class ChatRoomMediator(ABC):
@abstractmethod
def show_message(self, user, message: str):
pass
# 具体中介者
class ChatRoom(ChatRoomMediator):
def show_message(self, user, message: str):
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
sender = user.name
print(f"{time} [{sender}]: {message}")
# 同事类
class User:
def __init__(self, name: str, chat_room: ChatRoomMediator):
self.name = name
self.chat_room = chat_room
def send_message(self, message: str):
self.chat_room.show_message(self, message)
# 使用示例
if __name__ == "__main__":
chat_room = ChatRoom()
john = User("John", chat_room)
jane = User("Jane", chat_room)
john.send_message("Hi there!")
jane.send_message("Hey!")
18. 备忘录模式 (Memento)
意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
# 备忘录类
class Memento:
def __init__(self, state: str):
self.state = state
def get_state(self) -> str:
return self.state
# 原发器类
class Originator:
def __init__(self):
self.state = None
def set_state(self, state: str):
self.state = state
def get_state(self) -> str:
return self.state
def save_state_to_memento(self) -> Memento:
return Memento(self.state)
def get_state_from_memento(self, memento: Memento):
self.state = memento.get_state()
# 管理者类
class CareTaker:
def __init__(self):
self.memento_list: List[Memento] = []
def add(self, state: Memento):
self.memento_list.append(state)
def get(self, index: int) -> Memento:
return self.memento_list[index]
# 使用示例
if __name__ == "__main__":
originator = Originator()
care_taker = CareTaker()
originator.set_state("State #1")
originator.set_state("State #2")
care_taker.add(originator.save_state_to_memento())
originator.set_state("State #3")
care_taker.add(originator.save_state_to_memento())
originator.set_state("State #4")
print("Current State:", originator.get_state())
originator.get_state_from_memento(care_taker.get(0))
print("First saved State:", originator.get_state())
originator.get_state_from_memento(care_taker.get(1))
print("Second saved State:", originator.get_state())
19. 观察者模式 (Observer)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
from abc import ABC, abstractmethod
from typing import List
# 主题接口
class Subject(ABC):
@abstractmethod
def register_observer(self, observer):
pass
@abstractmethod
def remove_observer(self, observer):
pass
@abstractmethod
def notify_observers(self):
pass
# 具体主题
class ConcreteSubject(Subject):
def __init__(self):
self.observers: List[Observer] = []
self.state = None
def register_observer(self, observer):
self.observers.append(observer)
def remove_observer(self, observer):
self.observers.remove(observer)
def notify_observers(self):
for observer in self.observers:
observer.update()
def get_state(self):
return self.state
def set_state(self, state):
self.state = state
self.notify_observers()
# 观察者接口
class Observer(ABC):
@abstractmethod
def update(self):
pass
# 具体观察者A
class ConcreteObserverA(Observer):
def __init__(self, subject: ConcreteSubject):
self.subject = subject
self.subject.register_observer(self)
def update(self):
print(f"ConcreteObserverA: Subject's state changed to {self.subject.get_state()}")
# 具体观察者B
class ConcreteObserverB(Observer):
def __init__(self, subject: ConcreteSubject):
self.subject = subject
self.subject.register_observer(self)
def update(self):
print(f"ConcreteObserverB: Subject's state changed to {self.subject.get_state()}")
# 使用示例
if __name__ == "__main__":
subject = ConcreteSubject()
ConcreteObserverA(subject)
ConcreteObserverB(subject)
subject.set_state(1)
subject.set_state(2)
20. 状态模式 (State)
意图:允许一个对象在其内部状态改变时改变它的行为
from abc import ABC, abstractmethod
# 状态接口
class State(ABC):
@abstractmethod
def do_action(self, context):
pass
# 具体状态 - 开始状态
class StartState(State):
def do_action(self, context):
print("Player is in start state")
context.state = self
def __str__(self):
return "Start State"
# 具体状态 - 停止状态
class StopState(State):
def do_action(self, context):
print("Player is in stop state")
context.state = self
def __str__(self):
return "Stop State"
# 上下文类
class Context:
def __init__(self):
self.state = None
def set_state(self, state: State):
self.state = state
def get_state(self) -> State:
return self.state
# 使用示例
if __name__ == "__main__":
context = Context()
start_state = StartState()
start_state.do_action(context)
print(context.get_state())
stop_state = StopState()
stop_state.do_action(context)
print(context.get_state())
21. 策略模式 (Strategy)
意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。
from abc import ABC, abstractmethod
# 策略接口
class Strategy(ABC):
@abstractmethod
def do_operation(self, num1: int, num2: int) -> int:
pass
# 具体策略 - 加法
class OperationAdd(Strategy):
def do_operation(self, num1: int, num2: int) -> int:
return num1 + num2
# 具体策略 - 减法
class OperationSubtract(Strategy):
def do_operation(self, num1: int, num2: int) -> int:
return num1 - num2
# 具体策略 - 乘法
class OperationMultiply(Strategy):
def do_operation(self, num1: int, num2: int) -> int:
return num1 * num2
# 上下文类
class Context:
def __init__(self, strategy: Strategy):
self.strategy = strategy
def execute_strategy(self, num1: int, num2: int) -> int:
return self.strategy.do_operation(num1, num2)
# 使用示例
if __name__ == "__main__":
context = Context(OperationAdd())
print("10 + 5 =", context.execute_strategy(10, 5))
context = Context(OperationSubtract())
print("10 - 5 =", context.execute_strategy(10, 5))
context = Context(OperationMultiply())
print("10 * 5 =", context.execute_strategy(10, 5))
22. 模板方法模式 (Template Method)
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
from abc import ABC, abstractmethod
# 抽象类 - 定义模板方法
class Game(ABC):
def play(self):
# 初始化游戏
self.initialize()
# 开始游戏
self.start_play()
# 结束游戏
self.end_play()
@abstractmethod
def initialize(self):
pass
@abstractmethod
def start_play(self):
pass
@abstractmethod
def end_play(self):
pass
# 具体子类 - 足球游戏
class Football(Game):
def initialize(self):
print("Football Game Initialized! Start playing.")
def start_play(self):
print("Football Game Started. Enjoy the game!")
def end_play(self):
print("Football Game Finished!")
# 具体子类 - 篮球游戏
class Basketball(Game):
def initialize(self):
print("Basketball Game Initialized! Start playing.")
def start_play(self):
print("Basketball Game Started. Enjoy the game!")
def end_play(self):
print("Basketball Game Finished!")
# 使用示例
if __name__ == "__main__":
game = Football()
game.play()
print()
game = Basketball()
game.play()
23. 访问者模式 (Visitor)
意图:表示一个作用于某对象结构中的各元素的操作。
from abc import ABC, abstractmethod
# 元素接口
class ComputerPart(ABC):
@abstractmethod
def accept(self, visitor):
pass
# 具体元素 - 键盘
class Keyboard(ComputerPart):
def accept(self, visitor):
visitor.visit(self)
# 具体元素 - 显示器
class Monitor(ComputerPart):
def accept(self, visitor):
visitor.visit(self)
# 具体元素 - 鼠标
class Mouse(ComputerPart):
def accept(self, visitor):
visitor.visit(self)
# 具体元素 - 计算机
class Computer(ComputerPart):
def __init__(self):
self.parts = [Mouse(), Keyboard(), Monitor()]
def accept(self, visitor):
for part in self.parts:
part.accept(visitor)
visitor.visit(self)
# 访问者接口
class ComputerPartVisitor(ABC):
@abstractmethod
def visit(self, computer):
pass
@abstractmethod
def visit(self, mouse):
pass
@abstractmethod
def visit(self, keyboard):
pass
@abstractmethod
def visit(self, monitor):
pass
# 具体访问者 - 显示访问者
class ComputerPartDisplayVisitor(ComputerPartVisitor):
def visit(self, computer):
print("Displaying Computer.")
def visit(self, mouse):
print("Displaying Mouse.")
def visit(self, keyboard):
print("Displaying Keyboard.")
def visit(self, monitor):
print("Displaying Monitor.")
# 使用示例
if __name__ == "__main__":
computer = Computer()
computer.accept(ComputerPartDisplayVisitor())
总结
这23种设计模式可以分为三大类:
- 创建型模式:关注对象的创建过程
- 单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
- 结构型模式:关注类和对象的组合
- 适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式、代理模式
- 行为型模式:关注对象之间的交互
- 责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式
每种设计模式都有其特定的应用场景,理解这些模式可以帮助我们编写更加灵活、可维护和可扩展的代码。在实际开发中,应根据具体问题选择合适的模式,而不是为了使用模式而使用模式。