命令模式

命令模式:
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可测销的操作。

在软件系统中,行为请求者和行为实现者通常是一种紧耦合的关系,但在某些场合,需要对请求做记录,有撤销等处理时,这种紧耦合就难以处理,需要用到一个接收者(Invoker)。

命令模式组成:
这里写图片描述

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

具体命令角色(ConcreteCommand):继承自抽象命令,将一个接收者对象绑定于一个动作,调用接收者相应的操作,已完成命令。

调用者角色(Invoker):要求命令执行请求,通常会持有很多命令对象。是客户端真正触发命令并要求执行相应操作的对象,也就是和客户端打交道的。

接收者(Receiver):真正执行一个来自Invoker请求的类,任何类都可以作为一个接收者,只要能实现命令要求的相应功能。

命令模式实现代码:

    /// 接收者类,知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。
    public class Receiver
    {
        /// 真正的命令实现
        public void Action()
        {
            System.out.println("Execute request!");
        }
    }

    /// 抽象命令类,用来声明执行操作的接口
    public interface ICommand
    {
        void Execute();
    }

    /// 具体命令类,实现具体命令。
    public class ConcereteCommand extends ICommand
    {
        // 具体命令类包含有一个接收者,将这个接收者对象绑定于一个动作
        private Receiver receiver;

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

        /// 说这个实现是“虚”的,因为它是通过调用接收者相应的操作来实现Execute的
        public void Execute()
        {
            receiver.Action();
        }
    }

    /// 调度类,要求该命令执行这个请求
    public class Invoker
    {
        private ICommand command;

        /// 设置命令
        public void SetCommand(ICommand command)
        {
            this.command = command;
        }

        /// 执行命令
        public void ExecuteCommand()
        {
            command.Execute();
        }
    }

    // 客户端
            static void Main(string[] args)
        {
            Receiver receiver = new Receiver();
            ICommand command = new ConcereteCommand(receiver);
            Invoker invoker = new Invoker();

            invoker.SetCommand(command);
            invoker.ExecuteCommand();

        }

现在已去烧烤店吃烧烤为例,店里有服务员,我们把点菜告诉服务员,服务员记录后给烧烤制作者制作。

// 抽象命令类
abstract public class Command {

    protected Barbecuer receiver;
    public Command(Barbecuer receiver) {
        // TODO Auto-generated constructor stub
        this.receiver = receiver;
    }
    abstract public void excuteCommand();
}

// 烤鸡翅命令
public class backChickenWingCommand extends Command {

    public backChickenWingCommand(Barbecuer receiver) {
        // TODO Auto-generated constructor stub
        super(receiver);
    }
    // 执行命令
    @Override
    public void excuteCommand() {
        // TODO Auto-generated method stub
        receiver.bakeChickenWing();
    }
}

// 烤羊肉命令
public class bakeMuttonCommand extends Command {

    public bakeMuttonCommand(Barbecuer receiver) {
        // TODO Auto-generated constructor stub
        super(receiver);
    }
    // 执行命令
    @Override
    public void excuteCommand() {
        // TODO Auto-generated method stub
        receiver.bakeMutton();
    }
}

// 请求者
import java.util.ArrayList;

public class Waiter {

    ArrayList<Command> orders = new ArrayList<>();

    // 设置订单
    public void setOrder(Command c) {
        orders.add(c);
        System.out.println("增加订单:" + c.toString());
    }

    // 取消订单
    public void cancelOrder(Command c) {
        orders.remove(c);
        System.out.println("取消订单:" + c.toString());
    }
    // 通知全部执行
    public void notifyToExec() {
        for (Command command : orders) {
            command.excuteCommand();
        }
    }
}

// 客户端
public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Barbecuer barbecuer = new Barbecuer();
        Command command1 = new bakeMuttonCommand(barbecuer);
        Command command2 = new bakeMuttonCommand(barbecuer);
        Command command3 = new backChickenWingCommand(barbecuer); 
        Waiter hotGirl = new Waiter();

        hotGirl.setOrder(command1);
        hotGirl.setOrder(command2);
        hotGirl.setOrder(command3);
        hotGirl.notifyToExec();
    }
}

输出结果:
增加订单:bakeMuttonCommand@15db9742
增加订单:bakeMuttonCommand@6d06d69c
增加订单:backChickenWingCommand@7852e922
烤羊肉串!
烤羊肉串!
烤鸡翅了!

uml图:

这里写图片描述

分析:

命令模式优点:

1、可以加入新的命令类而不影响其他的类;

2、容易设计一个命令队列,保存要执行的所有命令;

3、可以较为容易的将命令计入日志;

4、允许请求接收的一方决定是否否决请求;

5、可以较为容易的对请求撤销或重做。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值