• 第二十五讲:命令模式



    package com.ibeifeng.ex1;
    
    public class MainClass {
        public static void main(String[] args) {
            Peddler peddler = new Peddler();
            peddler.sailApple();
            peddler.sailBanana();
        }
    }
    package com.ibeifeng.ex1;
    //小摊,小贩
    /*
     * 小商贩
     * 
     */
    public class Peddler {
       //卖苹果
       public void sailApple(){
           System.out.println("卖苹果");
       }
       //卖香蕉 
       public void sailBanana(){
           System.out.println("卖香蕉");
       }
    }

    Command:Command.

    Client:MainClass

    对于每一个行为都创建一个Command的实现子类:AppleCommand.

    //命令类必须包含调用方,是谁在卖,是Peddler在卖.所以命令类需要持有Peddler的引用.

    Invorker:执行Command对象.被调用者:Peddler,商贩被调用,所以需要持有一个Peddler的引用.


    实现了使用一个专门的类Command对这种调用过程加以封装.使用命令类除了可以对以前的调用加以封装还可以添加额外的功能.

    package com.ibeifeng.ex2;
    
    public class AppleCommand extends Command{
    
        public AppleCommand(Peddler peddler) {
            super(peddler);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void sail() {
            // TODO Auto-generated method stub
            //this.peddler.sailApple();
            this.getPeddler().sailApple();//不管你怎么搞,还是商贩在卖.
        }
    
    }
    package com.ibeifeng.ex2;
    
    public class BananaCommand extends Command{
    
        public BananaCommand(Peddler peddler) {
            super(peddler);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void sail() {
            // TODO Auto-generated method stub
            this.getPeddler().sailBanana();
        }
    
    }
    package com.ibeifeng.ex2;
    
    public abstract class Command {
        private Peddler peddler;
        //protected Peddler peddler;//子类如果要直接访问peddler可以改成保护类型.
        //不必隐藏细节隐藏的那么深.并不是每个属性都是private.你只是去考虑访问权限就行了.
        public Command(Peddler peddler) {//提供一个构造函数比较方便.
            //将构造函数放在最上面,这也是我们平常的一个习惯.
            super();
            this.peddler = peddler;
        }
        public abstract void sail();
        //命令类必须包含调用方,是谁在卖,是Peddler在卖.所以命令类需要持有Peddler的引用.
        
        public Peddler getPeddler() {
            return peddler;
        }
    
        public void setPeddler(Peddler peddler) {
            this.peddler = peddler;
        }
        
        
    }
    package com.ibeifeng.ex2;
    
    public class MainClass {
        public static void main(String[] args) {
            Peddler peddler = new Peddler();
            /*peddler.sailApple();
            peddler.sailBanana();*/
            Command appleCommand = new AppleCommand(peddler);
            Command bananaCommand = new BananaCommand(peddler);
            appleCommand.sail();
            bananaCommand.sail();//通过不同的命令来调用它的sail()方法
        }
    }
    package com.ibeifeng.ex2;
    //小摊,小贩
    /*
     * 小商贩
     * 
     */
    public class Peddler {
       //卖苹果
       public void sailApple(){
           System.out.println("卖苹果");
       }
       //卖香蕉 
       public void sailBanana(){
           System.out.println("卖香蕉");
       }
    }

    希望有一个类Receiver.小商贩赚了一些钱了,不想自己动手了,他可以请一个服务员:waiter.帮手.

    Receiver:Receiver(waiter)里面有action()方法,其实action()方法是执行Command的方法.Receiver接受一个命令.

    方案二是通过命令Command的实现类调用sail()方法.所以方案三现在是由waiter来执行一个命令.所以方案三是客户跟你请的服务员直接打交道,给他发出一个命令.


    package com.ibeifeng.ex3;
    
    public class AppleCommand extends Command{
    
        public AppleCommand(Peddler peddler) {
            super(peddler);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void sail() {
            // TODO Auto-generated method stub
            //this.peddler.sailApple();
            this.getPeddler().sailApple();//不管你怎么搞,还是商贩在卖.
        }
    
    }
    package com.ibeifeng.ex3;
    
    public class BananaCommand extends Command{
    
        public BananaCommand(Peddler peddler) {
            super(peddler);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void sail() {
            // TODO Auto-generated method stub
            this.getPeddler().sailBanana();
        }
    
    }
    package com.ibeifeng.ex3;
    
    public abstract class Command {
        private Peddler peddler;
        //protected Peddler peddler;//子类如果要直接访问peddler可以改成保护类型.
        //不必隐藏细节隐藏的那么深.并不是每个属性都是private.你只是去考虑访问权限就行了.
        public Command(Peddler peddler) {//提供一个构造函数比较方便.
            //将构造函数放在最上面,这也是我们平常的一个习惯.
            super();
            this.peddler = peddler;
        }
        public abstract void sail();
        //命令类必须包含调用方,是谁在卖,是Peddler在卖.所以命令类需要持有Peddler的引用.
        
        public Peddler getPeddler() {
            return peddler;
        }
    
        public void setPeddler(Peddler peddler) {
            this.peddler = peddler;
        }
        
        
    }
    package com.ibeifeng.ex3;
    //小摊,小贩
    /*
     * 小商贩
     * 
     */
    public class Peddler {
       //卖苹果
       public void sailApple(){
           System.out.println("卖苹果");
       }
       //卖香蕉 
       public void sailBanana(){
           System.out.println("卖香蕉");
       }
    }
    package com.ibeifeng.ex3;
    
    public class Waiter {
       private Command command;
    
    public Command getCommand() {
        return command;
    }
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public Waiter(Command command) {
        super();
        this.command = command;
    }
    
       public Waiter() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    public void sail(){//服务员也有一个sail(),服务员也是在卖东西,是你的帮手
           command.sail();
       }
    }
    package com.ibeifeng.ex3;
    
    public class MainClass {
        public static void main(String[] args) {
            Peddler peddler = new Peddler();//首先要有peddler,你要买的这个商贩/货家
            /*peddler.sailApple();
            peddler.sailBanana();*/
            Command appleCommand = new AppleCommand(peddler);//实例化Command的时候把被调用方peddler传进去
            //实际上操作的是商贩这个对象.
            Command bananaCommand = new BananaCommand(peddler);
            //appleCommand.sail();
            //bananaCommand.sail();//通过不同的命令来调用它的sail()方法
            Waiter waiter = new Waiter();//命令是由invoker(waiter)发出来的,是由它来执行这个命令.
            waiter.setCommand(appleCommand);
            waiter.sail();
            waiter.setCommand(bananaCommand);
            waiter.sail();
        }
    }

    Client是直接和Receiver(waiter).waiter持有了command的引用.前面讲错了,

    invoker:waiter,调用者,它持有了command的引用.

    Receiver:被调用者,Peddler.

    调用ConcreteCommand(AppleCommand、BananaCommand)的execute()方法其实是调用了Receiver(Peddler)的Action()方法.Receiver是一个目标对象.


    Command:Command.调用一个行为,被调用方是谁呢?被调用方就是Receiver(Peddler).调用ConcreteCommand的execute()方法其实是执行了Receiver(Peddler)的action()方法.Command持有的是Receiver的引用.Invoker是waiter.它持有了Command的引用.

    命令是发到invoker,也就是这个waiter.是由waiter来执行这个命令.

    建类的顺序也是Peddler->Command->Waiter,客户端MainClass调用的顺序也是这样的一层一层.和现实生活的例子逻辑相反,客户直接和waiter交互,要买什么商家(Receiver(Peddler))的商品,发送不同的命令(比如说AppleCommand这个命令),waiter接受并执行客户的命令(比如说AppleCommand这个命令(封装了目标对象Receiver(Peddler)的行为:卖苹果),调用了AppleCommand的sail()方法,AppleCommand的sail()方法其实是调用了peddler的sailApple()方法.如果是BananaCommand这个命令,waiter就调用BananaCommand的sail()方法,调用BananaCommand的sail()方法其实是调用peddler的sailBanana()方法.

    Pedder和Command可以创建在一起,但是setCommand()的时候必须把Command的实现类添加进去.


    最终版的命令模式:invoker(waiter)其实是包含很多命令类,命令类是作用于Receiver(peddler)的action方法.


    package com.ibeifeng.ex4;
    
    public class AppleCommand extends Command{
    
        public AppleCommand(Peddler peddler) {
            super(peddler);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void sail() {
            // TODO Auto-generated method stub
            //this.peddler.sailApple();
            this.getPeddler().sailApple();//不管你怎么搞,还是商贩在卖.
        }
    
    }
    package com.ibeifeng.ex4;
    
    public class BananaCommand extends Command{
    
        public BananaCommand(Peddler peddler) {
            super(peddler);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void sail() {
            // TODO Auto-generated method stub
            this.getPeddler().sailBanana();
        }
    
    }
    package com.ibeifeng.ex4;
    
    public abstract class Command {
        private Peddler peddler;
        //protected Peddler peddler;//子类如果要直接访问peddler可以改成保护类型.
        //不必隐藏细节隐藏的那么深.并不是每个属性都是private.你只是去考虑访问权限就行了.
        public Command(Peddler peddler) {//提供一个构造函数比较方便.
            //将构造函数放在最上面,这也是我们平常的一个习惯.
            super();
            this.peddler = peddler;
        }
        public abstract void sail();
        //命令类必须包含调用方,是谁在卖,是Peddler在卖.所以命令类需要持有Peddler的引用.
        
        public Peddler getPeddler() {
            return peddler;
        }
    
        public void setPeddler(Peddler peddler) {
            this.peddler = peddler;
        }
        
        
    }
    package com.ibeifeng.ex4;
    
    public class MainClass {
        public static void main(String[] args) {
            Peddler peddler = new Peddler();//首先要有peddler,你要买的这个商贩/货家
            /*peddler.sailApple();
            peddler.sailBanana();*/
            Command appleCommand = new AppleCommand(peddler);//实例化Command的时候把被调用方peddler传进去
            //实际上操作的是商贩这个对象.
            Command bananaCommand = new BananaCommand(peddler);
            //appleCommand.sail();
            //bananaCommand.sail();//通过不同的命令来调用它的sail()方法
            Waiter waiter = new Waiter();//命令是由invoker(waiter)发出来的,是由它来执行这个命令.
            //waiter.setCommand(appleCommand);
            //下订单
            waiter.setOrder(appleCommand);
            //waiter.sail();
            //waiter.setCommand(bananaCommand);
            waiter.setOrder(bananaCommand);
            
            //移除订单某项
            waiter.removeOrder(bananaCommand);
            waiter.sail();
        }
    }
    package com.ibeifeng.ex4;
    //小摊,小贩
    /*
     * 小商贩
     * 
     */
    public class Peddler {
       //卖苹果
       public void sailApple(){
           System.out.println("卖苹果");
       }
       //卖香蕉 
       public void sailBanana(){
           System.out.println("卖香蕉");
       }
    }
    package com.ibeifeng.ex4;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class Waiter {
       //private Command command;
        private List<Command> commands = new ArrayList<Command>();//订单,菜单,菜谱
    
    /*public Command getCommand() {
        return command;
    }*/
    public void sail(){
        for (Command command :  commands){
            command.sail();
        }
    }
    //public void setCommand(Command command) {
    public void setOrder(Command command) {
        //this.command = command;
        commands.add(command);
    }
    public void removeOrder(Command command){
        commands.remove(command);
    }
    /*public Waiter(Command command) {
        super();
        this.command = command;
    }*/
    
    /*   public Waiter() {
        super();
        // TODO Auto-generated constructor stub
    }*/
    
    /*public void sail(){//服务员也有一个sail(),服务员也是在卖东西,是你的帮手
           command.sail();
       }*/
    }
  • 相关阅读:
    四则运算3
    结对编程
    2016年秋季-软件需求分析-UML图
    2016年秋季-学习进度条
    2016年秋季-学习进度条
    2016年秋季-《UML大战需求分析》-阅读笔记1
    2016年秋季-课堂练习1-Liz开发问题账户分析系统
    2016年秋季-《UML大战需求分析》-个人阅读计划
    2016年秋季-软件需求与分析-基本知识
    用户体验
  • 原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6755531.html
Copyright © 2020-2023  润新知