python 类与对象(OOP) 设计者模式

学习设计者模式

设计者模式
单例模式(Singleton)
全局唯一对象:配置管理 / 日志 / 数据库连接
工厂方法模式(Factory Method)
根据参数创建不同对象
装饰器模式(Decorator)
给对象动态增加功能(权限、缓存、中间件)
外观模式(Facade)
封装多个复杂子系统,对外提供统一接口
代理模式(Proxy)
控制对真实对象的访问(延迟加载、远程代理、缓存代理)
策略模式(Strategy)
将多种算法/策略抽象出来,可在运行时自由切换
观察者模式(Observer)
发布/订阅机制,多个对象自动响应事件

单例模式(Singleton)

数据库连接单一而不是建立多个连接池避免资源浪费 → 性能下降 → 甚至连接冲突

工厂方法模式(Factory Method)

把“创建对象”的逻辑抽出来,放到一个“工厂类”里面处理。

使用者不需要知道具体创建细节,只需要调用工厂就能得到对象。

# 抽象产品
class Animal:
    def speak(self):
        pass

# 具体产品
class Dog(Animal):
    def speak(self):
        return "汪汪"

class Cat(Animal):
    def speak(self):
        return "喵喵"

# 抽象工厂
class AnimalFactory:
    def create_animal(self):
        raise NotImplementedError

# 具体工厂
class DogFactory(AnimalFactory):
    def create_animal(self):
        return Dog()

class CatFactory(AnimalFactory):
    def create_animal(self):
        return Cat()

# 客户端
factory = DogFactory()
animal = factory.create_animal()
print(animal.speak())   # 汪汪

装饰器模式(Decorator)

核心思想(白话理解)

在不修改原有类/函数的情况下,动态地添加额外功能。

# 装饰器(包装函数)
def login_required(func):
    def wrapper(*args, **kwargs):
        print("-> 检查用户是否登录")
        return func(*args, **kwargs)
    return wrapper


# 原本的函数
@login_required
def download_file():
    print("正在下载文件...")


# 调用
download_file()
-> 检查用户是否登录
正在下载文件...

外观模式(Facade)

把复杂系统包装成一个“简单入口”对外提供服务

# 子系统1:打开外卖App
class AppOpener:
    def open_app(self):
        print("打开美食外卖App")

# 子系统2:选择餐厅并下单
class OrderPlacer:
    def place_order(self):
        print("选择餐厅 -> 下单")

# 子系统3:付款
class PaymentSystem:
    def pay(self):
        print("支付订单")

# 子系统4:等待送达
class DeliveryTracker:
    def wait_for_delivery(self):
        print("等待骑手送餐...")

# 外观类(Facade)—— 外卖助理
class FoodDeliveryFacade:
    def __init__(self):
        self.app = AppOpener()
        self.order = OrderPlacer()
        self.payment = PaymentSystem()
        self.tracker = DeliveryTracker()

    def order_food(self):
        # 把多个步骤组合起来
        self.app.open_app()
        self.order.place_order()
        self.payment.pay()
        self.tracker.wait_for_delivery()
        print("✅ 晚餐已送达!")

# 客户端
assistant = FoodDeliveryFacade()
assistant.order_food()

代理模式(Proxy)

不直接访问真实对象,而是通过一个“代理对象”来间接访问它

# 真正的对象 → 明星
class Star:
    def meet(self):
        print("🎤 明星:很高兴见到你~")

# 代理对象 → 经纪人
class Agent:
    def __init__(self):
        self.star = Star()        # 经纪人掌管明星

    def meet_star(self, fan_name):
        # 在联系明星之前,先做一些检查
        if fan_name == "黄牛":
            print("❌ 经纪人:你是黄牛,不安排见面")
            return

        print("✅ 经纪人:粉丝身份确认,安排见面")
        # 然后才让明星真正出面
        self.star.meet()


# 客户端
agent = Agent()

agent.meet_star("普通粉丝")
# 输出:
# ✅ 经纪人:粉丝身份确认,安排见面
# 🎤 明星:很高兴见到你~

agent.meet_star("黄牛")
# 输出:
# ❌ 经纪人:你是黄牛,不安排见面

策略模式(Strategy)

把多个“可互换的算法/策略” 抽象出来,运行时根据需要选择其中一种来执行

# 三种策略(不同的“去公司方式”)
class WalkStrategy:
    def go(self):
        print("走路去公司")

class SubwayStrategy:
    def go(self):
        print("坐地铁去公司")

class TaxiStrategy:
    def go(self):
        print("打车去公司")


# 环境类(上下文):
# 负责根据需要选择“策略”并执行
class GoToWorkContext:
    def __init__(self, strategy):
        self.strategy = strategy

    def execute(self):
        self.strategy.go()


# 客户端
# 情况1:公司在附近
context = GoToWorkContext(WalkStrategy())
context.execute()

# 情况2:地铁更快
context = GoToWorkContext(SubwayStrategy())
context.execute()

观察者模式(Observer)

一个对象发生变化时,通知所有订阅它的对象,让它们自动做出响应。

也就是说: “发布者 → 通知 → 多个订阅者”

# 发布者(Subject)
class YouTubeChannel:
    def __init__(self):
        self.observers = []  # 存放所有订阅者

    def subscribe(self, observer):
        self.observers.append(observer)

    def upload_video(self, title):
        print(f"频道上传新视频:{title}")
        # 通知所有观察者
        for ob in self.observers:
            ob.notify(title)


# 观察者(Observer)
class User:
    def __init__(self, name):
        self.name = name

    def notify(self, title):
        print(f"{self.name} 收到通知:{title}")


# 客户端
channel = YouTubeChannel()

user1 = User("小明")
user2 = User("小红")

channel.subscribe(user1)
channel.subscribe(user2)

channel.upload_video("如何写 Python 设计模式")