1.命令模式

命令模式包含以下主要角色:

  • 抽象命令类(Command)角色: 定义命令的接口,声明执行的方法。

  • 具体命令(Concrete Command)角色:具体的命令,实现命令接口;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。

  • 实现者/接收者(Receiver)角色: 接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。

  • 调用者/请求者(Invoker)角色: 要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。

订单类:


import java.util.HashMap;
import java.util.Map;

//订单类
public class Order {
    //餐桌号码
    private int diningTable;
    //所下的餐品及份数
    private Map<String, Integer> foodDir = new HashMap<>();

    public int getDiningTable() {
        return diningTable;
    }

    public void setDiningTable(int diningTable) {
        this.diningTable = diningTable;
    }

    public Map<String, Integer> getFoodDir() {
        return foodDir;
    }

    public void setFood(String name, int num) {
        foodDir.put(name, num);
    }
}

抽象命令类:

//抽象命令类
public interface Command {
    void execute();
}

具体命令:

import java.util.Map;
import java.util.Set;

//具体的命令类
public class OrderCommand implements Command {

    //持有接收者对象
    private SeniorChef receiver;
    //持有订单对象
    private Order order;

    public OrderCommand(SeniorChef receiver, Order order) {
        this.receiver = receiver;
        this.order = order;
    }

    public void execute() {
        System.out.println(order.getDiningTable() + "桌的订单:");
        Map<String, Integer> foodDir = order.getFoodDir();
        //遍历map集合
        Set<String> keys = foodDir.keySet();
        for (String foodName : keys) {
            receiver.makeFood(foodName, foodDir.get(foodName));//餐品名称,份数
        }

        System.out.println(order.getDiningTable() + "桌的饭准备完毕!!!");
    }
}

实现者/接收者:

//厨师类:接收者对象
public class SeniorChef {

    public void makeFood(String name, int num) {
        System.out.println(num + "份" + name);
    }
}

调用者/请求者:

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

//服务员类:调用者角色
public class Waitor {

    //持有多个命令对象
    private List<Command> commands = new ArrayList<>();

    public void setCommand(Command cmd) {
        //将cmd对象存储到list集合中
        commands.add(cmd);
    }

    //发起命令的功能
    public void orderUp() {
        System.out.println("美女服务员:大厨,新订单来了。。。。");
        //遍历list集合
        for (Command command : commands) {
           if(command != null) {
               command.execute();
           }
        }
    }
}

测试类:

//测试类
public class Client {
    public static void main(String[] args) {
        //创建第一个订单对象
        Order order1 = new Order();
        order1.setDiningTable(101);
        order1.setFood("西红柿鸡蛋面",1);
        order1.setFood("小杯可乐",2);

        //创建第二个订单对象
        Order order2 = new Order();
        order2.setDiningTable(102);
        order2.setFood("尖椒肉丝盖饭",1);
        order2.setFood("小杯雪碧",1);

        //创建厨师对象
        SeniorChef receiver = new SeniorChef();

        //创建命令对象(聚合厨师和订单)
        OrderCommand cmd1 = new OrderCommand(receiver,order1);
        OrderCommand cmd2 = new OrderCommand(receiver,order2);

        //创建调用者(服务员对象)
        Waitor invoke = new Waitor();
        invoke.setCommand(cmd1);
        invoke.setCommand(cmd2);

        //让服务员发起命令
        invoke.orderUp();
    }
}

Runable是一个典型命令模式

Runnable担当命令的角色,Thread充当的是调用者,start方法就是其执行方法

//抽象命令
public interface Runnable {
    public abstract void run();
}


//具体命令角色(自己定义的)
public class TurnOnThread implements Runnable {
    private Receiver receiver;

    public TurnOnThread(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void run() {
        receiver.excute();
    }
}


//接收者(自己定义的)
public class Receiver {
    public void excute(){
        System.out.println("开启线程");
    }
}


//调用者
public class Thread implements Runnable {
    private Runnable target;
    
    public synchronized void start() {//执行方法
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
            }
        }
    }
    
    private native void start0();
}


//测试类
public class Demo {
    public static void main(String[] args) {
        TurnOnThread turnOnThread = new TurnOnThread(new Receiver());
        Thread thread = new Thread(turnOnThread);
        thread.start();
    }
}

2.责任链模式

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

请假条类:

//请假条类
public class LeaveRequest {

    private String name; //姓名
    private int num;//请假天数
    private String content;//请假内容

    public LeaveRequest(String name, int num, String content) {
        this.name = name;
        this.num = num;
        this.content = content;
    }

    public String getName() {
        return name;
    }

    public int getNum() {
        return num;
    }

    public String getContent() {
        return content;
    }
}

抽象处理者:

//抽象处理者类
public abstract class Handler {

    //设置常量
    protected final static int NUM_ONE = 1;
    protected final static int NUM_THREE = 3;
    protected final static int NUM_SEVEN = 7;

    //成员变量
    private int numStart;//该领导处理的请求天数区间
    private int numEnd;
    private Handler nextHandler;//声明后续者(声明上级领导)

    //构造方法
    public Handler(int numStart) {
        this.numStart = numStart;
    }

    public Handler(int numStart, int numEnd) {
        this.numStart = numStart;
        this.numEnd = numEnd;
    }

    //设置上级领导对象
    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    //各级领导处理请求条的方法
    protected abstract void handleLeave(LeaveRequest leave);

    //提交请求条
    public final void submit(LeaveRequest leave) {
        //该领导进行审批
        this.handleLeave(leave);
        if (this.nextHandler != null && leave.getNum() > this.numEnd) {
            //提交给上级领导进行审批
            this.nextHandler.submit(leave);
        } else {
            System.out.println("流程结束!");
        }
    }
}

具体处理者:

//小组长类:具体的处理者
public class GroupLeader extends Handler {

    public GroupLeader() {
        super(0,Handler.NUM_ONE);
    }

    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("小组长审批:同意");
    }
}


//部门经理类:具体的处理者
public class Manager extends Handler {

    public Manager() {
        super(Handler.NUM_ONE, Handler.NUM_THREE);
    }

    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("部门经理审批:同意");
    }
}


//总经理类:具体的处理者
public class GeneralManager extends Handler {

    public GeneralManager() {
        super(Handler.NUM_THREE, Handler.NUM_SEVEN);
    }

    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("总经理审批:同意");
    }
}


//董事长类:具体的处理者
public class Chairman extends Handler {

    public Chairman() {
        super(Handler.NUM_SEVEN);//只需要设置最小天数
    }

    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("老板审批:同意");
    }
}

测试类:

//测试类
public class Client {
    public static void main(String[] args) {
        //创建一个请假条对象
        LeaveRequest leave = new LeaveRequest("小明", 10, "身体不适");

        //创建各级领导对象
        GroupLeader groupLeader = new GroupLeader();
        Manager manager = new Manager();
        GeneralManager generalManager = new GeneralManager();
        Chairman chairman = new Chairman();

        //设置处理者链
        groupLeader.setNextHandler(manager);
        manager.setNextHandler(generalManager);
        generalManager.setNextHandler(chairman);

        //小明提交请假申请
        groupLeader.submit(leave);
    }
}

更多推荐