大话设计模式学习笔记(23)——命令模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/q1052196521/article/details/79730257

源码git地址 https://github.com/dlovetco/designMode

问题提出

小明在一家烧烤店里吃烧烤。店里人很多,所以由服务员来负责记录客人们点了哪些菜。之后再把要烧烤的菜单拿到后厨给厨师。用代码实现小明点单的场景。

普通情况下,一般都是客人直接像厨师发出请求。但是这样的坏处在于客人不能更改自己的订单,而且没有具体的记录下来菜单,不好算账。所以这个服务员类就是负责保存以及记录日志的。

命令模式

讲一个请求分装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

package commandmode;

import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

public class CommandMode {
    public static void main(String[] args) {
        String customer = "小明";
        Waiter waiter = new Waiter();//服务员
        Chef chef = new Chef();//厨师
        Order meatOrder = new MeatOrder(chef);
        waiter.addOrder(customer, meatOrder);
        waiter.addOrder(customer, new VegetableOrder(chef));
        waiter.removeOrder(customer,meatOrder);
        waiter.excuteOrders();
    }
}

/**
 * 各种各样的订单
 */
interface Order {
    //执行订单
    void excuteOrder();
}

class VegetableOrder implements Order {

    private Chef chef;

    public VegetableOrder(Chef chef) {
        this.chef = chef;
    }

    @Override
    public void excuteOrder() {
        chef.cookVegetable();
    }

    @Override
    public String toString() {
        return "点了一串蔬菜,时间为:  " + LocalTime.now();
    }
}

class MeatOrder implements Order {

    private Chef chef;

    public MeatOrder(Chef chef) {
        this.chef = chef;
    }

    @Override
    public void excuteOrder() {
        chef.cookMeat();
    }

    @Override
    public String toString() {
        return "点了一串肉,时间为:  " + LocalTime.now();
    }
}

/**
 * 厨师
 */
class Chef {

    public void cookMeat() {
        System.out.println("厨师烤了一串肉");
    }

    public void cookVegetable() {
        System.out.println("厨师烤了一串蔬菜");
    }
}

class Waiter {
    private List<Order> orderList = new ArrayList<>();

    public void addOrder(String name, Order order) {
        System.out.println(name + "点了" + order.toString());
        orderList.add(order);
    }

    public void removeOrder(String name, Order order) {
        System.out.println(name + "取消" + order.toString());
        orderList.remove(order);
    }

    /**
     * 整个菜单交给厨师开始制作
     */
    public void excuteOrders() {
        orderList.forEach(Order::excuteOrder);
    }
}

输出:
小明点了点了一串肉,时间为: 16:20:16.987
小明点了点了一串蔬菜,时间为: 16:20:16.989
小明取消点了一串肉,时间为: 16:20:16.990
厨师烤了一串蔬菜

这里,我们把给厨师下的命令分装成了对象,这样就可以在waiter类中进行保存。

命令模式的优点在于:
1. 能够比较容易地设计一个命令队列
2. 能够在一些情况下将命令记录日志
3. 允许接收请求的一方决定是否要否决请求
4. 容易实现对请求的撤销和重做
5. 加入新的命令类不需要改变其他的类
6. 把请求一个操作的对象与知道怎么执行一个操作的对象分割开

plantuml

@startuml
interface Order{
excuteOrder()
}
Order <|.. VegetableOrder
class VegetableOrder{
Chef chef
excuteOrder()
}
Order <|.. MeatOrder
class MeatOrder{
Chef chef
excuteOrder()
}

Order <..* Waiter
class Waiter{
List<Order> orderList
}

Chef <-- VegetableOrder
Chef <-- MeatOrder
class Chef{
cookMeat()
cookVegetable()
}
@enduml

这里写图片描述

猜你喜欢

转载自blog.csdn.net/q1052196521/article/details/79730257
今日推荐