《设计模式》17.命令模式(行为型)

将请求封装成为命令对象,使“方法的请求者”与“方法的实现者”解耦。命令对象可以被存储、转发、排队、记录、处理、撤销等。又称为动作(Action)模式或事务(Transaction)模式。

角色

调用者/请求者(Invoker):请求的发送者,持有一个或多个命令对象,通过调用命令对象执行命令接口处理相关请求,它不直接访问接收者
抽象命令类(Command):声明执行命令的接口(execute)
具体命令(ConcreteCommand):抽象命令类的实现类,持有接收者对象,调用接收者的功能接口完成操作。
实现者/接收者(Receiver):执行命令功能的相关操作,是命令的真正实现者

调用者/请求者 Invoker

public class Invoker {
    private Command command;
    public Invoker() { }

    public void setCommand(Command command) {
        this.command = command;
    }

    public void commit() {
        this.command.execute();
    }

    public void rollback() {
        this.command.recover();
    }
}

抽象命令类 Command

public interface Command {
    void execute();
    void recover();
}

具体命令 Concrete Command

public class ConcreteCommand implements Command {
    private Receiver receiver;
    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }
    @Override
    public void execute() {
        receiver.operate();
    }

    @Override
    public void recover() {
        receiver.cancel();
    }
}

实现者/接收者 Receiver

public class Receiver {
    public void operate() {
        System.out.println("operate...");
    }

    public void cancel() {
        System.out.println("cancel...");
    }
}

测试类

public class CommandPattern {
    public static void main(String args[]) {
        Receiver receiver = new Receiver();
        Invoker invoker = new Invoker();
        invoker.setCommand(new ConcreteCommand(receiver));
        try {
            invoker.commit();
            throw new RuntimeException("error occur...");
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());
            invoker.rollback();
        }
    }
}
operate...
error occur...
cancel...

举例:餐厅点菜

通过服务员(调用者)点菜,支持批量操作,将菜作为命令,根据不同的菜系分配给不同的厨师

public class Waiter {
    private List<Cuisine> cuisines = new ArrayList<>();
    public void addCuisine(Cuisine cuisine) {
        this.cuisines.add(cuisine);
    }

    public void addCuisines(Cuisine ... coll) {
        for (Cuisine cuisine : coll) {
            if (!cuisines.contains(cuisine))
                cuisines.add(cuisine);
        }
    }

    public void addCuisines(Collection<Cuisine> coll) {
        cuisines.addAll(new HashSet<>(coll));
    }

    public void order() {
        for (Cuisine cuisine : cuisines) {
            cuisine.order();
        }
    }
}
public interface Cuisine {
    void order();
}
public class CantoneseCuisine implements Cuisine {
    private Chef chef = new CantoneseCuisineChef();

    @Override
    public void order() {
        this.chef.cooking();
    }
}

public class HunanCuisine implements Cuisine {
    private Chef chef = new HunanCuisineChef();

    @Override
    public void order() {
        chef.cooking();
    }
}

public class SichuanCuisine implements Cuisine {
    private Chef chef = new SichuanCuisineChef();

    @Override
    public void order() {
        this.chef.cooking();
    }
}
public interface Chef {
    void cooking();
}

public class CantoneseCuisineChef implements Chef {
    @Override
    public void cooking() {
        System.out.println("cooking cantonese cuisine...");
    }
}

public class HunanCuisineChef implements Chef {
    @Override
    public void cooking() {
        System.out.println("cooking hunan cuisine...");
    }
}

public class SichuanCuisineChef implements Chef {
    @Override
    public void cooking() {
        System.out.println("cooking sichuan cuisine...");
    }
}
public class CommandPattern {
    public static void main(String args[]) {
        Waiter waiter = new Waiter();

        waiter.addCuisine(new HunanCuisine());
        waiter.addCuisine(new CantoneseCuisine());
        waiter.addCuisine(new SichuanCuisine());

        waiter.order();
    }
}
cooking hunan cuisine...
cooking cantonese cuisine...
cooking sichuan cuisine...

举例:前端请求服务器

将请求封装,通过客户端执行不同的请求,后台执行不同的业务操作

public class FrontClient {
    private Request request;
    public void setRequest(Request request) {
        this.request = request;
    }

    public void get() {
        request.doGet();
    }

    public void post() {
        request.doPost();
    }
}
public interface Request {
    void doGet();
    void doPost();
}
public class HttpRequest implements Request {
    private Backend backend;
    public HttpRequest(Backend backend) {
        this.backend = backend;
    }

    @Override
    public void doGet() {
        backend.doGetService();
    }

    @Override
    public void doPost() {
        backend.doPostService();
    }
}
public class Backend {
    public void doGetService() {
        System.out.println("do get service...");
    }
    
    public void doPostService() {
        System.out.println("do post service...");
    }
}
public class CommandPattern {
    public static void main(String args[]) {
        Backend backend = new Backend();
        Request request = new HttpRequest(backend);

        FrontClient client = new FrontClient();
        client.setRequest(request);

        client.get();
        client.post();
    }
}
do get service...
do post service...
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值