Java 设计模式-命令模式

109 阅读2分钟
  1. 需求分析: 现在某公司有一个项目需要开发, 项目划分为三个不同的小组, 分别为: 需求组, 美工组, 代码组. 客户和这三个小组进行沟通.

    /**
     * 抽象组
     */
    public abstract class Group {
        // 找到组
        public abstract void find();
        // 增加功能
        public abstract void add();
        // 删除功能
        public abstract void delete();
        // 给出变更计划
        public abstract void plan();
    }
    
    /**
     * 需求组
     */
    public class RequirementGroup extends Group {
        public void fin() {
            System.out.println("找到需求组");
        }
        
        public void add() {
            System.out.println("客户要求增加一项需求");
        }
        
        public void change() {
            System.out.println("客户要求修改一项功能");
        }
        
        public void delete() {
            System.out.println("客户要求删除一项需求");
        }
        
        public void plan() {
            System.out.println("客户要求需求变更计划");
        }
    }
    
    public class PageGroup extends Group {
        public void fin() {
            System.out.println("找到美工组");
        }
        
        public void add() {
            System.out.println("客户要求增加一个页面");
        }
        
        public void change() {
            System.out.println("客户要求修改一个页面");
        }
        
        public void delete() {
            System.out.println("客户要求删除一项页面");
        }
        
        public void plan() {
            System.out.println("客户要求页面变更计划");
        }
    }
    
    public class CodeGroup extends Group {
        public void fin() {
            System.out.println("找到代码组");
        }
        
        public void add() {
            System.out.println("客户要求增加一项功能");
        }
        
        public void change() {
            System.out.println("客户要求修改一项功能");
        }
        
        public void delete() {
            System.out.println("客户要求删除一项功能");
        }
        
        public void plan() {
            System.out.println("客户要求代码变更计划");
        }
    }
    
    public class Client {
        public static void main(String[] args) {
            Group requirementGroup = new RequirementGroup();
            requirementGroup.find();
            requirementGroup.add();
            requirementGroup.plan();
        }
    }
    

    客户每次都需要和具体的项目沟通, 并且布置一堆的命令. 并且某个命令可能需要多个小组来完成. 所以需要为客户提供一个接头人. 客户有什么命令直接布置给接头人, 由接头人来协调各个小组.

    public abstract class Command {
        // 这些称为命令的执行者
        protected Group requirementGroup = new RequirementGroup();
        protected Group pageGroup = new PageGroup();
        protected Group codeGroup = new CodeGroup();
        
        public abstract void execute();
    }
    
    /**
     * 增加需求的命令
     */
    public class AddRequirementCommand extends Command {
        public void execute() {
            super.requirementGroup.find();
            super.requirementGroup.add();
            super.requirementGroup.plan();
        }
    }
    
    /**
     * 删除一个页面的命令
     */
    public class DeletePageCommand extends Command {
        public void execute() {
            super.pageGroup.find();
            super.pageGroup.delete();
            super.pageGroup.plan();
        }
    }
    
    /**
     * 负责人
     */
    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 xiaoli = new Invoker();
            // 客户下达增加需求的命令
            Command addRequirementCommand = new AddRequirementCommand();
            xiaoli.setCommand(addRequirementCommand);
            xiaoli.action();
            
            // 客户下达删除页面的命令
            Command deletePageCommand = new DeletePageCommand();
            xiaoli.setCommand(deletePageCommand);
            xiaoli.action();
        }
    }
    

    这样客户完全不知道公司内部的具体小组划分情况, 客户也不需要知道, 公司内部对客户来说应该是透明的. 客户只需要找到公司的接头人就可以了.

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

    command
    在上面代码中各个小组对应的是命令的接收者, 接头人对应的是命令的调用者.

  3. 命令模式的应用:
    java.lang.Runnable 的实现
    javax.swing.Action 的实现

  4. 参考:
    [1] : Java 库中的设计模式
    [2] : 设计模式之禅
    [3] : Head First 设计模式