菜鸟教程 -- 学的不仅是技术,更是梦想!

设计模式
(追記) (追記ここまで)

命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。

命令模式将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

命令模式结构示意图:

介绍

意图

将请求封装为一个对象,允许用户使用不同的请求对客户端进行参数化。

主要解决的问题

  • 解决在软件系统中请求者和执行者之间的紧耦合问题,特别是在需要对行为进行记录、撤销/重做或事务处理等场景。

使用场景

  • 当需要对行为进行记录、撤销/重做或事务处理时,使用命令模式来解耦请求者和执行者。

实现方式

  • 定义命令接口:所有命令必须实现的接口。
  • 创建具体命令:实现命令接口的具体类,包含执行请求的方法。
  • 调用者:持有命令对象并触发命令的执行。
  • 接收者:实际执行命令的对象。

关键代码

  • 接收者(Receiver):执行命令的实际对象。
  • 命令(Command):定义执行命令的接口。
  • 调用者(Invoker):使用命令对象的入口点。

应用实例

  • Struts 1:ActionServlet作为Invoker,模型层的类作为具体的Command。

优点

  1. 降低耦合度:请求者和执行者之间的耦合度降低。
  2. 易于扩展:新命令可以很容易地添加到系统中。

缺点

  • 过多命令类:系统可能会有过多的具体命令类,增加系统的复杂度。

使用建议

  • 在GUI中,每个按钮或菜单项可以视为一条命令。
  • 在需要模拟命令行操作的场景中使用命令模式。

注意事项

  • 如果系统需要支持命令的撤销(Undo)和恢复(Redo)操作,命令模式是一个合适的选择。

结构

主要涉及到以下几个核心角色:

  • 命令(Command):

    • 定义了执行操作的接口,通常包含一个 execute 方法,用于调用具体的操作。
  • 具体命令(ConcreteCommand):

    • 实现了命令接口,负责执行具体的操作。它通常包含了对接收者的引用,通过调用接收者的方法来完成请求的处理。
  • 接收者(Receiver):

    • 知道如何执行与请求相关的操作,实际执行命令的对象。
  • 调用者/请求者(Invoker):

    • 发送命令的对象,它包含了一个命令对象并能触发命令的执行。调用者并不直接处理请求,而是通过将请求传递给命令对象来实现。
  • 客户端(Client):

    • 创建具体命令对象并设置其接收者,将命令对象交给调用者执行。

实现

我们首先创建作为命令的接口 Order,然后创建作为请求的 Stock 类。实体命令类 BuyStockSellStock,实现了 Order 接口,将执行实际的命令处理。创建作为调用对象的类 Broker,它接受订单并能下订单。

Broker 对象使用命令模式,基于命令的类型确定哪个对象执行哪个命令。CommandPatternDemo 类使用 Broker 类来演示命令模式。

步骤 1

创建一个命令接口。

Order.java

publicinterfaceOrder{voidexecute(); }

步骤 2

创建一个请求类。

Stock.java

publicclassStock{privateStringname = "ABC"; privateintquantity = 10; publicvoidbuy(){System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] bought"); }publicvoidsell(){System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] sold"); }}

步骤 3

创建实现了 Order 接口的实体类。

BuyStock.java

publicclassBuyStockimplementsOrder{privateStockabcStock; publicBuyStock(StockabcStock){this.abcStock = abcStock; }publicvoidexecute(){abcStock.buy(); }}

SellStock.java

publicclassSellStockimplementsOrder{privateStockabcStock; publicSellStock(StockabcStock){this.abcStock = abcStock; }publicvoidexecute(){abcStock.sell(); }}

步骤 4

创建命令调用类。

Broker.java

importjava.util.ArrayList; importjava.util.List; publicclassBroker{privateList<Order> orderList = newArrayList<Order>(); publicvoidtakeOrder(Orderorder){orderList.add(order); }publicvoidplaceOrders(){for(Orderorder : orderList){order.execute(); }orderList.clear(); }}

步骤 5

使用 Broker 类来接受并执行命令。

CommandPatternDemo.java

publicclassCommandPatternDemo{publicstaticvoidmain(String[]args){StockabcStock = newStock(); BuyStockbuyStockOrder = newBuyStock(abcStock); SellStocksellStockOrder = newSellStock(abcStock); Brokerbroker = newBroker(); broker.takeOrder(buyStockOrder); broker.takeOrder(sellStockOrder); broker.placeOrders(); }}

步骤 6

执行程序,输出结果:

Stock [ Name: ABC, Quantity: 10 ] bought
Stock [ Name: ABC, Quantity: 10 ] sold
AI 思考中...

3 篇笔记 写笔记

  1. #0

    Siskin.xu

    sis***@sohu.com

    39

    Python 方式:

    # Command Pattern with Python Code
    from abc import abstractmethod,ABCMeta
    # 创建一个命令接口Order
    class Order(metaclass=ABCMeta):
     @abstractmethod
     def execute(self):
     pass
    # 创建一个请求类
    class Stock():
     _name = "ABC"
     _quantity = 10
     def buy(self):
     print("Stock [Name : {0}, Quantity: {1}] bought.".format(self._name,self._quantity))
     def sell(self):
     print("Stock [Name : {0}, Quantity: {1}] sold.".format(self._name, self._quantity))
    # 创建实现了Order接口的实体类
    class BuyStock(Order):
     _abcStock = None
     def __init__(self,inStock):
     self._abcStock = inStock
     def execute(self):
     self._abcStock.buy()
    class SellStock(Order):
     _abcStock = None
     def __init__(self,inStock):
     self._abcStock = inStock
     def execute(self):
     self._abcStock.sell()
    # 创建命令调用类
    class Broker():
     _orderList = []
     def takeOrder(self,inOrder):
     self._orderList.append(inOrder)
     def placeOrders(self):
     for aOrder in self._orderList:
     aOrder.execute()
     self._orderList.clear()
    # 调用输出
    if __name__ == '__main__':
     abcStock = Stock()
     buyStockOrder = BuyStock(abcStock)
     sellStockOrder = SellStock(abcStock)
     broker = Broker()
     broker.takeOrder(buyStockOrder)
     broker.takeOrder(sellStockOrder)
     broker.placeOrders()

    Siskin.xu

    sis***@sohu.com

    6年前 (2020年03月07日)
  2. #0

    Siskin.xu

    sis***@sohu.com

    27

    Python 代码:

    # Command Pattern with Python Code
    from abc import abstractmethod,ABCMeta
    # 创建一个命令接口Order
    class Order(metaclass=ABCMeta):
     @abstractmethod
     def execute(self):
     pass
    # 创建一个请求类
    class Stock():
     _name = "ABC"
     _quantity = 10
     def buy(self):
     print("Stock [Name : {0}, Quantity: {1}] bought.".format(self._name,self._quantity))
     def sell(self):
     print("Stock [Name : {0}, Quantity: {1}] sold.".format(self._name, self._quantity))
    # 创建实现了Order接口的实体类
    class BuyStock(Order):
     _abcStock = None
     def __init__(self,inStock):
     self._abcStock = inStock
     def execute(self):
     self._abcStock.buy()
    class SellStock(Order):
     _abcStock = None
     def __init__(self,inStock):
     self._abcStock = inStock
     def execute(self):
     self._abcStock.sell()
    # 创建命令调用类
    class Broker():
     _orderList = []
     def takeOrder(self,inOrder):
     self._orderList.append(inOrder)
     def placeOrders(self):
     for aOrder in self._orderList:
     aOrder.execute()
     self._orderList.clear()
    # 调用输出
    if __name__ == '__main__':
     abcStock = Stock()
     buyStockOrder = BuyStock(abcStock)
     sellStockOrder = SellStock(abcStock)
     broker = Broker()
     broker.takeOrder(buyStockOrder)
     broker.takeOrder(sellStockOrder)
     broker.placeOrders()

    Siskin.xu

    sis***@sohu.com

    6年前 (2020年03月11日)
  3. #0

    嗯先生

    129***[email protected]

    6

    Kotlin 写法:

    interface Order {
     fun execute()
    }
    class Stock {
     private val name = "ABC" private val quantitle = 10 fun buy(){
     println("Stoke [ Name:$name,Quantity:$quantitle] bought")
     }
     fun sell(){
     println("Stoke [ Name:$name,Quantity:$quantitle] sold")
     }
    }
    class BuyStock: Order {
     private lateinit var abcStock: Stock
     constructor(abcStock: Stock){
     this.abcStock = abcStock
     }
     override fun execute() {
     abcStock.buy()
     }
    }
    class SellStock: Order {
     private lateinit var abcStock: Stock
     constructor(abcStock: Stock){
     this.abcStock = abcStock
     }
     override fun execute() {
     abcStock.sell()
     }
    }
    class Broker {
     private val orderList = mutableListOf<Order>()
     fun takeOrder(order: Order){
     orderList.add(order)
     }
     fun placeOrders(){
     for(order in orderList){
     order.execute()
     }
     orderList.clear()
     }
    }
    fun main(){
     val buyStock = BuyStock(Stock())
     val sellStock = SellStock(Stock())
     Broker().apply { 
     takeOrder(buyStock)
     takeOrder(sellStock)
     placeOrders()
     }
    }

    嗯先生

    129***[email protected]

    5年前 (2021年10月08日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /