Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • python 学习指南
  • python 中的设计模式
    • 装饰器设计模式
      • 例: 记录函数的执行时间
      • 解释
      • 结果
      • 小结
    • 单例模式 (Singleton Pattern)
      • 方法一:使用装饰器实现
      • 方法二:使用 __new__ 方法实现
    • 工厂模式 (Factory Pattern)
      • 简单工厂模式
      • 工厂方法模式
    • 观察者模式 (Observer Pattern)
    • 策略模式 (Strategy Pattern)
    • 命令模式 (Command Pattern)
    • 适配器模式 (Adapter Pattern)
      • 实际应用场景
    • 模板方法模式 (Template Method Pattern)
    • 建造者模式 (Builder Pattern)
  • module

  • tool

  • other

  • 《python》
Jacky
2024-09-09
目录

python 中的设计模式

# 装饰器设计模式

装饰器模式(Decorator Pattern)是一种设计模式,允许你在不修改函数代码的前提下,动态地给函数添加功能。Python 中的装饰器语法非常简洁,它使用 @decorator 来修饰一个函数

下面是一个简单的例子来展示如何使用装饰器模式给函数添加功能

# 例: 记录函数的执行时间

import time

# 定义装饰器
def time_it(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()  # 记录开始时间
        result = func(*args, **kwargs)  # 执行原函数
        end_time = time.time()  # 记录结束时间
        print(f"Function {func.__name__} took {end_time - start_time:.4f} seconds")
        return result
    return wrapper

# 使用装饰器
@time_it
def slow_function():
    time.sleep(2)  # 模拟一个耗时的操作
    print("Function finished")

# 调用被装饰的函数
slow_function()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 解释

  • 装饰器函数 time_it(func):

    • 这是一个装饰器函数,接受一个函数 func 作为参数
    • 它内部定义了一个 wrapper 函数,该函数在执行原函数 func 之前和之后做了一些额外的事情——记录并打印函数的执行时间
    • 最后,wrapper 函数返回了 func 的结果,并通过 return wrapper 将包装函数返回
  • 应用装饰器:

    • @time_it 装饰了 slow_function,相当于执行了 slow_function = time_it(slow_function),在调用 slow_function() 时实际上执行的是 wrapper 函数
  • 执行流程:

    • 当你调用 slow_function() 时,首先进入装饰器 wrapper,记录开始时间
    • 执行原始的 slow_function(模拟一个 2 秒的延迟),然后记录结束时间并打印耗时
    • 结果是,除了 slow_function 原有的功能外,还添加了记录执行时间的功能

# 结果

Function finished
Function slow_function took 2.0001 seconds
1
2

# 小结

装饰器的作用: 在不修改 slow_function 源代码的前提下,添加了记录执行时间的功能。装饰器提供了一个干净、优雅的方式来增强函数的行为,而不破坏其原有逻辑

# 单例模式 (Singleton Pattern)

单例模式确保一个类只有一个实例,并提供一个全局访问点。

# 方法一:使用装饰器实现

def singleton(cls):
    """单例装饰器"""
    instances = {}
    
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    
    return get_instance

@singleton
class Database:
    def __init__(self):
        self.connection = "Database connection established"
    
    def query(self, sql):
        return f"Executing: {sql}"

# 测试
db1 = Database()
db2 = Database()
print(db1 is db2)  # True
print(id(db1) == id(db2))  # True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 方法二:使用 __new__ 方法实现

class Singleton:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.data = []
            self.initialized = True

# 测试
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 工厂模式 (Factory Pattern)

工厂模式用于创建对象,而不需要指定具体的类。

# 简单工厂模式

from abc import ABC, abstractmethod

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

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

class Cat(Animal):
    def speak(self):
        return "Meow!"

class Bird(Animal):
    def speak(self):
        return "Tweet!"

# 简单工厂
class AnimalFactory:
    @staticmethod
    def create_animal(animal_type):
        animals = {
            'dog': Dog,
            'cat': Cat,
            'bird': Bird
        }
        
        if animal_type.lower() in animals:
            return animals[animal_type.lower()]()
        else:
            raise ValueError(f"Unknown animal type: {animal_type}")

# 使用
factory = AnimalFactory()
dog = factory.create_animal('dog')
cat = factory.create_animal('cat')

print(dog.speak())  # Woof!
print(cat.speak())  # Meow!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 工厂方法模式

from abc import ABC, abstractmethod

# 抽象产品
class Vehicle(ABC):
    @abstractmethod
    def drive(self):
        pass

# 具体产品
class Car(Vehicle):
    def drive(self):
        return "Driving a car"

class Motorcycle(Vehicle):
    def drive(self):
        return "Riding a motorcycle"

# 抽象工厂
class VehicleFactory(ABC):
    @abstractmethod
    def create_vehicle(self):
        pass

# 具体工厂
class CarFactory(VehicleFactory):
    def create_vehicle(self):
        return Car()

class MotorcycleFactory(VehicleFactory):
    def create_vehicle(self):
        return Motorcycle()

# 使用
car_factory = CarFactory()
motorcycle_factory = MotorcycleFactory()

car = car_factory.create_vehicle()
motorcycle = motorcycle_factory.create_vehicle()

print(car.drive())      # Driving a car
print(motorcycle.drive())  # Riding a motorcycle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

# 观察者模式 (Observer Pattern)

观察者模式定义了一种一对多的依赖关系,当一个对象状态改变时,所有依赖者都会得到通知。

from abc import ABC, abstractmethod

# 抽象观察者
class Observer(ABC):
    @abstractmethod
    def update(self, subject):
        pass

# 具体观察者
class EmailObserver(Observer):
    def update(self, subject):
        print(f"Email notification: {subject.get_state()}")

class SMSObserver(Observer):
    def update(self, subject):
        print(f"SMS notification: {subject.get_state()}")

# 被观察者
class Subject:
    def __init__(self):
        self._observers = []
        self._state = None
    
    def attach(self, observer):
        if observer not in self._observers:
            self._observers.append(observer)
    
    def detach(self, observer):
        self._observers.remove(observer)
    
    def notify(self):
        for observer in self._observers:
            observer.update(self)
    
    def set_state(self, state):
        self._state = state
        self.notify()
    
    def get_state(self):
        return self._state

# 使用
subject = Subject()
email_observer = EmailObserver()
sms_observer = SMSObserver()

subject.attach(email_observer)
subject.attach(sms_observer)

subject.set_state("Order completed!")
# 输出:
# Email notification: Order completed!
# SMS notification: Order completed!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 策略模式 (Strategy Pattern)

策略模式定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。

from abc import ABC, abstractmethod

# 抽象策略
class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount):
        pass

# 具体策略
class CreditCardPayment(PaymentStrategy):
    def __init__(self, card_number):
        self.card_number = card_number
    
    def pay(self, amount):
        return f"Paid ${amount} using Credit Card ending in {self.card_number[-4:]}"

class PayPalPayment(PaymentStrategy):
    def __init__(self, email):
        self.email = email
    
    def pay(self, amount):
        return f"Paid ${amount} using PayPal account {self.email}"

class CashPayment(PaymentStrategy):
    def pay(self, amount):
        return f"Paid ${amount} in cash"

# 上下文
class ShoppingCart:
    def __init__(self):
        self.payment_strategy = None
        self.items = []
    
    def add_item(self, item, price):
        self.items.append((item, price))
    
    def set_payment_strategy(self, strategy):
        self.payment_strategy = strategy
    
    def checkout(self):
        total = sum(price for _, price in self.items)
        if self.payment_strategy:
            result = self.payment_strategy.pay(total)
            print(result)
            self.items.clear()
        else:
            print("Please select a payment method")

# 使用
cart = ShoppingCart()
cart.add_item("Laptop", 999)
cart.add_item("Mouse", 25)

# 使用信用卡支付
cart.set_payment_strategy(CreditCardPayment("1234567890123456"))
cart.checkout()

# 使用PayPal支付
cart.add_item("Keyboard", 50)
cart.set_payment_strategy(PayPalPayment("[email protected]"))
cart.checkout()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 命令模式 (Command Pattern)

命令模式将请求封装成对象,从而可以用不同的请求对客户进行参数化。

from abc import ABC, abstractmethod

# 抽象命令
class Command(ABC):
    @abstractmethod
    def execute(self):
        pass
    
    @abstractmethod
    def undo(self):
        pass

# 具体命令
class LightOnCommand(Command):
    def __init__(self, light):
        self.light = light
    
    def execute(self):
        return self.light.turn_on()
    
    def undo(self):
        return self.light.turn_off()

class LightOffCommand(Command):
    def __init__(self, light):
        self.light = light
    
    def execute(self):
        return self.light.turn_off()
    
    def undo(self):
        return self.light.turn_on()

# 接收者
class Light:
    def turn_on(self):
        return "Light is ON"
    
    def turn_off(self):
        return "Light is OFF"

# 调用者
class RemoteControl:
    def __init__(self):
        self.commands = {}
    
    def set_command(self, slot, command):
        self.commands[slot] = command
    
    def press_button(self, slot):
        if slot in self.commands:
            return self.commands[slot].execute()
        return "No command set for this slot"
    
    def press_undo(self, slot):
        if slot in self.commands:
            return self.commands[slot].undo()
        return "No command set for this slot"

# 使用
light = Light()
remote = RemoteControl()

remote.set_command(0, LightOnCommand(light))
remote.set_command(1, LightOffCommand(light))

print(remote.press_button(0))  # Light is ON
print(remote.press_button(1))  # Light is OFF
print(remote.press_undo(0))    # Light is OFF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

# 适配器模式 (Adapter Pattern)

适配器模式允许不兼容的接口能够一起工作。

# 目标接口
class Target:
    def request(self):
        return "Target: The default target's behavior."

# 需要适配的类
class Adaptee:
    def specific_request(self):
        return ".eetpadA eht fo roivaheb laicepS"

# 适配器
class Adapter(Target):
    def __init__(self, adaptee):
        self.adaptee = adaptee
    
    def request(self):
        result = self.adaptee.specific_request()
        return f"Adapter: (TRANSLATED) {result[::-1]}"

# 使用
adaptee = Adaptee()
adapter = Adapter(adaptee)

print(adapter.request())  # Adapter: (TRANSLATED) Special behavior of the Adaptee.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 实际应用场景

这种模式在以下情况很有用:

  • 集成第三方库:当第三方库的接口与你的代码不兼容时
  • 系统重构:当你想使用新接口但不想修改现有代码时
  • 多平台支持:当需要适配不同平台的API时

类比现实生活

  • 欧洲插头 → 电源适配器 → 中国插座
  • USB-C设备 → USB-C转USB-A适配器 → USB-A接口

# 模板方法模式 (Template Method Pattern)

模板方法模式定义了一个算法的骨架,将一些步骤延迟到子类中实现。

from abc import ABC, abstractmethod

# 抽象类
class Beverage(ABC):
    def prepare(self):
        """模板方法"""
        self.boil_water()
        self.brew()
        self.pour_in_cup()
        if self.customer_wants_condiments():
            self.add_condiments()
    
    def boil_water(self):
        print("Boiling water")
    
    @abstractmethod
    def brew(self):
        pass
    
    def pour_in_cup(self):
        print("Pouring into cup")
    
    @abstractmethod
    def add_condiments(self):
        pass
    
    def customer_wants_condiments(self):
        return True

# 具体类
class Coffee(Beverage):
    def brew(self):
        print("Dripping coffee through filter")
    
    def add_condiments(self):
        print("Adding sugar and milk")

class Tea(Beverage):
    def brew(self):
        print("Steeping the tea")
    
    def add_condiments(self):
        print("Adding lemon")

# 使用
coffee = Coffee()
tea = Tea()

print("Making coffee:")
coffee.prepare()

print("\nMaking tea:")
tea.prepare()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 建造者模式 (Builder Pattern)

建造者模式用于创建复杂对象,特别是当对象的创建过程需要多个步骤时。

class Computer:
    def __init__(self):
        self.cpu = None
        self.memory = None
        self.storage = None
        self.graphics = None
    
    def __str__(self):
        return f"Computer: CPU={self.cpu}, Memory={self.memory}, Storage={self.storage}, Graphics={self.graphics}"

class ComputerBuilder:
    def __init__(self):
        self.computer = Computer()
    
    def set_cpu(self, cpu):
        self.computer.cpu = cpu
        return self
    
    def set_memory(self, memory):
        self.computer.memory = memory
        return self
    
    def set_storage(self, storage):
        self.computer.storage = storage
        return self
    
    def set_graphics(self, graphics):
        self.computer.graphics = graphics
        return self
    
    def build(self):
        return self.computer

# 使用
builder = ComputerBuilder()
computer = (builder
           .set_cpu("Intel i7")
           .set_memory("16GB")
           .set_storage("512GB SSD")
           .set_graphics("NVIDIA RTX 3080")
           .build())

print(computer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

这些是Python中最常见和实用的设计模式。每种模式都有其特定的使用场景,选择合适的模式可以让代码更加清晰、可维护和可扩展。

#Python#设计模式
上次更新: 2025/10/09, 21:06:25
python 学习指南
python modules

← python 学习指南 python modules→

最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式