编程语言的设计模式是一种总结和抽象,帮助开发者应对常见的编程问题。以下是几种主要的设计模式:
1. 创建型模式
- 单例模式 (Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。
- 工厂模式 (Factory Pattern):定义一个创建对象的接口,但由子类决定实例化哪一个类。适合对象的创建复杂或者需要动态配置的情况。
- 抽象工厂模式 (Abstract Factory Pattern):提供一个接口,用于创建一系列相关或依赖的对象,而无需指定具体的类。
- 建造者模式 (Builder Pattern):将一个复杂对象的构建过程分离,使同样的构建过程可以创建不同的表示。适合于多步骤的对象构建。
- 原型模式 (Prototype Pattern):通过复制现有实例来创建新的对象,而不是通过实例化类。
2. 结构型模式
- 适配器模式 (Adapter Pattern):将一个类的接口转换为另一个接口,使得本来由于接口不兼容而无法工作的类可以一起工作。
- 装饰器模式 (Decorator Pattern):动态地给对象增加行为或责任,而不改变其接口。
- 代理模式 (Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。
- 外观模式 (Facade Pattern):提供一个简化的接口来访问一组复杂的子系统。
- 桥接模式 (Bridge Pattern):将抽象部分与实现部分分离,以便它们可以独立变化。
- 组合模式 (Composite Pattern):将对象组合成树状结构,以表示“部分-整体”的层次结构。使得客户可以一致地使用单个对象和组合对象。
3. 行为型模式
- 观察者模式 (Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知并自动更新。
- 策略模式 (Strategy Pattern):定义一系列算法,把它们封装起来,并使它们可以互相替换。
- 命令模式 (Command Pattern):将请求封装为对象,从而可以对不同的请求进行参数化处理、排队或记录日志。
- 迭代器模式 (Iterator Pattern):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
- 中介者模式 (Mediator Pattern):用一个中介对象来封装一系列对象之间的交互。中介者使各对象不需要显式地相互引用。
- 责任链模式 (Chain of Responsibility Pattern):将请求沿着处理链传递,直到有对象处理它为止。
- 备忘录模式 (Memento Pattern):在不破坏封装性的前提下,捕获一个对象的内部状态,并在以后需要时恢复。
- 解释器模式 (Interpreter Pattern):给定一个语言,定义它的文法表示,并提供一个解释器来处理语言中的句子。
4. 并发型模式
- 线程池模式 (Thread Pool Pattern):允许复用线程资源,避免反复创建销毁。
- 生产者-消费者模式 (Producer-Consumer Pattern):通过平衡生产者和消费者的速度来优化资源使用。
- 读写锁模式 (Read-Write Lock Pattern):在读多写少的情况下,允许多个读操作同时执行,而写操作独占。
这些设计模式涵盖了大部分常见的应用场景,掌握后可以有效提高代码的可维护性和扩展性。
分类 | 设计模式 | 描述 |
---|---|---|
创建型模式 | 单例模式 (Singleton) | 确保一个类只有一个实例,并提供一个全局访问点。 |
工厂模式 (Factory) | 定义创建对象的接口,由子类决定实例化哪个类。适合需要动态创建的情况。 | |
抽象工厂模式 (Abstract Factory) | 提供一个接口,用于创建一系列相关或依赖的对象,避免指定具体类。 | |
建造者模式 (Builder) | 将复杂对象的构建过程分离,使同样的构建过程可以创建不同表示。适合多步骤对象构建。 | |
原型模式 (Prototype) | 通过复制现有实例创建新对象,而不是通过实例化类。 | |
结构型模式 | 适配器模式 (Adapter) | 将一个类的接口转换为另一个接口,使得接口不兼容的类可以一起工作。 |
装饰器模式 (Decorator) | 动态地给对象增加行为或责任,而不改变其接口。 | |
代理模式 (Proxy) | 为其他对象提供代理以控制对这个对象的访问。 | |
外观模式 (Facade) | 提供一个简化的接口以便访问一组复杂子系统。 | |
桥接模式 (Bridge) | 将抽象与实现分离,以便它们可以独立变化。 | |
组合模式 (Composite) | 将对象组合成树状结构以表示“部分-整体”的层次结构,使客户可一致地使用单个或组合对象。 | |
行为型模式 | 观察者模式 (Observer) | 定义对象间的一对多依赖,当一个对象状态改变时通知所有依赖它的对象。 |
策略模式 (Strategy) | 定义一系列算法,把它们封装起来,并使它们可以互相替换。 | |
命令模式 (Command) | 将请求封装为对象,以便对不同的请求进行参数化处理、排队或记录。 | |
迭代器模式 (Iterator) | 提供顺序访问聚合对象元素的方法,不暴露其内部表示。 | |
中介者模式 (Mediator) | 使用中介对象封装一系列对象间的交互,使各对象不需显式相互引用。 | |
责任链模式 (Chain of Responsibility) | 将请求沿处理链传递,直到有对象处理为止。 | |
备忘录模式 (Memento) | 捕获对象的内部状态,并在以后需要时恢复,保持封装性。 | |
解释器模式 (Interpreter) | 定义语言文法表示,并提供解释器来处理语言中的句子。 | |
并发型模式 | 线程池模式 (Thread Pool) | 复用线程资源,避免反复创建销毁。 |
生产者-消费者模式 (Producer-Consumer) | 平衡生产者和消费者速度,优化资源使用。 | |
读写锁模式 (Read-Write Lock) | 在读多写少情况下允许多个读操作同时执行,写操作独占。 |
这个表格将设计模式按类型划分,并概括了每种模式的核心功能,有助于快速了解和选择合适的设计模式。
在 Python 中,实现设计模式通常比在强类型语言中更灵活,许多模式可以通过 Python 的动态特性简化。下面是每个设计模式的简要说明及使用示例。
1. 创建型模式
单例模式 (Singleton)
说明:单例模式确保一个类只有一个实例,常用于需要全局访问的对象,例如配置、日志记录器等。
class Singleton:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super(Singleton, cls).__new__(cls)return cls._instancesingleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # 输出:True
工厂模式 (Factory)
说明:工厂模式通过定义一个创建对象的接口,延迟实例化到子类。常用于需要动态创建对象的场景。
class Dog:def sound(self):return "Woof!"class Cat:def sound(self):return "Meow!"class AnimalFactory:def create_animal(self, animal_type):if animal_type == "dog":return Dog()elif animal_type == "cat":return Cat()factory = AnimalFactory()
animal = factory.create_animal("dog")
print(animal.sound()) # 输出:Woof!
抽象工厂模式 (Abstract Factory)
说明:提供一个接口来创建一系列相关对象,不需要指定具体的类。
class Dog:def speak(self):return "Woof!"class Cat:def speak(self):return "Meow!"class AnimalFactory:def create_dog(self):return Dog()def create_cat(self):return Cat()factory = AnimalFactory()
dog = factory.create_dog()
print(dog.speak()) # 输出:Woof!
建造者模式 (Builder)
说明:分步骤创建复杂对象,允许不同表示的对象共享构建过程。
class PizzaBuilder:def __init__(self):self.ingredients = []def add_cheese(self):self.ingredients.append("Cheese")return selfdef add_pepperoni(self):self.ingredients.append("Pepperoni")return selfdef build(self):return "Pizza with " + ", ".join(self.ingredients)builder = PizzaBuilder()
pizza = builder.add_cheese().add_pepperoni().build()
print(pizza) # 输出:Pizza with Cheese, Pepperoni
原型模式 (Prototype)
说明:通过克隆现有对象来创建新对象,通常用于减少创建对象的成本。
import copyclass Prototype:def __init__(self, value):self.value = valuedef clone(self):return copy.deepcopy(self)obj1 = Prototype([1, 2, 3])
obj2 = obj1.clone()
obj2.value.append(4)
print(obj1.value) # 输出:[1, 2, 3]
print(obj2.value) # 输出:[1, 2, 3, 4]
2. 结构型模式
以下是适配器模式、装饰器模式、代理模式、外观模式、桥接模式和组合模式的 Python 实现示例:
适配器模式 (Adapter)
说明:适配器模式通过包装一个类,将其接口转换为另一个客户端所期望的接口,适用于类接口不兼容的场景。
class Adaptee:def specific_request(self):return "Adaptee's specific behavior"class Target:def request(self):passclass Adapter(Target):def __init__(self, adaptee):self.adaptee = adapteedef request(self):return self.adaptee.specific_request()# 使用示例
adaptee = Adaptee()
adapter = Adapter(adaptee)
print(adapter.request()) # 输出:Adaptee's specific behavior
装饰器模式 (Decorator)
说明:装饰器模式用于在不修改对象结构的情况下动态地给对象增加功能,遵循开放-关闭原则。
class Coffee:def cost(self):return 5class MilkDecorator:def __init__(self, coffee):self.coffee = coffeedef cost(self):return self.coffee.cost() + 2class SugarDecorator:def __init__(self, coffee):self.coffee = coffeedef cost(self):return self.coffee.cost() + 1# 使用示例
coffee = Coffee()
coffee_with_milk = MilkDecorator(coffee)
coffee_with_milk_and_sugar = SugarDecorator(coffee_with_milk)
print(coffee_with_milk_and_sugar.cost()) # 输出:8
代理模式 (Proxy)
说明:代理模式为其他对象提供一个代理,以控制对该对象的访问,通常用于延迟加载、访问控制等。
class RealSubject:def request(self):return "RealSubject's request"class Proxy:def __init__(self):self._real_subject = Nonedef request(self):if self._real_subject is None:self._real_subject = RealSubject() # 延迟加载return self._real_subject.request()# 使用示例
proxy = Proxy()
print(proxy.request()) # 输出:RealSubject's request
外观模式 (Facade)
说明:外观模式通过提供一个简化的接口来隐藏内部子系统的复杂性,方便客户端访问。
class SubsystemA:def operation_a(self):return "SubsystemA operation"class SubsystemB:def operation_b(self):return "SubsystemB operation"class Facade:def __init__(self):self._subsystem_a = SubsystemA()self._subsystem_b = SubsystemB()def operation(self):return f"{self._subsystem_a.operation_a()} and {self._subsystem_b.operation_b()}"# 使用示例
facade = Facade()
print(facade.operation()) # 输出:SubsystemA operation and SubsystemB operation
桥接模式 (Bridge)
说明:桥接模式将抽象部分与实现部分分离,以便它们可以独立变化。适合希望将抽象和实现解耦的情况。
class Implementor:def operation_impl(self):passclass ConcreteImplementorA(Implementor):def operation_impl(self):return "ConcreteImplementorA's operation"class ConcreteImplementorB(Implementor):def operation_impl(self):return "ConcreteImplementorB's operation"class Abstraction:def __init__(self, implementor):self.implementor = implementordef operation(self):return self.implementor.operation_impl()# 使用示例
abstraction_a = Abstraction(ConcreteImplementorA())
abstraction_b = Abstraction(ConcreteImplementorB())
print(abstraction_a.operation()) # 输出:ConcreteImplementorA's operation
print(abstraction_b.operation()) # 输出:ConcreteImplementorB's operation
组合模式 (Composite)
说明:组合模式将对象组织成树状结构,以表示“部分-整体”层次结构。常用于表示一组对象的树结构,使得客户端可以一致地处理单个对象和组合对象。
class Component:def operation(self):passclass Leaf(Component):def __init__(self, name):self.name = namedef operation(self):return f"Leaf {self.name}"class Composite(Component):def __init__(self, name):self.name = nameself.children = []def add(self, component):self.children.append(component)def operation(self):results = [f"Composite {self.name}"]for child in self.children:results.append(child.operation())return " - ".join(results)# 使用示例
leaf1 = Leaf("A")
leaf2 = Leaf("B")
composite = Composite("X")
composite.add(leaf1)
composite.add(leaf2)
print(composite.operation()) # 输出:Composite X - Leaf A - Leaf B
这些实现展示了每种结构型设计模式在 Python 中的简单应用,适配器、装饰器、代理、外观、桥接和组合模式都是用来简化对象的交互、增强代码的模块化和重用性。在复杂应用中,这些模式可以有效管理对象关系并提高代码的灵活性。
3. 行为型模式
观察者模式 (Observer)
说明:一对多依赖,当一个对象状态改变时通知其他依赖它的对象。
class Subject:def __init__(self):self._observers = []def add_observer(self, observer):self._observers.append(observer)def notify_observers(self, message):for observer in self._observers:observer.update(message)class Observer:def update(self, message):print(f"Received: {message}")subject = Subject()
observer1 = Observer()
subject.add_observer(observer1)
subject.notify_observers("Hello") # 输出:Received: Hello
下面是 Python 实现的这些行为型设计模式的代码示例:
策略模式 (Strategy)
说明:策略模式允许定义一系列可互换的算法或行为,并使它们能够动态地切换。
class StrategyA:def execute(self):return "Executing Strategy A"class StrategyB:def execute(self):return "Executing Strategy B"class Context:def __init__(self, strategy):self._strategy = strategydef execute_strategy(self):return self._strategy.execute()# 使用示例
context = Context(StrategyA())
print(context.execute_strategy()) # 输出:Executing Strategy A
context = Context(StrategyB())
print(context.execute_strategy()) # 输出:Executing Strategy B
命令模式 (Command)
说明:命令模式将请求封装成对象,从而可以对不同请求进行参数化、排队、记录日志等操作。命令对象通常包含执行方法和撤销方法。
class Command:def execute(self):passclass LightOnCommand(Command):def __init__(self, light):self.light = lightdef execute(self):return self.light.turn_on()class LightOffCommand(Command):def __init__(self, light):self.light = lightdef execute(self):return self.light.turn_off()class Light:def turn_on(self):return "Light is ON"def turn_off(self):return "Light is OFF"# 客户端代码
light = Light()
on_command = LightOnCommand(light)
off_command = LightOffCommand(light)print(on_command.execute()) # 输出:Light is ON
print(off_command.execute()) # 输出:Light is OFF
迭代器模式 (Iterator)
说明:迭代器模式为集合对象提供一种顺序访问元素的方法,而不暴露其内部表示。
class Iterator:def __init__(self, collection):self._collection = collectionself._index = 0def __next__(self):if self._index < len(self._collection):item = self._collection[self._index]self._index += 1return itemelse:raise StopIterationdef __iter__(self):return self# 使用示例
collection = [1, 2, 3]
iterator = Iterator(collection)
for item in iterator:print(item) # 输出:1, 2, 3
中介者模式 (Mediator)
说明:中介者模式通过一个中介对象来封装对象之间的交互,减少对象间的耦合,使得它们不需要显式地相互引用。
class Mediator:def notify(self, sender, event):passclass ConcreteMediator(Mediator):def __init__(self, component1, component2):self._component1 = component1self._component2 = component2self._component1.mediator = selfself._component2.mediator = selfdef notify(self, sender, event):if event == "A":return "Mediator reacts to event A and triggers following operations: " + self._component2.do_c()elif event == "B":return "Mediator reacts to event B and triggers following operations: " + self._component1.do_a()class Component:def __init__(self):self.mediator = Noneclass Component1(Component):def do_a(self):return "Component1 does A and notifies mediator."class Component2(Component):def do_c(self):return "Component2 does C and notifies mediator."# 使用示例
c1 = Component1()
c2 = Component2()
mediator = ConcreteMediator(c1, c2)print(mediator.notify(c1, "A")) # 输出:Mediator reacts to event A and triggers following operations: Component2 does C
责任链模式 (Chain of Responsibility)
说明:责任链模式将请求沿着处理链传递,直到有一个对象处理它为止。
class Handler:def __init__(self, successor=None):self._successor = successordef handle(self, request):if self._successor:return self._successor.handle(request)return "End of chain, no handler for request."class ConcreteHandler1(Handler):def handle(self, request):if request == "Task1":return "Handler1 handles Task1"return super().handle(request)class ConcreteHandler2(Handler):def handle(self, request):if request == "Task2":return "Handler2 handles Task2"return super().handle(request)# 责任链的创建
handler_chain = ConcreteHandler1(ConcreteHandler2())# 使用示例
print(handler_chain.handle("Task1")) # 输出:Handler1 handles Task1
print(handler_chain.handle("Task2")) # 输出:Handler2 handles Task2
print(handler_chain.handle("Task3")) # 输出:End of chain, no handler for request.
备忘录模式 (Memento)
说明:备忘录模式允许在不破坏封装性的前提下捕获和恢复对象的内部状态。
class Memento:def __init__(self, state):self._state = statedef get_state(self):return self._stateclass Originator:def __init__(self):self._state = Nonedef set_state(self, state):self._state = statedef save(self):return Memento(self._state)def restore(self, memento):self._state = memento.get_state()# 使用示例
originator = Originator()
originator.set_state("State1")
memento = originator.save() # 保存状态
originator.set_state("State2") # 改变状态
originator.restore(memento) # 恢复状态
print(originator._state) # 输出:State1
解释器模式 (Interpreter)
说明:解释器模式定义一种语言的文法,并提供一个解释器来处理该语言的表达式。
class Expression:def interpret(self, context):passclass NumberExpression(Expression):def __init__(self, number):self.number = numberdef interpret(self, context):return self.numberclass PlusExpression(Expression):def __init__(self, left, right):self.left = leftself.right = rightdef interpret(self, context):return self.left.interpret(context) + self.right.interpret(context)# 使用示例
left = NumberExpression(3)
right = NumberExpression(5)
expression = PlusExpression(left, right)
print(expression.interpret({})) # 输出:8
这些代码示例涵盖了策略模式、命令模式、迭代器模式、中介者模式、责任链模式、备忘录模式和解释器模式。每种模式都解决了不同的行为和对象间交互的问题,有助于提升代码的灵活性和可维护性。
4. 并发模式
下面是线程池模式、生产者-消费者模式和读写锁模式的 Python 实现示例。Python 的 concurrent.futures
和 threading
库使实现这些模式变得相对简单。
线程池模式 (Thread Pool)
说明:线程池模式创建一组线程,用来执行多个任务,避免为每个任务创建和销毁线程的开销。Python 提供了 concurrent.futures.ThreadPoolExecutor
来方便实现线程池。
from concurrent.futures import ThreadPoolExecutor
import timedef task(n):time.sleep(1)return f"Task {n} completed"# 创建一个包含 3 个线程的线程池
with ThreadPoolExecutor(max_workers=3) as executor:futures = [executor.submit(task, i) for i in range(5)]for future in futures:print(future.result()) # 输出:Task i completed (i 为任务编号)
在此示例中,任务被分配到 3 个线程执行,这样在执行多个任务时就不需要创建和销毁线程。
生产者-消费者模式 (Producer-Consumer)
说明:生产者-消费者模式允许多个生产者线程和多个消费者线程进行通信,生产者将数据放入队列中,消费者从队列中取出数据。Python 的 queue.Queue
可以有效地处理线程安全的队列。
import threading
import queue
import time
import randombuffer = queue.Queue(maxsize=5) # 有限缓冲区
NUM_PRODUCERS = 2
NUM_CONSUMERS = 2def producer():while True:item = random.randint(1, 100)buffer.put(item)print(f"Produced {item}")time.sleep(random.random())def consumer():while True:item = buffer.get()print(f"Consumed {item}")time.sleep(random.random())# 创建和启动生产者线程
producers = [threading.Thread(target=producer) for _ in range(NUM_PRODUCERS)]
for p in producers:p.start()# 创建和启动消费者线程
consumers = [threading.Thread(target=consumer) for _ in range(NUM_CONSUMERS)]
for c in consumers:c.start()
在此示例中,生产者线程不断生成数据并将其放入缓冲区,消费者线程不断从缓冲区获取数据。缓冲区使用 queue.Queue
实现,可以有效地避免数据竞争。
读写锁模式 (Read-Write Lock)
说明:读写锁模式允许多个读者同时读取数据,但只允许一个写者修改数据,避免数据不一致的情况。Python 中没有原生的读写锁实现,但可以使用 threading.RLock
和 threading.Condition
来实现。
import threading
import timeclass ReadWriteLock:def __init__(self):self.readers = 0self.writer = Falseself.lock = threading.RLock()self.readers_ok = threading.Condition(self.lock)def acquire_read(self):with self.lock:while self.writer:self.readers_ok.wait()self.readers += 1def release_read(self):with self.lock:self.readers -= 1if self.readers == 0:self.readers_ok.notify_all()def acquire_write(self):with self.lock:while self.writer or self.readers > 0:self.readers_ok.wait()self.writer = Truedef release_write(self):with self.lock:self.writer = Falseself.readers_ok.notify_all()# 使用示例
rw_lock = ReadWriteLock()def reader():while True:rw_lock.acquire_read()print("Reading data")time.sleep(1)rw_lock.release_read()time.sleep(1)def writer():while True:rw_lock.acquire_write()print("Writing data")time.sleep(2)rw_lock.release_write()time.sleep(1)# 启动读者线程和写者线程
threading.Thread(target=reader).start()
threading.Thread(target=writer).start()
在此示例中,acquire_read
和 acquire_write
确保多个读者可以同时读取,但只有一个写者可以写入数据。通过这种方式实现了线程安全的读写锁。