zoukankan      html  css  js  c++  java
  • 行为型模式之 命令模式

    命令模式(Command Pattern):将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。

    主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

    何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

    如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。

    关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口

    优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。

    缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

    模式动机

    在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。

    命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。

    实现

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

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

    //步骤一 创建一个命令接口
    class Order {
    public:
        virtual void execute() {}
    };
    
    //步骤二 创建一个请求类
    class Stock {
    private:
        string name = "ABC";
        int quantity = 10;
    public:
        void Buy() {
            printf("Buy Stock Name = %s, Quantity = %d",name.c_str(),quantity);
        }
        void Sell() {
            printf("Sell Stock Name = %s, Quantity = %d", name.c_str(), quantity);
        }
    };
    
    //步骤 3 创建实现了 Order 接口的实体类
    
    class BuyStock : public Order {
    private:
        Stock* abcstock;
    public:
        BuyStock(Stock* stock)
        {
            abcstock = stock;
        }
        BuyStock() {}
        void execute() {
            abcstock->Buy();
        }
    };
    
    class SellStock :public Order {
    private:
        Stock * abcstock;
    public:
        SellStock(Stock* stock)
        {
            abcstock = stock;
        }
        SellStock() {}
        void execute() {
            abcstock->Sell();
        }
    };
    
    //步骤 4 创建命令调用类
    class Broker {
    private:
        list<Order*> orderlist;
    public:
        void takeOrder(Order* ord) { orderlist.push_back(ord); }
        void placeOrders() {
            list<Order*>::iterator ite = orderlist.begin();
            for (; ite != orderlist.end(); ++ite)
            {
                (*ite)->execute();
            }
        }
    };
    
    int main() 
    {
        Stock stock;
        BuyStock buy(&stock);
        SellStock sell(&stock);
    
        Broker broker;
        broker.takeOrder(&buy);
        broker.takeOrder(&sell);
    
        broker.placeOrders();
        return 0;
    }
  • 相关阅读:
    计算机组成原理学习总纲图
    USE RED
    既有的问题如何解决
    字符串极值题解
    扩展 KMP
    KMP
    FHQ-Treap
    STL
    iOS内存管理理论知识过一遍
    iOS中Block理论知识过一遍
  • 原文地址:https://www.cnblogs.com/gardenofhu/p/8507631.html
Copyright © 2011-2022 走看看