设计模式--命令模式

                     设计模式--命令模式
 


命令模式原理
家电自动化遥控器API项目:
各家电API
遥控器接口

要求自动化遥控器:扩展性好、维护性好
·
传统设计方案实现如下

Light灯设备

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");
	}

}


Stereo设备

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");
	}
}


Control控制器接口

public interface Control {

	public void onButton(int slot);

	public void offButton(int slot);
	
	public void undoButton();
}

TraditionControl

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
		
	}

	

}


命令模式的原理
·设计方案类图
设计模式--命令模式

设计模式--命令模式

命令模式:将请求、命令、动作等封装成对象,这样可以让项目使用这些对象来参数化其他对象。
使得命令的请求者和执行者解耦
·类继承体系结构
·扩展性功能
命令模式项目代码讲解
Command

public interface Command {
    public void execute();
    public void undo();
}


LightOnCommand

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();
    }

}

LightOffCommand

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();
	}

}



StereoOnCommand

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();
    }

}

StereoOffCommand 

public class StereoOffCommand implements Command {
	private Stereo setreo;
	public StereoOffCommand(Stereo setreo)
	{
		this.setreo=setreo;
	}
	
	@Override
	public void execute() {
		// TODO Auto-generated method stub
		setreo.Off();
	}

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

}


StereoAddVolCommand

public class StereoAddVolCommand implements Command {
	private Stereo setreo;
	public StereoAddVolCommand(Stereo setreo)
	{
		this.setreo=setreo;
	}
	
	@Override
	public void execute() {
		// TODO Auto-generated method stub
	int vol=	setreo.GetVol();
	if(vol<11)
	{
		setreo.SetVol(++vol);
	}
		
	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub
	int vol=	setreo.GetVol();
	if(vol>0)
	{
		setreo.SetVol(--vol);
	}
		
	}

}

StereoSubVolCommand

public class StereoSubVolCommand implements Command {
	private Stereo setreo;
	public StereoSubVolCommand(Stereo setreo)
	{
		this.setreo=setreo;
	}
	
	@Override
	public void execute() {
		// TODO Auto-generated method stub
	int vol=	setreo.GetVol();
	if(vol>0)
	{
		setreo.SetVol(--vol);
	}
		
	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub
	int vol=	setreo.GetVol();
	if(vol<11)
	{
		setreo.SetVol(++vol);
	}
		
	}

}


NoCommand可以提高运行速度

public class NoCommand implements Command {

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

	}

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

	}

}

CommandModeControl按钮的执行

public class CommandModeControl implements Control{
	private Command[] onCommands;
	private Command[] offCommands;
	private Stack<Command> stack=new Stack<Command>();
	public CommandModeControl()
	{
		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;
		
	}

	@Override
	public void onButton(int slot) {
		
		onCommands[slot].execute();
		stack.push(onCommands[slot]);
	}

	@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();
	}

}

 MarcoCommand有时一个按钮控制很多设备

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();
			
		}
	}

}


ControlTest

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);
	}

}