命令模式(Command Pattern)

命令模式(将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理)
  • 优点
    1、降低了系统耦合度。
    2、新的命令可以很容易添加到系统中去。

  • 缺点
    1、使用命令模式可能会导致某些系统有过多的具体命令类。

  • 命令模式包含以下主要角色
    抽象命令类角色:定义命令的接口,声明执行的方法。
    具体命令类角色:具体命令实现类,拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
    接收者角色:是真正执行命令的对象,执行命令功能的相关操作。
    请求者角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

  • 例子:人用遥控板进行电视频道换台为例

抽象命令类角色

/**
 * 换台命令接口
 */
public abstract class ChangeCommand {
    public TV tv;

    public ChangeCommand(TV tv) {
        this.tv = tv;
    }

    public abstract void changeChannel();
}

具体命令类角色

/**
 * 换到CCTV1频道命令
 */
public class ChangeCCTV1 extends ChangeCommand {
    public ChangeCCTV1(TV tv) {
        super(tv);
    }

    @Override
    public void changeChannel() {
        tv.changeCCTV1();
    }
}
/**
 * 换到CCTV2频道命令
 */
public class ChangeCCTV2 extends ChangeCommand {
    public ChangeCCTV2(TV tv) {
        super(tv);
    }

    @Override
    public void changeChannel() {
        tv.changeCCTV2();
    }
}
/**
 * 换到CCTV3频道命令
 */
public class ChangeCCTV3 extends ChangeCommand {
    public ChangeCCTV3(TV tv) {
        super(tv);
    }

    @Override
    public void changeChannel() {
        tv.changeCCTV3();
    }
}
/**
 * 换到CCTV4频道命令
 */
public class ChangeCCTV4 extends ChangeCommand {
    public ChangeCCTV4(TV tv) {
        super(tv);
    }

    @Override
    public void changeChannel() {
        tv.changeCCTV4();
    }
}

接收者角色

/**
 * 电视
 */
public class TV {
    public void changeCCTV1() {
        System.out.println("切换到CCTV1方法被调用...");
    }
    public void changeCCTV2() {
        System.out.println("切换到CCTV2方法被调用...");
    }
    public void changeCCTV3() {
        System.out.println("切换到CCTV3方法被调用...");
    }
    public void changeCCTV4() {
        System.out.println("切换到CCTV4方法被调用...");
    }
}

请求者角色

/**
 * 人
 */
public class People {
    private List<ChangeCommand> commandRecords = new ArrayList<>();
    // 换台
    public void change(ChangeCommand command) {
        System.out.println("调用者执行换台命令...");
        commandRecords.add(command);
        command.changeChannel();
    }

    // 返回
    public void back() {
        System.out.println("调用者执行返回命令...");
        // 当前历史小于2
        if (commandRecords.size()< 2) {
            return;
        } else {
            commandRecords.remove(commandRecords.size() - 1);
            ChangeCommand upCommand = commandRecords.get(commandRecords.size() - 1);
            upCommand.changeChannel();
        }
    }
}

测试

public class Test {
    public static void main(String[] args) {
        TV tv = new TV();
        ChangeCommand cctv1 = new ChangeCCTV1(tv);
        ChangeCommand cctv2 = new ChangeCCTV2(tv);
        ChangeCommand cctv3 = new ChangeCCTV3(tv);
        ChangeCommand cctv4 = new ChangeCCTV4(tv);
        People people = new People();
        people.change(cctv1);
        people.change(cctv3);
        people.change(cctv2);
        people.change(cctv4);
        people.back();
        people.back();
        people.back();
        people.back();
    }
}
// 运行结果
调用者执行换台命令...
切换到CCTV1方法被调用...
调用者执行换台命令...
切换到CCTV3方法被调用...
调用者执行换台命令...
切换到CCTV2方法被调用...
调用者执行换台命令...
切换到CCTV4方法被调用...
调用者执行返回命令...
切换到CCTV2方法被调用...
调用者执行返回命令...
切换到CCTV3方法被调用...
调用者执行返回命令...
切换到CCTV1方法被调用...
调用者执行返回命令...

命令模式就是将请求封装成一个个命令,以命令为参数来进行切换,达到请求参数化的目的,且还能通过集合这个数据结构来存储已经执行的请求,进行回退操作。如果需要添加新的电视频道,只需要添加新的命令类即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值