• 命令模式 rust和java实现


    命令模式

    命令模式(Command Pattern)是一种数据驱动的设计模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

    介绍

    • 意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

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

    • 何时使用:当需要先将一个函数登记上,然后再以后调用此函数时,就需要使用命令模式,其实这就是回调函数。

    • 优点:1.类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。2.可扩展性:Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严 重的代码耦合。3.命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题。

    • 缺点:命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来 了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项 目中慎重考虑使用。

    命令模式结构示意图:
    在这里插入图片描述

    java

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

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

    步骤 1
    创建一个命令接口。

    Order.java

    public interface Order {
       void execute();
    }
    
    • 1
    • 2
    • 3

    步骤 2
    创建一个请求类。
    Stock.java

    public class Stock {
       
       private String name = "ABC";
       private int quantity = 10;
     
       public void buy(){
          System.out.println("Stock [ Name: "+name+", 
             Quantity: " + quantity +" ] bought");
       }
       public void sell(){
          System.out.println("Stock [ Name: "+name+", 
             Quantity: " + quantity +" ] sold");
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    BuyStock.java

    public class BuyStock implements Order {
       private Stock abcStock;
     
       public BuyStock(Stock abcStock){
          this.abcStock = abcStock;
       }
     
       public void execute() {
          abcStock.buy();
       }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    SellStock.java

    public class SellStock implements Order {
       private Stock abcStock;
     
       public SellStock(Stock abcStock){
          this.abcStock = abcStock;
       }
     
       public void execute() {
          abcStock.sell();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    步骤 4
    创建命令调用类。

    Broker.java
    import java.util.ArrayList;
    import java.util.List;

     public class Broker {
       private List<Order> orderList = new ArrayList<Order>(); 
     
       public void takeOrder(Order order){
          orderList.add(order);      
       }
     
       public void placeOrders(){
          for (Order order : orderList) {
             order.execute();
          }
          orderList.clear();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

    CommandPatternDemo.java

    public class CommandPatternDemo {
       public static void main(String[] args) {
          Stock abcStock = new Stock();
     
          BuyStock buyStockOrder = new BuyStock(abcStock);
          SellStock sellStockOrder = new SellStock(abcStock);
     
          Broker broker = new Broker();
          broker.takeOrder(buyStockOrder);
          broker.takeOrder(sellStockOrder);
     
          broker.placeOrders();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    步骤 6
    执行程序,输出结果:

    Stock [ Name: ABC, Quantity: 10 ] bought
    Stock [ Name: ABC, Quantity: 10 ] sold
    
    • 1
    • 2

    rust

    trait Order {
        fn execute(&self);
    }
    #[derive(Clone)]
    struct Stock{
        name:String,
        quantity:i32,
    }
    impl Stock {
        fn buy(&self) {
            println!("Stock [ Name : {}  Quantity: {}] bought",self.name,self.quantity);
        }
        fn sell(&self) {
            println!("Stock [ Name : {}  Quantity: {}] sold",self.name,self.quantity);
        }
        fn new()->Stock{
            Stock{
                name:"ABC".to_owned(),
                quantity:10
            }
        }
    }
    // 创建命令实体
    struct  BuyStock {
        abc_stock:Stock
    }
    impl Order for BuyStock {
        fn execute(&self) {
            self.abc_stock.buy();
        }
    }
    struct  SellStock {
        abc_stock:Stock
    }
    impl Order for SellStock {
        fn execute(&self) {
            self.abc_stock.sell();
        }
    }
    // 创建命令调用类。
    struct Broker{
        order_list:Vec>
    }
    impl Broker {
        fn take_order(&mut self,order:impl Order+ 'static){
            
            self.order_list.push(Box::new(order));
        }
        fn place_orders(&self){
            self.order_list.iter().for_each(|f|f.execute());
        }
        fn  new()->Broker {
            Broker{
                order_list:vec![]
            }
        }
    }
    fn main(){
        let stock=Stock::new();
       
        let buy=BuyStock{abc_stock:stock.clone()};
        let sell=SellStock{abc_stock:stock.clone()};
        let mut broker=Broker::new();
        broker.take_order(buy);
        broker.take_order(sell);
        broker.place_orders();
    
    }
    
    • 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

    rust仓库

    https://github.com/onenewcode/design.git
    本教程项目在bin文件夹下的command.rs文件中

  • 相关阅读:
    单链表的实现
    什么是 DevOps?看这一篇就够了!
    基于springboot+vue水务报修处理系统
    Flink部署模式及核心概念
    MySQL索引机制(详细+原理+解析)
    26装饰器3(在面向对象的过程中使用装饰器)
    基于springboot小型车队管理系统毕业设计源码061709
    vue使用Element-plus的Image预览时样式崩乱
    详解ConCurrentHashMap源码(jdk1.8)
    JavaEE -- Spring的创建和使用
  • 原文地址:https://blog.csdn.net/studycodeday/article/details/134682871