设计模式-命令模式

[TOC]

设计模式-命令模式

定义

命令模式(Command Pattern)是对命令的一个封装,每一个命令都是一个操作。请求的一方发出请求,要求执行一个操作,接收的一方收到请求并执行操作。命令模式解耦了请求方和接收方,请求方只需要请求执行命令,不用关心命令是怎么被接收的,怎样被操作等。

本质:解耦命令请求和处理。

属于行为型模式。

适用场景

  1. 现实语义中具备“命令”操作
  2. 请求调用者和请求的接收者需要解耦,使得调用者和接受者不直接交互
  3. 需要抽象出等待执行的行为,比如撤销操作和恢复操作等
  4. 需要支持命令宏(即命令组合操作)

代码示例

拿下单举例:

  1. 新建 饭 类和 订单 类
package com.black.design.pattern.command.order;

// 饭
public class Meal {
    
    // 饭名
    private String name ;
    // 价格
    private double price;
    // 数量
    private int amt;
    
    public Meal(String name, double price, int amt) {
        super();
        this.name = name;
        this.price = price;
        this.amt = amt;
    }


    public String getName() {
        return name;
    }


    public double getPrice() {
        return price;
    }


    public int getAmt() {
        return amt;
    }

    // 总价
    public double getTotalAmt() {
        return price * amt;
    }
}

package com.black.design.pattern.command.order;

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

// 订单
public class Order {
    // 饭
    private List<Meal> meals = new ArrayList<Meal>();
    // 订单总价
    private double totalAmt;
    
    public Order() {
       
    }
    
    //点菜
   public void addMeal(Meal meal){
       meals.add(meal);
       totalAmt = totalAmt + meal.getAmt() * meal.getPrice();
    }
   
    // 总价
    public double getTotalAmt() {
        return totalAmt;
    }

    public List<Meal> getMeals() {
        return meals;
    }

}

  1. 新建 厨师 类和 收银员 类
package com.black.design.pattern.command.order;

import java.util.List;

// 厨师
public class Cook{

    // 订单
    private Order o;
    
    public Cook(Order o ) {
       this.o = o;
    }
    
    public void cook() {
         System.out.println("厨师做饭开始...");
         List<Meal> meals =  o.getMeals();
         for (Meal meal: meals) {
             System.out.println(meal.getName() +"做好了,一共" +meal.getAmt()+"份" );
        }
         System.out.println("厨师做饭结束。");
    }
}

package com.black.design.pattern.command.order;

// 收银员
public class Cashier{
    
   // 订单
    private Order o;
    
    public Cashier(Order o ) {
       this.o = o;
    }
    
    public void checkOut() {
       System.out.println("收银员开始结账...");
       System.out.println("一共应收取"+o.getTotalAmt()+"元");
       System.out.println("已结账...");
    }
}
  1. 创建命令接口类和【下单】【结账】命令类
package com.black.design.pattern.command.order;

// 命令接口类
public interface ICommand {
  //执行命令
    public void  execute();
}

package com.black.design.pattern.command.order;

import com.black.design.pattern.command.order.ICommand;

// 下单命令
public class PlaceOrderCommand implements ICommand {

    // 厨师
    private Cook cook;
    
    public PlaceOrderCommand(Cook cook) {
        this.cook = cook;
    }
    
    public void execute() {
        // 开始做饭
        cook.cook();
    }

}

package com.black.design.pattern.command.order;

import com.black.design.pattern.command.order.ICommand;

// 结账命令
public class CheckOutCommand implements ICommand {
    
    // 收银员
    private Cashier cashier;
    
    public CheckOutCommand(Cashier cashier) {
        this.cashier = cashier;
    }
    
    public void execute() {
        // 结账
        cashier.checkOut();
    }

}

  1. 创建服务员类,用于执行命令
package com.black.design.pattern.command.order;

import java.util.List;

import com.black.design.pattern.command.order.ICommand;

// 服务员
public class Waiter {

 private List<ICommand> commands;
    
    public void setCommands(List<ICommand> cds) {
        this.commands = cds;
    }
    
    // 执行命令
    public void executeCommands() {
        for (ICommand command : commands) {
            command.execute();
        }
    }
}

  1. 测试
package com.black.design.pattern.command.order;

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

public class Clinet {
    
    public static void main(String[] args) {
        
        // 去饭馆吃饭,开始点菜
        System.out.println("=====================");
        System.out.println("     进饭馆吃饭");
        System.out.println("=====================");
        System.out.println("进饭馆,叫来了一个服务员");
        Waiter waiter = new Waiter();
       
        Meal chaoJiDan = new Meal("炒鸡蛋",12.00,1);
        Meal feiniuFan = new Meal("肥牛盖饭",18.00,1);
        Meal liufeichang = new Meal("溜肥肠",48.00,1);
        Meal mapodoufu = new Meal("麻婆豆腐",24.00,1);
        System.out.println("点了一份炒鸡蛋");
        System.out.println("点了一份肥牛盖饭");
        System.out.println("点了一份溜肥肠");
        System.out.println("点了一份麻婆豆腐");

        Order order = new Order();
        order.addMeal(chaoJiDan);
        order.addMeal(feiniuFan);
        order.addMeal(liufeichang);
        order.addMeal(mapodoufu);
        
        // 下单
        Cook cook = new Cook(order);
        ICommand placeOrder = new PlaceOrderCommand(cook);
        List<ICommand>   commands = new ArrayList<ICommand>();
        commands.add(placeOrder);
        waiter.setCommands(commands);
        System.out.println("点好了,让服务员去下单");
        System.out.println("服务员去下单了...");
        waiter.executeCommands();
        
        System.out.println("=====================");
        System.out.println("     吃饭中...");
        System.out.println("=====================");
        System.out.println("吃完了,叫服务员过来结账");
       
        // 结账
        Cashier cashier = new Cashier(order);
        ICommand checkout = new CheckOutCommand(cashier);
        List<ICommand>   commands2 = new ArrayList<ICommand>();
        commands2.add(checkout);
        waiter.setCommands(commands2);
        waiter.executeCommands();
        System.out.println("=====================");
        System.out.println("     离开饭馆");
        System.out.println("=====================");
    }
}

结果:

=====================
     进饭馆吃饭
=====================
进饭馆,叫来了一个服务员
点了一份炒鸡蛋
点了一份肥牛盖饭
点了一份溜肥肠
点了一份麻婆豆腐
点好了,让服务员去下单
服务员去下单了...
厨师做饭开始...
炒鸡蛋做好了,一共1份
肥牛盖饭做好了,一共1份
溜肥肠做好了,一共1份
麻婆豆腐做好了,一共1份
厨师做饭结束。
=====================
     吃饭中...
=====================
吃完了,叫服务员过来结账
收银员开始结账...
一共应收取102.0元
已结账...
=====================
     离开饭馆
=====================

设计模式-命令模式

上一篇:030.程序流程结构-循环结构-while语句


下一篇:PS真正实用技巧:曲线、滤镜、智能对象、字体