zoukankan      html  css  js  c++  java
  • Java设计模式--命令模式

    命令模式

    以网上很多人的例子:点餐。

    以前吃烧烤,每一个客人都是直接跟烧烤师傅说吃什么,烧烤师傅【又要烧烤又要记住每个客人点了什么】记性差。这里是行为请求者和行为实现者的紧耦合,不好。

    现在呢,每个烧烤摊有个服务员,客人想吃啥,直接跟服务员说,服务员把每一份订单给烧烤师傅看,烧烤师傅【只需要根据单子烧烤】效率提升。这里是行为请求者和行为实现者的解耦,好。

    大概过程如图:

    角色:

    客户角色(Client):创造了一个具体命令(ConcreteCommand)并确定其接收者。

    命令角色(Command):所有具体命令类的抽象接口。

    具体命令角色(ConcreteCommand):定义一个接收者(Receiver)和行为之间的弱耦合;实现execute方法,调用接收者(Receiver)的相关操作。

    请求者角色(Invoker):负责调用命令对象(Command)执行请求,相关的方法叫做行动方法。

    接收者角色(Receiver):具体实施和执行一个请求。

    UML图:

    示例:

    Command

    /**
     * 命令接口
     */
    
    public interface Command {
    
        void execute();
    }

    Receiver

    /**
     * 命令接收者
     */
    public class Receiver {
        public Receiver() {
        }
        public void action(){
            // 命令真正执行的逻辑
            System.out.println("~~~~~~~~~~~~~");
        }
    }

    ConcreteCommand

    /**
     * 命令接口实现类
     */
    public class ConcreteCommand implements Command {
        private Receiver receiver;
    
        public ConcreteCommand(Receiver receiver) {
            this.receiver = receiver;
        }
    
        public void execute() {
            receiver.action();
        }
    }

    Invoker

    /**
     * 命令调用者
     */
    public class Invoker {
    
        private Command command;
    
        public Invoker(Command command) {
            this.command = command;
        }
    
        public void action(){
            command.execute();
        }
    }

    Client

    /**
     *  命令 + 实现类
     *  命令调用者
     *  命令接收者
     *  客户端
     *
     *  客户端发出命令,由命令调用者负责传递,最终命令接收者执行。客户端不与命令细节直接接触。
     */
    public class Client {
        public static void main(String[] args){
            Receiver receiver = new Receiver();
            Command command = new ConcreteCommand(receiver);
            Invoker invoker = new Invoker(command);
            invoker.action();
        }
    }

    命令模式有什么好处

    实现了命令请求和命令实现的解耦合(中间加了个调用者),说白了,就是让命令实现专注自己职责内的事情,不需要管其他的。

    不好的地方就是Command实现类可能会有N个。

    实例

    来自《Java与模式》中茱莉亚玩收音机的例子。说茱莉亚(客户端)玩收音机,只需要手按相关的按键(命令调用者)即可,不需要关心收音机(命令实现者)播放或者停止的细节。

    代码:

    Command

    public interface Command {
    
        void execute();
    }

    AutoPlayer

    /**
     * 命令实现细节
     */
    public class AutoPlayer {
    
        public void play(){
            System.out.println("Play Music");
        }
    
        public void stop(){
            System.out.println("Stop Music");
        }
    }

    具体命令:Play

    /**
     * 播放命令
     */
    public class PlayCommand implements Command {
    
        private AutoPlayer autoPlayer;
    
        public PlayCommand(AutoPlayer autoPlayer) {
            this.autoPlayer = autoPlayer;
        }
    
        public void execute() {
            autoPlayer.play();
        }
    }

    具体命令:Stop

    /**
     * 停止命令
     */
    public class StopCommand implements Command {
    
        private AutoPlayer autoPlayer;
    
        public StopCommand(AutoPlayer autoPlayer) {
            this.autoPlayer = autoPlayer;
        }
    
        public void execute() {
            autoPlayer.stop();
        }
    }

    命令调用者:Keyboard

    /**
     * 命令调用者
     */
    public class KeyBoard {
    
        private Command playCommand;
        private Command stopCommand;
    
        public KeyBoard(Command playCommand, Command stopCommand) {
            this.playCommand = playCommand;
            this.stopCommand = stopCommand;
        }
    
        public void play(){
            playCommand.execute();
        }
    
        public void stop(){
            stopCommand.execute();
        }
    }

    客户端:Julia

    public class Julia {
    
        public static void main(String[] args){
            AutoPlayer player = new AutoPlayer();
            PlayCommand playCommand = new PlayCommand(player);
            StopCommand stopCommand = new StopCommand(player);
            KeyBoard keyBoard = new KeyBoard(playCommand, stopCommand);
            keyBoard.play();
            keyBoard.stop();
        }
    
    }

    回调函数

    代码

    Callback

    /**
     * 回调接口(命令接口)
     */
    public interface Callback {
    
        void callback();
    }

    商店

    /**
     * 命令调用者(商店店员)
     */
    public class SomeService {
    
        private Callback callback;
        private String phone;
    
        public void setCallback(Callback callback) {
            this.callback = callback;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public void service(){
            System.out.println("来货了,给客人【"+ phone +"】打电话......");
            callback.callback();
        }
    }

    客人

    public class Client {
    
        public static void main(String[] args){
    
            SomeService service = new SomeService();
            service.setPhone("12306");
            service.setCallback(() -> {
                // 这里的角色是具体的命令实现
                System.out.println("货到了,我来取!");
            });
            service.service();
        }
    }

    结果:

  • 相关阅读:
    css位置相关元素
    用smarty模板做的登录
    时间查询插件
    smarty 总结和分析
    手风琴特效
    Mysql 知识点总结
    Javascript实现图片的预加载的完整实现
    phpcms 列表页中调用其下的所有子栏目(或特定的子栏目)的方法
    phpcms v9表单实现问答咨询功能
    Cocos2d-x学习之 整体框架描述
  • 原文地址:https://www.cnblogs.com/LUA123/p/13559374.html
Copyright © 2011-2022 走看看