Java设计模式——命令模式

定义
将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。

组成角色
1、Command
定义命令的接口,声明执行的方法。
2、ConcreteCommand
命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
3、Receiver
接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
4、Invoker
要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
5、Client
创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

优缺点
优点:
1、 类间解耦
调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
2、 可扩展性
Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。

缺点:
如果有N个命令,Command的子类就是N个,这个类膨胀的非常大,需要在项目中慎重考虑使用。

代码示例
定义命令的接口,声明执行的方法。

/**
 * 执行命令的接口
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public interface Command {
    void exeute();
}

命令接口实现对象

/**
 * 开机命令
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public class CommandOn implements Command {

    private Tv myTv;
    
    public CommandOn(Tv tv){
        myTv = tv;
    }
    
    @Override
    public void exeute() {
        myTv.turnOn();
    }
    
}

/**
 * 关机命令
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public class CommandOff implements Command{

    private Tv myTv;
    public CommandOff(Tv tv){
        myTv = tv;
    }
    @Override
    public void exeute() {
        myTv.turnOff();
        
    }
    
}

/**
 * 切换频道
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public class CommandChange implements Command{
    
    private Tv myTv;
    
    private int channel;
    
    public CommandChange(Tv tv,int channel){
        myTv = tv;
        this.channel = channel;
    }

    @Override
    public void exeute() {
        myTv.changeChannel(channel);
        
    }
}

接收者,真正执行命令的对象。

/**
 * 命令接收者Receiver
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public class Tv {
    public int currentChannel = 0;
    
    public void turnOn(){
        System.out.println("on:开的状态");
    }
    
    public void turnOff(){
        System.out.println("off:关的状态");
    }
    
    public void changeChannel(int channel){
        this.currentChannel = channel;
        System.out.println("切换频道");
    }
}
/**
 * 遥控器
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public class Control {
    private Command onCommand,offCommand,changeCommand;
    
    public Control(Command on,Command off,Command channel){
        onCommand = on;
        offCommand = off;
        changeCommand = channel;
    }
    
    public void turnOn(){
        onCommand.exeute();
    }
    
    public void turnOff(){
        offCommand.exeute();
    }
    
    public void changeChannel(){
        changeCommand.exeute();
    }
}

/**
 * 测试客户端
 * @author lu
 * @since  1.0, 2020年7月4日
 */
public class Client {
    public static void main(String[] args) {
      //命令 接收者
        Tv myTv = new Tv();
        //开机命令
        CommandOn on  = new CommandOn(myTv);
        //关机命令
        CommandOff off  = new CommandOff(myTv);
        //频道切换命令
        CommandChange channel = new CommandChange(myTv,2);
        //命令控制对象
        Control control = new Control(on,off,channel);
        
        //开机
        control.turnOn();
        //切换频道
        control.changeChannel();
        //关机
        control.turnOff();
    }
}

执行结果
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值