设计模式--命令模式

Posted lm970585581

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--命令模式相关的知识,希望对你有一定的参考价值。

家电自动化遥控器API项目

传统设计方案

package com.java.jikexueyuan.commandmode.device;
//电灯
public class Light {
    //电灯的位置
    String loc = "";

    public Light(String loc) {
        this.loc = loc;
    }

    //开灯
    public void On() {

        System.out.println(loc + " On");
    }

    //关灯
    public void Off() {

        System.out.println(loc + " Off");
    }

}
package com.java.jikexueyuan.commandmode.device;
//音响
public class Stereo {
    static int volume = 0;
    //
    public void On() {
        System.out.println("Stereo On");
    }
    //
    public void Off() {
        System.out.println("Stereo Off");
    }
    //选歌曲
    public void SetCd() {
        System.out.println("Stereo SetCd");
    }
    //设置音量
    public void SetVol(int vol) {
        volume = vol;
        System.out.println("Stereo volume=" + volume);
    }
    //查看音量
    public int GetVol() {
        return volume;
    }
    //开始播放
    public void Start() {
        System.out.println("Stereo Start");
    }
}
package com.java.jikexueyuan.commandmode;
//遥控器
public interface Control {
    //开机按钮
    public void onButton(int slot);
    //关机按钮
    public void offButton(int slot);
    
    public void undoButton();
}
package com.java.jikexueyuan.commandmode;

import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
//遥控器实现类
public class TraditionControl implements Control {
    Light light;
    Stereo stereo;

    public TraditionControl(Light light, Stereo stereo) {
        this.light = light;
        this.stereo = stereo;
    }

    @Override
    public void onButton(int slot) {
        // TODO Auto-generated method stub
        switch (slot) {
        case 0:
            light.On();
            break;
        case 1:
            stereo.On();
            break;
        case 2:
            int vol = stereo.GetVol();
            if (vol < 11) {
                stereo.SetVol(++vol);
            }
            break;
        }
    }

    @Override
    public void offButton(int slot) {
        // TODO Auto-generated method stub
        switch (slot) {
        case 0:
            light.Off();
            break;
        case 1:
            stereo.Off();
            break;
        case 2:
            int vol = stereo.GetVol();
            if (vol > 0) {
                stereo.SetVol(--vol);
            }
            break;
        }
    }

    @Override
    public void undoButton() {
        // TODO Auto-generated method stub
        
    }

    

}
package com.java.jikexueyuan.commandmode;

import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
//使用遥控器
public class ControlTest {
    public static void main(String[] args) {
        Control ctl;
        Light light = new Light("Bedroom");
        Stereo stereo = new Stereo();
        ctl = new TraditionControl(light, stereo);

        ctl.onButton(0);
        ctl.offButton(0);
        ctl.onButton(1);
        ctl.onButton(2);
        ctl.offButton(2);

        ctl.offButton(1);
    }
}

命令模式:将请求、命令、动作等封装成对象,这样可以让项目使用这些对象来参数化其他对象。使得命令的请求者和执行者解耦

重新设计如下

package com.java.jikexueyuan.commandmode.command;
//所有命令的接口
public interface Command {
    public void execute();
    public void undo();
}
package com.java.jikexueyuan.commandmode.command;

import com.java.jikexueyuan.commandmode.device.Light;
//开灯
public class LightOnCommand implements Command {
    private Light light;
    
    public LightOnCommand(Light light)
    {
        this.light=light;
        
    }
    @Override
    public void execute() {
        // TODO Auto-generated method stub
        light.On();
    }

    @Override
    public void undo() {
        // TODO Auto-generated method stub
        light.Off();
    }

}
package com.java.jikexueyuan.commandmode.command;

import com.java.jikexueyuan.commandmode.device.Light;
//关灯
public class LightOffCommand implements Command {
    private Light light;
    public LightOffCommand(Light light)
    {
        this.light=light;
    }
    @Override
    public void execute() {
        // TODO Auto-generated method stub
        light.Off();
    }

    @Override
    public void undo() {
        // TODO Auto-generated method stub
        light.On();
    }

}
package com.java.jikexueyuan.commandmode.command;

import com.java.jikexueyuan.commandmode.device.Stereo;
//打开音响,并选择歌曲
public class StereoOnCommand implements Command {
    private Stereo setreo;
    public StereoOnCommand(Stereo setreo)
    {
        this.setreo=setreo;
    }
    
    @Override
    public void execute() {
        // TODO Auto-generated method stub
        setreo.On();
        setreo.SetCd();
        
    }

    @Override
    public void undo() {
        // TODO Auto-generated method stub
        setreo.Off();
    }

}
package com.java.jikexueyuan.commandmode.command;
//空指令
public class NoCommand implements Command {

    @Override
    public void execute() {
        // TODO Auto-generated method stub

    }

    @Override
    public void undo() {
        // TODO Auto-generated method stub

    }

}
package com.java.jikexueyuan.commandmode.command;

import java.util.Stack;

import com.java.jikexueyuan.commandmode.Control;
import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
//遥控器实现类
public class CommandModeControl implements Control{
    private Command[] onCommands;
    private Command[] offCommands;
    //使用栈 设置回退
    private Stack<Command> stack=new Stack<Command>();
    public CommandModeControl()
    {
        //假设左右各5个按钮
        onCommands=new Command[5];
         offCommands=new Command[5];
        
         Command noCommand=new NoCommand();
         
         for(int i=0,len=onCommands.length;i<len;i++)
         {
             
             //初始化按钮为未设置命令
             onCommands[i]=noCommand;
             offCommands[i]=noCommand;
         }
         
    }
    //为指定按钮设置命令
    public void setCommand(int slot,Command onCommand,Command offCommand)
    {
        onCommands[slot]=onCommand;
         offCommands[slot]=offCommand;
        
    }
    //点击on按钮
    @Override
    public void onButton(int slot) {
        
        onCommands[slot].execute();
        stack.push(onCommands[slot]);
    }
    //点击off按钮
    @Override
    public void offButton(int slot) {
        
        offCommands[slot].execute();
        stack.push(offCommands[slot]);
    }

    @Override
    public void undoButton() {
        // TODO Auto-generated method stub
        //返回在这个堆栈的顶部的对象--最后一次操作的对象
        stack.pop().undo();
    }

}
package com.java.jikexueyuan.commandmode.command;
//宏命令
public class MarcoCommand implements Command {

    private Command[] commands;
    //初始化多个命令给宏命令
    public MarcoCommand(Command[] commands) {
        this.commands = commands;
    }

    @Override
    public void execute() {//执行时把所有初始化的命令全部执行
        // TODO Auto-generated method stub
        for (int i = 0, len = commands.length; i < len; i++) {
            commands[i].execute();
        }
    }

    @Override
    public void undo() {
        // TODO Auto-generated method stub
        for (int i = commands.length - 1; i >= 0; i--) {
            commands[i].undo();
            
        }
    }

}
package com.java.jikexueyuan.commandmode.command;

import com.java.jikexueyuan.commandmode.Control;
import com.java.jikexueyuan.commandmode.TraditionControl;
import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;

public class ControlTest {
    //按钮设置和点击演示
    public static void main(String[] args) {
        CommandModeControl control = new CommandModeControl();
        MarcoCommand onmarco,offmarco;
        Light bedroomlight = new Light("BedRoom");
        Light kitchlight = new Light("Kitch");
        Stereo stereo = new Stereo();
        
        
        
        LightOnCommand bedroomlighton = new LightOnCommand(bedroomlight);
        LightOffCommand bedroomlightoff = new LightOffCommand(bedroomlight);
        LightOnCommand kitchlighton = new LightOnCommand(kitchlight);
        LightOffCommand kitchlightoff = new LightOffCommand(kitchlight);

         Command[] oncommands={bedroomlighton,kitchlighton};
         Command[] offcommands={bedroomlightoff,kitchlightoff};
            
        onmarco=new MarcoCommand(oncommands);
        offmarco=new MarcoCommand(offcommands);
        
        StereoOnCommand stereoOn = new StereoOnCommand(stereo);
        StereoOffCommand stereoOff = new StereoOffCommand(stereo);
        StereoAddVolCommand stereoaddvol = new StereoAddVolCommand(stereo);
        StereoSubVolCommand stereosubvol = new StereoSubVolCommand(stereo);

        control.setCommand(0, bedroomlighton, bedroomlightoff);
        control.setCommand(1, kitchlighton, kitchlightoff);
        control.setCommand(2, stereoOn, stereoOff);
        control.setCommand(3, stereoaddvol, stereosubvol);
        control.setCommand(4, onmarco, offmarco);

        control.onButton(0);
        control.undoButton();
        //control.offButton(0);
        control.onButton(1);
        control.offButton(1);
        control.onButton(2);
        control.onButton(3);
                
        control.offButton(3);
        control.undoButton();
        control.offButton(2);
        control.undoButton();
        control.onButton(4);
        control.offButton(4);
    }

}

 

以上是关于设计模式--命令模式的主要内容,如果未能解决你的问题,请参考以下文章

是否有在单个活动中处理多个片段的 Android 设计模式?

尝试使用片段保存夜间模式状态

Sublime text3最全快捷键清单

Sublime text3最全快捷键清单

csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us

java 查看寻呼机设计模式与片段。