设计模式原来这么简单-命令模式

命令模式

1.什么是命令模式

WIKI: 它把在稍后执行的一个动作或触发的一个事件所需要的所有信息封装到一个对象中。

2.实例

例如假如有一个万能遥控可以对任何东西发出任何命令

3.程序示例
public interface Command {

    /**
     * 执行命令
     * @param target 执行命令的目标
     */
    void doCommand(Target target);

    void redoCommand();

    void undoCommand();
}

/**
 * 目标
 */
public interface Target {
    /**
     * 获取目标的名字
     */
    String getTargetName();
}
/**
 * 电视类
 */
public abstract class TvTarget implements Target{
    /**
     * 电视开关状态
     */
    private boolean isTvOn;

    private String tvName;

    private int leastChannelNum = 0;

    private int channelNum = 1;

    public int getChannelNum() {
        return channelNum;
    }

    @Override
    public String getTargetName() {
        return tvName;
    }

    public boolean isOn() {
        return isTvOn;
    }

    protected void setTvOn(boolean tvOn) {
        isTvOn = tvOn;
    }

    protected void setTvName(String tvName) {
        this.tvName = tvName;
    }

    /**
     * 切换频道
     * 实际中不同品牌切换频道的逻辑并不相同
     */
    public void changeChannel(int channelNum){
        if(isOn()){
            leastChannelNum = this.channelNum;
            this.channelNum = channelNum;
            System.out.println(String.format("已切换到%d频道~", channelNum));
        }else {
            System.out.println("请先开启电视机~");
        }
    }

    public void reFreshChannel(){
        System.out.println(String.format("刷新%d频道成功~", channelNum));
    }

    /**
     * 返回上一个频道
     */
    public void returnLeastChannel(){
        if(isOn() && leastChannelNum != 0){
            System.out.print("返回上一个频道:");
            changeChannel(leastChannelNum);
        }else {
            System.out.println("请先开启电视机~");
        }
    }
}

public class AppleTv extends TvTarget{

    public AppleTv(){
        setTvName("苹果牌电视");
    }

    public void turnOn(){
        setTvOn(true);
        // ...
    }

    public void turnOff(){
        setTvOn(false);
        // ...
    }

}
public class ChangeChannelCommand implements Command{

    private int channelNum;

    private TvTarget tvTarget;

    public ChangeChannelCommand(int channelNum) {
        this.channelNum = channelNum;
    }

    @Override
    public void doCommand(Target target) {
        this.tvTarget = (TvTarget) target;
        tvTarget.changeChannel(channelNum);
    }

    @Override
    public void redoCommand() {
        tvTarget.reFreshChannel();
    }

    @Override
    public void undoCommand() {
        tvTarget.returnLeastChannel();
    }
}
/**
 * 万能遥控器
 * 可以控制电视、洗衣机、冰箱、空调...
 */
public class AmazingRemoteControl {

    // 待重新执行的命令
    private Deque<Command> redoCommandList = new LinkedList<>();
    // 待撤回的命令
    private Deque<Command> undoCommandList = new LinkedList<>();

    // 执行
    public void executeCommand(Command command, Target target){
        command.doCommand(target);
        redoCommandList.add(command);
        undoCommandList.add(command);
    }

    //撤回
    public void undoCommand(){
        if(!undoCommandList.isEmpty()){
            undoCommandList.pollLast().undoCommand();
        }
    }

    // 再次执行
    public void redoCommand(){
        if(!redoCommandList.isEmpty()){
            redoCommandList.pollLast().redoCommand();
        }
    }
}
@Test
public void test(){
    AmazingRemoteControl control = new AmazingRemoteControl();
    Command command = new ChangeChannelCommand(10);
    Command command2 = new ChangeChannelCommand(20);
    Command command3 = new ChangeChannelCommand(30);
    AppleTv tvTarget = new AppleTv();
   	// 关于电视的开关命令没写,可仿照ChangeChannelCommand写
    tvTarget.turnOn();

    control.executeCommand(command, tvTarget);

    control.executeCommand(command2, tvTarget);

    control.redoCommand();

    control.undoCommand();

    control.executeCommand(command3, tvTarget);

    control.redoCommand();

    control.undoCommand();
}

已切换到10频道~
已切换到20频道~
刷新20频道成功~
返回上一个频道:已切换到10频道~
已切换到30频道~
刷新30频道成功~
返回上一个频道:已切换到10频道~

4.总结

命令模式将命令和执行命令的实例解耦,使系统的扩展更加灵活,并借助列表实现了命令的再次执行和撤回。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值