美文网首页
行为模式之命令模式

行为模式之命令模式

作者: 后来丶_a24d | 来源:发表于2019-09-18 20:30 被阅读0次

总纲

  • 设计原则:遵循迪米特、开闭原则
  • 常用场景:行为的请求者与行为的处理者耦合度过高
  • 使用概率:20%
  • 复杂度:中高
  • 变化点:命令的种类
  • 选择关键点:请求者是否不需要关心命令的执行只知道接受者
  • 逆鳞:命令的种类无限制增长
  • 相关设计模式
    1. 职责链模式:容易将二者关联在一起的原因是,二者都是为了处理请求或者命令而存在的,而且二者都是为了将请求者与响应者解耦,不同的是命令模式中,客户端需要知道一个命令的接受者,在创建命令的时候就把接受者与命令绑定在一起发送给调用者,而职责链模式中,客户端并不关心最终处理请求的对象是谁,客户端只是封装一个请求对象,随后交给职责链的头部而已,也正因为这样,二者的实现方式,有着很大的区别

命令模式

  • 命令模式, 例子举的蛮好。
    在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。例子中有类保持takeOrder,takeOrder中可以记录command, 也可以有方法撤销命令。最终执行是placeOrders。解耦

uml类图

命令模式.png

对应代码

 public interface Task {

        void handle();

    }

    public class Demand implements Task{

        private Programmer programmer;

        public Demand(Programmer programmer) {
            super();
            this.programmer = programmer;
        }

        public void handle() {
            programmer.handleDemand();
        }

        public String toString() {
            return "Demand [programmer=" + programmer.getName() + "]";
        }

    }

    public class Bug implements Task{

        private Programmer programmer;

        public Bug(Programmer programmer) {
            super();
            this.programmer = programmer;
        }

        public void handle() {
            programmer.handleBug();
        }

        public String toString() {
            return "Bug [programmer=" + programmer.getName() + "]";
        }

    }

    public class Problem implements Task{

        private Programmer programmer;

        public Problem(Programmer programmer) {
            super();
            this.programmer = programmer;
        }

        public void handle() {
            programmer.handleProblem();
        }

        public String toString() {
            return "Problem [programmer=" + programmer.getName() + "]";
        }

    }

    public class ProductManager {

        private static final int TASK_NUMBER_IN_DAY = 4;//一天最多分派掉四个任务,多了推到第二天

        private List<Task> taskList;

        private List<Programmer> programmerList;//产品经理应该认识所有的程序猿

        private int currentIndex;

        public ProductManager(Programmer... programmers) {
            super();
            if (programmers == null || programmers.length == 0) {
                throw new RuntimeException("产品经理手下没有程序员,任务分配不出去,无法正常工作!");
            }
            taskList = new ArrayList<Task>();
            programmerList = Arrays.asList(programmers);
        }

        //接受一个任务
        public void receive(Task task){
            taskList.add(task);
        }

        public void assign(){
            Task[] copy = new Task[taskList.size() > TASK_NUMBER_IN_DAY ? taskList.size() - TASK_NUMBER_IN_DAY : 0];
            for (int i = 0; i < TASK_NUMBER_IN_DAY && i < taskList.size(); i++) {
                taskList.get(i).handle();
            }
            System.arraycopy(taskList.toArray(), TASK_NUMBER_IN_DAY > taskList.size() ? taskList.size() : TASK_NUMBER_IN_DAY, copy, 0, copy.length);
            taskList = Arrays.asList(copy);
        }
        //产品经理可以选择程序猿,简单的循环选取。
        public Programmer chooseProgrammer(){
            return programmerList.get(currentIndex == programmerList.size() ? 0 : currentIndex++);
        }

        public void printTaskList(){
            if (taskList == null || taskList.size() == 0) {
                System.out.println("----------当前无任务--------");
                return;
            }
            System.out.println("---------当前剩下的任务列表--------");
            for (Task task : taskList) {
                System.out.println(task);
            }
            System.out.println("----------------------------------");
        }
    }

    public class Salesman {

        private String name;

        private ProductManager productManager;

        public Salesman(String name) {
            super();
            this.name = name;
        }

        public Salesman(String name, ProductManager productManager) {
            super();
            this.name = name;
            this.productManager = productManager;
        }

        public void putDemand(){
            System.out.println( "业务员" + name + "提出新需求");
            productManager.receive(new Demand(productManager.chooseProgrammer()));
        }

        public void putBug(){
            System.out.println( "业务员" + name + "提出bug");
            productManager.receive(new Bug(productManager.chooseProgrammer()));
        }

        public void putProblem(){
            System.out.println( "业务员" + name + "提出线上问题");
            productManager.receive(new Problem(productManager.chooseProgrammer()));
        }

        public String getName() {
            return name;
        }

        public ProductManager getProductManager() {
            return productManager;
        }

        public void setProductManager(ProductManager productManager) {
            this.productManager = productManager;
        }
    }


    public class Work {

        public static void main(String[] args) {
            Programmer xiaozuo = new Programmer("小左");
            ProductManager productManager = new ProductManager(xiaozuo);

            Salesman salesmanA = new Salesman("A",productManager);
            Salesman salesmanB = new Salesman("B",productManager);
            Salesman salesmanC = new Salesman("C",productManager);
            Salesman salesmanD = new Salesman("D",productManager);

            salesmanA.putDemand();
            salesmanB.putDemand();
            salesmanB.putBug();
            salesmanC.putDemand();
            salesmanC.putProblem();
            salesmanD.putDemand();

            System.out.println("第一天产品经理分配任务");
            productManager.assign();
            productManager.printTaskList();
            System.out.println("第二天产品经理分配任务");
            productManager.assign();
            productManager.printTaskList();
        }

    }
  • 优点
  1. 最大的优点,就是将行为请求者和行为实现者解耦。
  2. 命令的添加特别方便,并且可以方便的制定各种命令和利用现有命令组合出新的命令。

相关文章

网友评论

      本文标题:行为模式之命令模式

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