美文网首页Java设计模式
设计模式之命令模式

设计模式之命令模式

作者: 于无声处写写写 | 来源:发表于2018-05-16 08:37 被阅读10次

    类图结构

    image.png
    • Receiver接受者角色:该角色就是干活的角色,命令传递到这里是应该被执行的
    • Command命令角色:需要执行的所有命令都在这里声明
    • Invoker调用者角色:接收到命令,并执行命令
    //通用Receiver类
    public abstract class Receiver {
        public abstract void doSomething();
    }
    
    //具体Receiver类
    public class ConcreteReciver1 extends Receiver{ 
        //每个接收者都必须处理一定的业务逻辑 
        public void doSomething(){ } 
    } 
    public class ConcreteReciver2 extends Receiver{ 
        //每个接收者都必须处理一定的业务逻辑 
        public void doSomething(){ } 
    }
    
    //抽象Command类
    public abstract class Command {
        public abstract void execute();
    }
    
    //具体的Command类
    public class ConcreteCommand1 extends Command { 
        //对哪个Receiver类进行命令处理 
        private Receiver receiver; 
        //构造函数传递接收者 
        public ConcreteCommand1(Receiver _receiver){
            this.receiver = _receiver; 
        } 
    
        //必须实现一个命令 
        public void execute() { 
        //业务处理 
            this.receiver.doSomething(); 
        } 
    } 
    
    public class ConcreteCommand2 extends Command { 
        //哪个Receiver类进行命令处理 
        private Receiver receiver; 
        //构造函数传递接收者 
        public ConcreteCommand2(Receiver _receiver){
            this.receiver = _receiver; 
        } 
        //必须实现一个命令 
        public void execute() { 
            //业务处理 
            this.receiver.doSomething();
        } 
    }
    
    //调用者Invoker类
    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 invoker = new Invoker();
            Receiver receiver = new ConcreteReceiver1();
            
            Command command = new ConcreteCommand1(receiver);
            invoker.setCommand(command);
            invoker.action();
        }
    }
    

    实例2

    |现在比较火的小米手机,可以当作遥控器控制多种不同的家电,手机发送命令,不同的电器接收到后执行。


    image.png
    • Command类
    public interface Command {
        public void execute();
        public void undo();
    }
    
    • 开灯命令
    public class LightOnCommand implements Command {
        private Light light;
    
        LightOnCommand(Light light) {
            this.light = light;
        }
    
        public void execute() {
            light.on();
        }
    
        public void undo() {
            light.off();
        }
    }
    
    • 开电视命令
    public class TVOnCommand implements Command {
        private TV tv;
    
        public TVOnCommand(TV tv) {
            this.tv = tv;
        }
    
        public void execute() {
            tv.on();
        }
    
        public void undo() {
            tv.off();
        }
    }
    
    • 家用电器接口类
    public interface HouseholdAppliances {
        public void on();
        public void off();
    }
    
    • 电视类
    public class TV implements HouseholdAppliances {
        public void on() {
            System.out.println("the TV on");
        }
    
        public void off() {
            System.out.println("the TV off");
        }
    }
    
    • 电灯类
    public class Light implements HouseholdAppliances{
        public void on() {
            System.out.println("the light on");
        }
    
        public void off() {
            System.out.println("the light off");
        }
    }
    
    • 手机控制器类
    public class MiPhone {
        ArrayList commands;
    
        public MiPhone() {
            commands = new ArrayList();
        }
    
        public void setCommand(Command command) {
            commands.add(command);
        }
    
        public void onButtonWasPushed(int slot) {
            ((Command)commands.get(slot-1)).execute();
        }
    
        public static void main(String[] args) {
            MiPhone miPhone = new MiPhone();
            //创建电器
            Light light = new Light();
            TV tv = new TV();
            //创建命令
            LightOnCommand lightOnCommand = new LightOnCommand(light);
            TVOnCommand tvOnCommand = new TVOnCommand(tv);
            //给小米手机设置命令
            //设置第一个按钮为开灯
            miPhone.setCommand(lightOnCommand);
            //设置第二个按钮为开电视
            miPhone.setCommand(tvOnCommand);
    
            //开灯
            miPhone.onButtonWasPushed(1);
            //开电视
            miPhone.onButtonWasPushed(2);
        }
    }
    
    • 运行结果


      image.png

    应用

    优点

    • 类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
    • 可扩展性:Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严 重的代码耦合。
    • 命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题

    缺点

    • 命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来 了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项 目中慎重考虑使用。

    相关文章

      网友评论

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

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