命令模式(Command)
解决命令执行问题
描述
将一个请求封装为一个对象,并定义该对象的执行方法,从而使得请求能够被延迟、队列化、记录和撤销。这种方式可以提高代码的重用性和可维护性,同时也能够支持事务性操作。
适用环境
当需要将请求封装成对象时使用;当需要支持撤销操作时使用。
优点:
可以将请求的发送者和接收者解耦,提高系统的灵活性;可以很容易地扩展新的命令。
缺点:
对于过多的命令,会导致系统代码变得复杂;命令模式可能会导致系统的性能下降。
违反原则:
开放-封闭原则:如果需要增加新的命令,则需要修改所有的命令类,违反该原则。
代码实现
书店订单系统当客户提交订单时需要将订单信息保存下来。
现在使用传统的方式来处理订单:
class Book:
def __init__(self, name, price):
self.name = name
self.price = price
class Order:
def __init__(self):
self.order_items = []
def add_item(self, item):
self.order_items.append(item)
def place_order(self):
total_price = sum([item.price for item in self.order_items])
print(f"订单总金额为{total_price}元")
book1 = Book('Python编程从入门到实践', 68.0)
book2 = Book('流畅的Python', 79.0)
order = Order()
order.add_item(book1)
order.add_item(book2)
order.place_order()
以上代码存在以下问题:
- 对订单进行其他操作时需要修改原有的代码。不同的操作编写不同的方法导致代码冗余。
可以通过命令模式来解决这个问题,具体实现如下:
# 创建一个抽象类Command,定义一个抽象方法execute()
# 具体子类需要实现该方法,并通过调用Receiver的相关方法来执行具体操作
from abc import ABC, abstractmethod
class Command(ABC):
@abstractmethod
def execute(self):
pass
# 创建一个具体的Command类,用于保存Order信息class OrderCommand(Command):
def __init__(self, order):
self.order = order
def execute(self):
total_price = sum([item.price for item in self.order.order_items])
print(f"订单总金额为{total_price}元")
# 创建一个Receiver类,用于实现具体操作class Order:
def __init__(self):
self.order_items = []
def add_item(self, item):
self.order_items.append(item)
def remove_item(self, item):
self.order_items.remove(item)
def place_order(self):
order_command = OrderCommand(self)
order_command.execute()
book1 = Book('Python编程从入门到实践', 68.0)
book2 = Book('流畅的Python', 79.0)
order = Order()
order.add_item(book1)
order.add_item(book2)
order.place_order()