版权声明:本文为博主原创文章,未经博主允许不得转载。 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