Android中的设计模式之命令模式

作者: WangGavin | 来源:发表于2018-08-20 23:54 被阅读11次

    参考

    • 《设计模式:可复用面向对象软件的基础 》5.2 Command 命令 对象行为型模式
    • 《Android源码设计模式解析与实战》第11章 让程序畅通执行--命令模式

    意图

    将一个请求封装为一个对象,从而使你可用不同地请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销地操作。

    适用场景

    • 需要抽象出待执行地动作,然后以参数地形式提供出来,类似于过程设计中的回调机制,命令模式正是回调机制的一个面向对象的替代品
    • 在不同的时刻指定、排列和执行请求。一个命令对象可以有与初始请求无关的生存期。
    • 需要支持取消操作。
    • 支持修改日志功能,这样当系统崩溃时,这些修改可以被重做一遍。
    • 需要支持事物操作。

    结构

    命令模式通用结构
    • Reicever 接收者角色,负责具体执行一个请求,任何一个类都可以成为一个接收者,而在接收者类中封装具体操作逻辑的方法我们称为行动方法(action)
    • Command 命令角色 定义所有具体命令类的抽象接口
    • ConcreteCommand 具体命令角色,实现了Command接口,在excute方法中调用接收者角色的相关方法,在接收者和命令执行的具体行为之间加以弱耦合。execute方法成为执行方法(excute)
    • Invoker 请求者角色,负责调用命令对象执行具体的请求,相关的方法我们成为行动方法(action)
    • Client 客户端角色

    执行流程

    执行流程

    代码就略了

    优点

    更弱的耦合性,更灵活的控制性以及更好的扩展性

    缺点

    类膨胀,大量衍生类的创建。

    例子1 操纵俄罗斯方块变换

    描述

    大家小时候都玩过俄罗斯方块,游戏中有4个按钮,分别是两个左右移动的按钮,一个快速落下的按钮,一个变化方块形状的按钮。所以四个按钮就相当于请求者,执行具体按钮命令的逻辑方法块可以看作命令角色。

    结构

    结构

    代码实现

    /**
     *  命令的接收者,负责具体执行请求
     * @author newtrekWang
     * @email  wangjiaxing20160101@gmail.com
     * @time   2018/8/20  23:35
     */
    public class TetrisMachine {
    
        public void toLeft(){
            System.out.println("向左");
        }
    
        public void toRigth(){
            System.out.println("向右");
        }
    
        public void fastToBottom(){
            System.out.println("快速向下");
        }
    
        public void transform(){
            System.out.println("变换形状");
        }
    }
    
    /**
     *  命令抽象
     * @author newtrekWang
     * @email  wangjiaxing20160101@gmail.com
     * @time   2018/8/20  23:37
     */
    public interface Command {
        /**
         * 执行命令
         */
        void execute();
    }
    
    
    /**
     *  向左命令
     * @author newtrekWang
     * @email  wangjiaxing20160101@gmail.com
     * @time   2018/8/20  23:39
     */
    public class LeftCommand implements Command {
        private TetrisMachine tetrisMachine;
    
        public LeftCommand(TetrisMachine tetrisMachine) {
            this.tetrisMachine = tetrisMachine;
        }
    
        @Override
        public void execute() {
            tetrisMachine.toLeft();
        }
    }
    
    /**
     *  向右命令
     * @author newtrekWang
     * @email  wangjiaxing20160101@gmail.com
     * @time   2018/8/20  23:39
     */
    public class RightCommand implements Command {
        private TetrisMachine tetrisMachine;
    
        public RightCommand(TetrisMachine tetrisMachine) {
            this.tetrisMachine = tetrisMachine;
        }
    
        @Override
        public void execute() {
            tetrisMachine.toRigth();
        }
    }
    
    /**
     *  快速向下命令
     * @author newtrekWang
     * @email  wangjiaxing20160101@gmail.com
     * @time   2018/8/20  23:39
     */
    public class FallCommand implements Command {
        private TetrisMachine tetrisMachine;
    
        public FallCommand(TetrisMachine tetrisMachine) {
            this.tetrisMachine = tetrisMachine;
        }
    
        @Override
        public void execute() {
            tetrisMachine.fastToBottom();
        }
    }
    
    /**
     *  变换形状命令
     * @author newtrekWang
     * @email  wangjiaxing20160101@gmail.com
     * @time   2018/8/20  23:39
     */
    public class TransformCommand implements Command {
        private TetrisMachine tetrisMachine;
    
        public TransformCommand(TetrisMachine tetrisMachine) {
            this.tetrisMachine = tetrisMachine;
        }
    
        @Override
        public void execute() {
            tetrisMachine.transform();
        }
    }
    
     public static void main(String[] args){
            TetrisMachine tetrisMachine = new TetrisMachine();
    
            LeftCommand leftCommand = new LeftCommand(tetrisMachine);
            RightCommand rightCommand = new RightCommand(tetrisMachine);
            FallCommand fallCommand = new FallCommand(tetrisMachine);
            TransformCommand transformCommand = new TransformCommand(tetrisMachine);
    
            leftCommand.execute();
            leftCommand.execute();
            fallCommand.execute();
            transformCommand.execute();
            rightCommand.execute();
    
        }
        
    

    执行结果:

    向左
    向左
    快速向下
    变换形状
    向右
    
    

    例子2 Android事件机制中底层逻辑对事件的转发处理

    Android的每一种事件在屏幕上产生后都会经由底层逻辑将其转换为一个NotifyArgs对象,NotifyAgs本身并无实现,其实它就相当于一个Command抽象。

    例子3 运用命令模式实现Android绘图板

    后更

    相关文章

      网友评论

        本文标题:Android中的设计模式之命令模式

        本文链接:https://www.haomeiwen.com/subject/dswriftx.html