精华内容
下载资源
问答
  • 命令模式
    千次阅读
    2022-04-07 23:07:59

    游戏中,玩家的输入方式有很多种,例如键盘、鼠标等。玩家输入操作,游戏需要调用相应的逻辑,最简单的处理方式是:

    if (Input.GetKeyDown("Q"))

            Jump();

    else if (Input.GetKeyDown("T"))

            Idle();

    else if (Input.GetKeyDown("A"))

            Attack();

    else if (Input.GetKeyDown("Z"))

            Skill();

    对应每一个按钮的输入,直接调用相应的操作函数。

    但这样的处理有一个问题:不支持玩家改键,假如玩家想要用按键Q来调用Skill,而不是Jump,那么上面的代码就有些麻烦。

    命令模式可以解决这个问题。

    命令模式的定义:

    将一个请求封装成一个对象,从而允许你使用不同的请求、队列或日志将客户端参数化,同时支持请求操作的撤销与恢复。

    将操作函数进行封装,我们可以改造上面的代码:

    定义命令基类

    class Command

    {

    public:

    virtual void Run() = 0;

    }

    定义攻击命令

    class AttackCommand:public Command

    {

    public:

    virtual void Run(){Attack();}

    }

    定义跳跃命令

    class JumpCommand:public Command

    {

    public:

    virtual void Run(){Jump();}

    }

    ……(依次定义剩余的命令)

    这样,我们使用对象,将直接的行为函数调用,封装在其内部。然后我们定义一个管理类,来管理整个游戏中的所有按键

    定义操作管理类

    class InputHandler

    {

    public:

    //默认按键

    void Init()

    {

    input_map["Q"] = new JumpCommand();

    input_map["T"] = new IdleCommand();

    input_map["A"] = new AttackCommand();

    input_map["Z"] = new SkillCommand();

    }

    //用户自定义按键

    void ChangeButton(std::string button_name,int type)

    {

    //根据type,将按键映射到对应的命令

    //注意内存释放

    }

    //处理玩家输入

    void HandleInput(std::string input)

    {

    input_map[input]->Run();

    }

    private:

    std::unorder_map<std::string,Command*> input_map;

    }

    命令模式,不单只是解决了按键的映射问题,还有别的好处:

    可以将行为的对象解耦,调用对应的函数,这样,同样一份攻击代码,既可以用于玩家角色,也可以用于NPC,敌人等。

    player->attack();

    enemy->attack();

    npc->attack();

     实例是可以存储的,因此,我们可以按照时间戳的方式,将命令依次存放起来,用于撤销和回放。(只需要记录命令的参数,实现对应的run函数和cancelrun函数)

    定义命令基类

    class Command

    {

    public:

    virtual void Run(Parameter && p) = 0;

    virtual void CancelRun() = 0;

    private:

    Parameter parameter;

    CancelParameter parameter;

    }

    更多相关内容
  • 设计模式---命令模式

    千次阅读 2021-12-30 17:25:06
    命令模式 命令模式的定义 ​ 命令模式是一个高内聚的模式,其定义为:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support ...

    命令模式

    命令模式的定义

    ​ 命令模式是一个高内聚的模式,其定义为:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)

    ​ 补充:什么是高内聚?

    ​ 高内聚低耦合,是软件工程中的概念,是判断软件设计好坏的标准,主要用于程序的面向对象的设计,主要看类的内聚性是否高,耦合度是否低。目的是使程序模块的可重用性、移植性大大增强。通常程序结构中各模块的内聚程度越高,模块间的耦合程度就越低。

    通用类图

    在这里插入图片描述

    在该类图中,我们看到三个角色:

    ● Receive接收者角色

    该角色就是干活的角色,命令传递到这里是应该被执行的,具体到我们上面的例子中就是Group的三个实现类。

    ● Command命令角色

    需要执行的所有命令都在这里声明。

    ● Invoker调用者角色

    接收到命令,并执行命令。在例子中,(项目经理)就是这个角色。

    命令模式比较简单,但是在项目中非常频繁地使用,因为它的封装性非常好,把请求方(Invoker)和执行方(Receiver)分开了,扩展性也有很好的保障,通用代码比较简单

    代码结构

    通用Receiver类

    public abstract class Receiver {
         //抽象接收者,定义每个接收者都必须完成的业务
         public abstract void doSomething();
    }
    

    为什么Receiver是一个抽象类?那是因为接收者可以有多个,有多个就需要定义一个所有特性的抽象集合——抽象的接收者

    具体的Receiver类

    public class ConcreteReciver1 extends Receiver{    
         //每个接收者都必须处理一定的业务逻辑
         public void doSomething(){
         }
    }
    public class ConcreteReciver2 extends Receiver{ 
         //每个接收者都必须处理一定的业务逻辑
         public void doSomething(){
         }
    }
    

    接收者可以是N个,这要依赖业务的具体定义。命令角色是命令模式的核心

    抽象的Command类

    public abstract class Command {
       //每个命令类都必须有一个执行命令的方法
       public abstract void execute();
    }
    

    根据环境的需求,具体的命令类也可以有N个。

    具体的Command类

    public class ConcreteCommand1 extends Command {
       //对哪个Receiver类进行命令处理
       private Receiver receiver; 
       //构造函数传递接收者
       public ConcreteCommand1(Receiver _receiver){
           this.receiver = _receiver;
       }
       //必须实现一个命令
       public void execute() {
           //业务处理
           this.receiver.doSomething();
       }
    }
    public class ConcreteCommand2 extends Command {
       //哪个Receiver类进行命令处理
       private Receiver receiver;
       //构造函数传递接收者
       public ConcreteCommand2(Receiver _receiver){
           this.receiver = _receiver;
       }
       //必须实现一个命令
       public void execute() {
           //业务处理
           this.receiver.doSomething();
       }
    }
    

    定义了两个具体的命令类,我们可以在实际应用中扩展该命令类。在每个命令类中,通过构造函数定义了该命令是针对哪一个接收者发出的,定义一个命令接收的主体。调用者非常简单,仅实现命令的传递。

    调用者Invoker类

    public class Invoker {
       private Command command;
       //受气包,接受命令
       public void setCommand(Command _command){
           this.command = _command;
       } 
       //执行命令
       public void action(){
           this.command.execute();
       }
    }
    

    调用者就像是一个受气包,不管什么命令,都要接收、执行!那我们来看高层模块如何调用命令模式.

    public class Client {
       public static void main(String[] args) {
           //首先声明调用者Invoker
           Invoker invoker = new Invoker();
           //定义接收者
           Receiver receiver = new ConcreteReciver1();
           //定义一个发送给接收者的命令
           Command command = new ConcreteCommand1(receiver);
           //把命令交给调用者去执行
           invoker.setCommand(command);
           invoker.action();
       }
    }
    

    案例

    ​ 小女孩茱丽(Julia)有一个盒式录音机,此录音机有播音(Play)、倒带(Rewind)和停止(Stop)功能,录音机的键盘便是请求者(Invoker)角色;茱丽(Julia)是客户端角色,而录音机便是接收者角色。Command类扮演抽象命令角色,而PlayCommand、StopCommand和RewindCommand便是具体命令类。茱丽(Julia)不需要知道播音(play)、倒带(rewind)和停止(stop)功能是怎么具体执行的,这些命令执行的细节全都由键盘(Keypad)具体实施。茱丽(Julia)只需要在键盘上按下相应的键便可以了。

    录音机是典型的命令模式。录音机按键把客户端与录音机的操作细节分割开来。
      在这里插入图片描述

    接收者角色,由录音机类扮演

    public class AudioPlayer {
        
        public void play(){
            System.out.println("播放...");
        }
        
        public void rewind(){
            System.out.println("倒带...");
        }
        
        public void stop(){
            System.out.println("停止...");
        }
    }
    

    抽象命令角色类

    public interface Command {
        /**
         * 执行方法
         */
        public void execute();
    }
    

    具体命令角色类

    public class PlayCommand implements Command {
    
        private AudioPlayer myAudio;
        
        public PlayCommand(AudioPlayer audioPlayer){
            myAudio = audioPlayer;
        }
        /**
         * 执行方法
         */
        @Override
        public void execute() {
            myAudio.play();
        }
    
    }
    
    public class RewindCommand implements Command {
    
        private AudioPlayer myAudio;
        
        public RewindCommand(AudioPlayer audioPlayer){
            myAudio = audioPlayer;
        }
        @Override
        public void execute() {
            myAudio.rewind();
        }
    
    }
    
    public class StopCommand implements Command {
        private AudioPlayer myAudio;
        
        public StopCommand(AudioPlayer audioPlayer){
            myAudio = audioPlayer;
        }
        @Override
        public void execute() {
            myAudio.stop();
        }
    
    }
    

    调用者角色,由键盘类扮演

    public class Keypad {
        private Command playCommand;
        private Command rewindCommand;
        private Command stopCommand;
        
        public void setPlayCommand(Command playCommand) {
            this.playCommand = playCommand;
        }
        public void setRewindCommand(Command rewindCommand) {
            this.rewindCommand = rewindCommand;
        }
        public void setStopCommand(Command stopCommand) {
            this.stopCommand = stopCommand;
        }
        /**
         * 执行播放方法
         */
        public void play(){
            playCommand.execute();
        }
        /**
         * 执行倒带方法
         */
        public void rewind(){
            rewindCommand.execute();
        }
        /**
         * 执行播放方法
         */
        public void stop(){
            stopCommand.execute();
        }
    }
    

    客户端角色,由茱丽小女孩扮演

    public class Julia {
        public static void main(String[]args){
            //创建接收者对象
            AudioPlayer audioPlayer = new AudioPlayer();
            //创建命令对象
            Command playCommand = new PlayCommand(audioPlayer);
            Command rewindCommand = new RewindCommand(audioPlayer);
            Command stopCommand = new StopCommand(audioPlayer);
            //创建请求者对象
            Keypad keypad = new Keypad();
            keypad.setPlayCommand(playCommand);
            keypad.setRewindCommand(rewindCommand);
            keypad.setStopCommand(stopCommand);
            //测试
            keypad.play();
            keypad.rewind();
            keypad.stop();
            keypad.play();
            keypad.stop();
        }
    }
    

    宏命令

    ​ 所谓宏命令简单点说就是包含多个命令的命令,是一个命令的组合。

    设想茱丽的录音机有一个记录功能,可以把一个一个的命令记录下来,再在任何需要的时候重新把这些记录下来的命令一次性执行,这就是所谓的宏命令集功能。因此,茱丽的录音机系统现在有四个键,分别为播音、倒带、停止和宏命令功能。此时系统的设计与前面的设计相比有所增强,主要体现在Julia类现在有了一个新方法,用以操作宏命令键。

    在这里插入图片描述

    系统需要一个代表宏命令的接口,以定义出具体宏命令所需要的接口。

    public interface MacroCommand extends Command {
        /**
         * 宏命令聚集的管理方法
         * 可以添加一个成员命令
         */
        public void add(Command cmd);
        /**
         * 宏命令聚集的管理方法
         * 可以删除一个成员命令
         */
        public void remove(Command cmd);
    }
    

    具体的宏命令MacroAudioCommand类负责把个别的命令合成宏命令。

    public class MacroAudioCommand implements MacroCommand {
        
        private List<Command> commandList = new ArrayList<Command>();
        /**
         * 宏命令聚集管理方法
         */
        @Override
        public void add(Command cmd) {
            commandList.add(cmd);
        }
        /**
         * 宏命令聚集管理方法
         */
        @Override
        public void remove(Command cmd) {
            commandList.remove(cmd);
        }
        /**
         * 执行方法
         */
        @Override
        public void execute() {
            for(Command cmd : commandList){
                cmd.execute();
            }
        }
    
    }	
    

    客户端类JuliaSister

    public class Julia {
        
        public static void main(String[]args){
            //创建接收者对象
            AudioPlayer audioPlayer = new AudioPlayer();
            //创建命令对象
            Command playCommand = new PlayCommand(audioPlayer);
            Command rewindCommand = new RewindCommand(audioPlayer);
            Command stopCommand = new StopCommand(audioPlayer);
            
            MacroCommand marco = new MacroAudioCommand();
            
            marco.add(playCommand);
            marco.add(rewindCommand);
            marco.add(stopCommand);
            marco.execute();
        }
    }
    

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

    撤销测试

    public class Julia {
        
        public static void main(String[]args){
            //创建接收者对象
            AudioPlayer audioPlayer = new AudioPlayer();
            //创建命令对象
            Command playCommand = new PlayCommand(audioPlayer);
            Command rewindCommand = new RewindCommand(audioPlayer);
            Command stopCommand = new StopCommand(audioPlayer);
            
            MacroCommand marco = new MacroAudioCommand();
            
            marco.add(playCommand);
          	//撤销命令
            marco.remove(playCommand);
            marco.add(rewindCommand);
            marco.add(stopCommand);
            marco.execute();
        }
    }
    

    运行结果:

    在这里插入图片描述

    命令模式的应用

    命令模式的优点

    ● 类间解耦

    调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。

    ● 可扩展性

    Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。

    命令模式的缺点

    命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项目中慎重考虑使用。

    命令模式的使用场景

    只要你认为是命令的地方就可以采用命令模式,例如,在GUI开发中,一个按钮的点击是一个命令,可以采用命令模式;模拟DOS命令的时候,当然也要采用命令模式;触发-反馈机制的处理等。

    命令模式在 Spring 框架 JdbcTemplate 应用的源码分析

    Spring 框架的 JdbcTemplate 就使用到了命令模式

    在这里插入图片描述

    模式角色分析说明

    StatementCallback 接口 ,类似命令接口(Command)

    class QueryStatementCallback implements StatementCallback, SqlProvider , 匿名内部类, 实现了命令接口, 同时也充当命令接收者

    命令调用者 是 JdbcTemplate , 其中 execute(StatementCallback action) 方法中,调用 action.doInStatement 方法. 不同的 实现 StatementCallback 接口的对象,对应不同的 doInStatemnt 实现逻辑

    另外实现 StatementCallback 命令接口的子类还有 ExecuteStatementCallback、StreamStatementCallback、BatchUpdateStatementCallback等。

    展开全文
  • 命令模式

    万次阅读 2018-10-22 09:47:29
    一、命令模式定义 命令大家都不会陌生,那么在开始命令模式之前,可以想象一下生活中的命令模式的特点: 如老板命令你完成一个OA项目是一个命令,接着看看其特点: 1、在上面的命令中,命令的执行者肯定是聪明的...

    一、命令模式定义

    命令大家都不会陌生,那么在开始命令模式之前,可以想象一下生活中的命令模式的特点:

    如老板命令你完成一个OA项目是一个命令,接着看看其特点:

    1、在上面的命令中,命令的执行者肯定是聪明的你了。具体的执行方法,可能是通过vs实现,或者是通过eclipse实现,由此看来:命令要有个命令的执行者,还要有个命令的执行方法。

    2、命令的发出者很明显是老板,老板还有个发出方法,可能是通过电话给你说,也可能给你邮件给你说,也可能是通过开会给你说。所以命令的发出者要有一个命令,还要有个发出的方法。

    3、最后看看命令,命令有个名字,命令的肯定要执行。而且命令是在boss给你发出通知后执行的。

    接下来看看命令模式的定义:

    命令模式:将请求封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。

    每次讲一个模式时,从定义都不能体会其中的技巧,所以接着我会通过举例子来说明命令模式。

    二、命令模式的举例

    下面来看看多用遥控器是如何使用命令模式的。

    2.1需求

    假设某个公司需要设计一个多用功能的遥控器。基本的需求如下:

    该遥控器有可以控制风扇,白炽灯,热水器等等的多对开关,而且可能还有其他的电器,暂时不做其功能,但是希望可以保留接口,用的时间可以方便的扩展。

    除上面的需求之外,还需要有个按钮,可以撤销上一步的操作。基本功能如下图:

    image

    2.2问题

    在设计遥控器时,风扇,白炽灯,热水器的开关方法已经定义好,其名字各不相同。不妨设置其方法为如下:

    image

    由于各种电器的开关方法都不一样,而且还存在一个待扩展的电器,如果没有学习命名模式之前,我们在设置扩展的开关时,会出现的问题是什么呢?假设现在有电视,冰箱还可能会用到遥控器,那么我们会在最后一个开关上写if else,当然如果哪一天有多了一个大门也加入了我们的遥控的行列,这样我们继续加if else ,很显然随着电器的高速发展,会有多个需要遥控可以控制的。

    举个例子,如果我们是需要遥控的客户,现在有一款遥控如果有遥控可以进行扩展,一种是可以扩展指定类型的,像上面的,只能再去扩展电视和冰箱中的一种,偶尔有一天你看到隔壁邻居的门,也可以使用遥控了,所以你去把你的高级遥控器,拿到扩展店时,扩展工程师说了,现在只能扩展电视和冰箱,不支持对大门的遥控扩展.

    我们肯定是希望,可以自由的扩展,大门可以使用遥控了,就对大门扩展,车门使用遥控了,就对车门扩展……其实也就是一种松耦合的实现。

    2.3分析问题

    为了实现松耦合,我们现在来想一下,周末去请朋友吃饭,服务员mm问你吃什么,你说水煮活鱼,然后在菜单上面,写上水煮活鱼。下个星期天想吃花生米啤酒,同样也写在订单上,然后服务员mm把订单拿给厨师。

    在上面的例子中,无论你点了什么菜,服务员mm,只需要知道顾客点的什么菜,从而给不同的厨师做(虽然不是直接的,但最终凉菜会给凉菜的师傅做,热菜的会给热菜的厨师做),然而具体的怎么做是厨师的事情,服务员知道顾客点上面菜,只是为了能正确的交个厨师去做。

    其实在这个例子中,也是一个命令模式的例子,不同的订单对应的有不同的厨师,最终订单拿到厨师面前,就是对厨师下了个命令,要做菜了。每订单或者说是每种菜都对应着自己的厨师,所以,客服需要有订单的的引用,订单为了知道调用哪个厨师,需要有厨师引用;两个引用都是使用的组合。从而可以调用多种自己需要对象的方法来实现松耦合。这里记住:客服mm知道顾客点菜的目的是为了让不同的厨师去做。再直接一些就是为了使用不同的命令。

    上面的吃饭问题和我们的遥控器问题差不多,都是包含下命令,命令的执行者,以及命令的具体内容。如果还是有些不清楚的话,就用简单的程序模拟一下上面的过程:

     View Code

    上面的例子中,厨师的做法有可能不同,就像我们遥控器的开关一样,电器的开关方法不一定相同。如果要执行,只需要把这个方法包在命令的激发方法中,然后去调用具体的方法就可以了。

    尽管上面的例子有些牵强,但是还是模拟了命令的过程,为我们遥控器的设计提供了思路。

    2.4解决问题

    回到我们的遥控器问题上面来,我们可以先定义好我们的风扇,白炽灯,热水器。然后定义其分别的开关命令,每个命令都有自己对应的电器引用,而且会在命令的Excute中包装电器的开或者关,最后需要把命令安装到遥控器上面,在遥控器上每个按钮都对应有自己的激发方法,其代码如下:

     View Code

    这样基本上就实现了我们的现有的三种电器的遥控。需要注意的是,在开始初始化遥控器时,对每个命令初始化成了NoCommand,也就是什么都不执行。在命令的初始化经常使用,同时这也解决了我们的在扩展前什么都不做的难题。看了风扇,白炽灯,热水器的遥控实现,进一步的扩展任何的电器,相信都不是什么难事。但是还有个功能没有实现,就是撤销到上一步的操作,接下来我们就来实现撤销操作。

    2.5问题的补充说明

    撤销操作就想我们遥控中的返回一样。基本上就是灯亮着,突然按了一下关灯,然后再按一下返回键,灯就亮了。其他的电器同样的道理。下面先看一下灯的撤销原理,命令除了执行外还有一个撤销,所以我们需要先都命令的接口添加一个方法。

    /// <summary> 
    /// 命令接口 
    /// </summary> 
    public interface ICommand 

        void Excute(); 
        void Undo(); 
    }

    对于开灯需要做的修改如下:

    public class LightOnCommand : ICommand 
       { 
           Light light; 
           public LightOnCommand(Light light) 
           { 
               this.light = light; 
           } 
           public void Excute() 
           { 
               light.LightOn(); 
           } 
           /// <summary> 
           /// 调用命令的反命令 
           /// </summary> 
           public void Undo() 
           { 
               light.LightOff(); 
           } 
       }

    其他命令同理,代码会在源码中一并给出。也就是每个命令都有自己的反命令,在Undo方法里面也就是调用反命令的Excute方法。每当按下一个按钮时,就去记录其命令的名称,如果按撤销的话,就执行命名的Undo方法。下面给出主要代码:

    public void OnButtonWasPressed(int slot) 
       { 
           onCommands[slot].Excute(); 
           backCommand=onCommands[slot]; 
       } 
       public void OffButtonWasPressed(int slot) 
       { 
           offCommands[slot].Excute(); 
           backCommand = offCommands[slot]; 
       } 
       public void BackButtonWasPressed() 
       { 
           backCommand.Undo(); 
       }

    以上是对遥控器对命令的撤销,需要注意两点1、通过记住命令执行之前的状态,然后去恢复到原来的状态。2、在每次执行之后要记住执行的那个命令。也即记住命令和记住状态。

    除了一次执行一个命令和撤销一个命令,当然还可以一次执行多个命令。下面给出主要代码:

    public class MutlipleCommand : ICommand 
       { 
           ICommand[] commands; 
           ICommand[] backCommands; 
           public MutlipleCommand(ICommand[] commands) 
           { 
               this.commands = commands; 
               backCommands = new ICommand[commands.Length]; 
           }


           public void Excute() 
           { 
               for (int i = 0; i < commands.Length; i++) 
                { 
                  commands[i].Excute(); 
                  backCommands[i] = commands[i]; 
                } 
               
           }

           public void Undo() 
           { 
               for (int i = 0; i < commands.Length; i++) 
               { 
                   backCommands[i].Undo(); 
               } 
           } 
       }

    三、命令模式类图

    image

    四、总结

    命令模式主要通过中介Command实现了发出命令者和命令的执行者,也即Invoke类和Receiver的松耦合。本文先给出了命令模式的定义,通过吃饭的例子给出了使用命令模式实现遥控器设计思路,最后还提到了撤销命令和一个命令实现多个命令的做法。

    展开全文
  • 什么是命令模式

    千次阅读 2022-03-01 22:32:36
    一、命令模式的定义 命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方,命令模式属于行为型模式 二、命令模式的uml图和通用写法 uml 通用...

    一、命令模式的定义

    命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方,命令模式属于行为型模式

    二、命令模式的uml图和通用写法

    uml

    在这里插入图片描述

    通用写法
    
    /**
     * 功能:命令的抽象
     */
    public interface ICommand {
    
        void execute();
    
    }
    
    /**
     * 功能:具体的命令
     */
    public class ConcreteCommand implements ICommand{
    
        Receiver receiver = new Receiver();
    
        @Override
        public void execute() {
            receiver.action();
        }
    }
    
    /**
     * 功能:命令接收者
     */
    public class Receiver {
    
        public void action() {
            System.out.println("具体执行");
        }
    }
    
    /**
     * 功能:命令请求者
     */
    public class Invoker {
    
        private ICommand iCommand;
    
        public Invoker(ICommand iCommand) {
            this.iCommand = iCommand;
        }
    
        public void action() {
            iCommand.execute();
        }
    }
    
    
    public class Tests {
    
        public static void main(String[] args) {
            ICommand command = new ConcreteCommand();
            Invoker invoker = new Invoker(command);
            invoker.action();
        }
    }
    
    

    命令模式中的4个角色:

    1. 接收者角色(Receiver):负责具体执行一个请求
    2. 命令角色(ICommand):定义需要执行的所有命令行为
    3. 具体的命令角色(ConcreteCommand):内部维护一个Receiver
    4. 请求者角色(Invoker):接收客户端的命令,并执行命令

    三、遥控操作电视的例子

    uml

    在这里插入图片描述

    /**
     * 功能:操作命令
     */
    public interface Command {
    
        void execute();
    }
    
    /**
     * 功能:打开电视机
     */
    public class OpenCommand implements Command{
        private TV tv = new TV();
    
        @Override
        public void execute() {
            tv.open();
        }
    }
    
    /**
     * 功能:换台
     */
    public class ChangeCommand implements Command{
        private TV tv = new TV();
    
        @Override
        public void execute() {
            tv.change();
        }
    }
    
    /**
     * 功能:关闭电视机
     */
    public class CloseCommand implements Command{
        private TV tv = new TV();
        @Override
        public void execute() {
            tv.close();
        }
    }
    
    package com.kangping.command.lizi;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 功能:遥控器
     */
    public class Control {
    
        public List<Command> commands = new ArrayList<>();
    
        public Control(Command command) {
            commands.add(command);
        }
    
        public Control(List<Command> commands) {
            this.commands.addAll(commands);
        }
    
        public void action() {
            commands.forEach(e -> e.execute());
        }
    }
    
    /**
     * 功能:电视机
     */
    public class TV {
        public void open() {
            System.out.println("打开电视机");
        }
        public void change() {
            System.out.println("切换电视机");
        }
        public void close() {
            System.out.println("关闭电视机");
        }
    }
    
    /**
     * 功能:
     */
    public class Tests {
    
        public static void main(String[] args) {
            Command command = new OpenCommand();
            Command changeCommand = new ChangeCommand();
            Command closeCommand = new CloseCommand();
            List list = new ArrayList<>();
            list.add(command);
            list.add(changeCommand);
            list.add(closeCommand);
            Control control = new Control(list);
            control.action();
        }
    }
    
    

    四、java 源码中的使用

    命令模式在jdk中的使用

    public interface Runnable {
       
        public abstract void run();
    }
    

    Runnable相当于命令的抽象。实际上调用线程的start以后,就有资格去抢cpu的资源,不要去写获取cpu资源的逻辑,抢到cpu资源以后执行run方法中的内容。Runnable接口把用户请求和cpu执行进行解耦。

    五、优点和缺点

    优点

    1. 通过引入命令的抽象接口,实现了命令请求与实现的解耦
    2. 扩展性良好,可以很容易的增加新命令

    缺点
    1.命令类可能过多

    展开全文
  • 设计模式之命令模式

    万次阅读 多人点赞 2018-01-11 10:03:25
    说实话这个模式挺令人纠结的,但从...命令模式的定义:将请求封装成一个对象,从而让用户使用不同的请求把客户端参数化,以及支持可撤销和恢复的功能。 从定义上来看着实令人一脸懵逼,在这里描述一下博主个人的理解:
  • 游戏开发设计模式:命令模式

    千次阅读 2022-03-09 19:18:11
    二、命令模式 2.1 命令模式的总结与介绍 将一个请求封装成一个对象,从而允许使用不同的请求、队列或日志将客户端参数化,同时支持请求操作的撤销与恢复。 命令就是一个对象化(实例化)的方调用、面向对象化的回调...
  • 目录 1、三种命令模式 2、Vim编辑器的简单使用 3、Vim编辑器的常用命令 ...运行Vim时默认进入命令模式,先切换到输入模式进行文档编写,再返回到命令模式,进入末行模式保存或退出。 2、Vim编辑器的简单使用
  • Linux中vim怎么进入命令模式的方法

    千次阅读 2021-05-09 01:49:55
    Linux中vim怎么进入命令模式的方法一按ESC键退出插入模式进入命令模式(正常模式)。Linux中vim怎么进入命令模式的方法二按CTRL+C键快速退出插入模式进入命令模式(正常模式)。Linux中vim怎么进入命令模式的...
  • Command命令模式

    千次阅读 2021-09-20 11:36:10
    简单来说,就像我们的复制、删除、插入等等都是命令,我们将命令封装为一个对象,并且支持撤销,将一系列命令串成一条链或者与链表结合使用,可以实现一系列的do和undo 模式类图: command: 抽象的命令类 X_Command...
  • 游戏设计模式 - 命令模式在Unity中的应用(C#) 实测:这是一篇简单易懂的文章-> https://zhuanlan.zhihu.com/p/46937284
  • 命令模式:在该模式下是不能对文件直接编辑,可以输入快捷键进行一些操作(删除行,复制行,移动光标、粘贴等)打开文件之后默认进入命令模式 编辑模式:可以对文件的内容进行编辑 末行模式:可以在末行输入命令来...
  • 设计模式(16)命令模式

    万次阅读 2019-05-02 12:30:44
    **定义:**将一个请求...​ 顾名思义,命令模式就是对命令的封装,首先来看一下命令模式类图中的基本结构: **Command类:**是一个抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来...
  • 设计模式在一些大型的软件系统中非常常用,用来处理复杂的结构和逻辑。游戏其实也是一个软件系统,也会有庞大的系统,复杂的逻辑关系,...本文介绍的命令模式可能与GoF上的稍有不同,是我自己对游戏开发中设计模式应用
  • jupyter notebook命令模式和编辑模式

    千次阅读 2020-10-08 20:52:49
    编辑模式(edit mode) ... 进入编辑模式后,cell中有光标,cell左侧变为绿色,右上角有铅笔符号。 命令模式(command mode) ...进入命令模式 后,cell中没有光标,cell左侧变为蓝色,右上角没有铅笔符号。 ...
  • Java设计模式之行为型:命令模式

    万次阅读 2018-11-04 10:16:56
    命令模式的本质是将请求封装成对象,将发出命令与执行命令的责任分开,命令的发送者和接收者完全解耦,发送者只需知道如何发送命令,不需要关心命令是如何实现的,甚至是否执行成功都不需要理会。命令模式的关键在于...
  • 文章目录一、命令模式定义二、命令模式的结构和说明三、命令模式示例 一、命令模式定义 将一个请求封装成一个对象,从而使你可用不同的请求把客户端参数化,对请求排队或者记录请求日志,以及支持可撤销和恢复操作...
  • 思科模拟器三种命令模式

    千次阅读 2020-01-12 21:36:03
    一:前言 IOS(InternetWork Operating System互联网操作系统)...为了安全,IOS提供了三种命令行模式,分别是User Mode(用户模式),Privileged Mode(特权模式),GlobalMode(全局模式),不同模式下,用户具有不同的配...
  • 命令模式&中介者模式

    千次阅读 多人点赞 2021-07-20 08:28:13
    公公 相当于命令模式的接受者(Receiver),执行皇帝的命令,收取早朝奏折(ConcreteCommand) 还是颁布圣旨(ConcreteCommand) 皇帝 相当于命令模式的调用者(Invoker) 老规矩,例子说完,看看代码吧 // 定义 命令类 ...
  • VIM命令模式与输入模式切换

    千次阅读 2018-07-10 11:43:26
    vi有两种工作模式:命令模式和文本输入模式。启动vi需要输入vi,按[Spacebar]键并输入文件名后回车。切换模式键vi从命令模式切换到文本输入模式。每个键以不同方式使vi进入文本输入模式。按[ESC]键使vi从文本输入...
  • 命令模式(Command模式)详解

    千次阅读 2020-03-18 09:46:39
    ”变得很重要,命令模式能很好地解决这个问题。 在现实生活中,这样的例子也很多,例如,电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者),还有计算机键盘上的“功能键...
  • 交换机基本命令模式

    千次阅读 2019-05-16 13:04:53
    交换机基本命令模式 对于思科交换机来说,主要有2种配置途径:其一,使用交换机自带的Console线缆连接到计算机的COM口,然后利用计算机的超级终端软件直接配置,首次配置通常使用这种方式;其二,通过telnet方式...
  • JavaScript 设计模式之命令模式

    万次阅读 2019-12-01 21:08:12
    什么是命令模式? 假设有一个快餐店,而我是该餐厅的点餐服务员,那么我一天的工作应该是这样的:当某位客人点餐或者打来订餐电话后,我会把他的需求都写在清单上,然后交给厨房,客人不用关心是哪些厨师帮他炒菜。...
  • C++ 命令模式

    千次阅读 2017-03-14 22:17:41
    命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传递给调用对象。调用对象寻找可以处理该命令的合适对象,并把该命令传给相应的对象,该对象执行命令。
  • Activiti核心架构之职责链与命令模式

    千次阅读 2017-06-26 07:33:54
    Activiti核心的骨架是:命令模式+职责链 本文的代码版本:activiti 5.22一、职责链1、什么是职责链模式http://blog.csdn.net/jiankunking/article/details/504432942、Activiti中职责链初始化     流程初始化...
  • 通过前面的学习我们知道,Linux 系统中所有的内容...使用 Vim 编辑文件时,存在 3 种工作模式,分别是命令模式、输入模式和编辑模式,这 3 种工作模式可随意切换,如图 1 所示。 图 1 Vim 的三种工作模式 Vim的命...
  • Android设计模式之——命令模式

    千次阅读 2017-10-29 20:56:30
    一、介绍命令模式(Command Pattern),是行为型设计模式之一。命令模式相对于其他的设计模式来说并没有那么多的条条框框,其实它不是一个很”规范“的模式,不过,就是基于这一点,命令模式相对于其他的设计模式...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,673,578
精华内容 669,431
关键字:

命令模式