【设计模式】《Head First 设计模式》读书笔记——命令模式

命令模式:

将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

涉及设计原则:

1.为交互对象之间松耦合设计而努力
2.依赖抽象,不要依赖具体类

问题简单描述:

需要实现一个遥控器,控制不同硬件的功能。因为遥控器以后可能需要新增对其他硬件的控制,如果遥控器知道太多硬件的细节(依赖实体类),每增加一个硬件都需要对遥控器进行修改。

解决思路:

引进一个“傻瓜”命令对象,命令对象只需要执行简单的方法。遥控器中设置命令对象,命令对象依赖具体的硬件操作,实现遥控器与硬件操作的解耦。

UML图:



实现代码:

Receiver类

package command;

/**
 * 电灯(receiver)
 * @author terry
 *
 */
public class Light {
	
	private String description;
	
	public Light() {
		super();
	}

	public Light(String description) {
		super();
		this.description = description;
	}

	public void on(){
		System.out.println("Light is on");
	}
	
	public void off(){
		System.out.println("Light is off");
	}
	
	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}
	
	
	
	

}
package command;

public class TV {
	
	private boolean power;
	
	private Integer volumnNow;
	
	private String description;

	public TV() {
		super();
		volumnNow=5;
		power=false;
	}

	public TV(String description) {
		super();
		this.description = description;
		volumnNow=5;
		power=false;
	}
	
	public void on(){
		System.out.println("TV is on");
		power=true;
	}
	
	public void off(){
		System.out.println("TV is off");
		power=false;
	}
	
	public void turnUpVolumn(){
		if(power){
			System.out.println("TV's volumn has changed from "+volumnNow+" to "+ (++volumnNow));
		}else{
			System.out.println("TV is off");
		}
		
	}
	
	public void turnDownVolumn(){
		if(power){
			System.out.println("TV's volumn has changed from "+volumnNow+" to "+ (--volumnNow));
		}else{
			System.out.println("TV is off");
		}
		
	}

	public Integer getVolumnNow() {
		return volumnNow;
	}

	public void setVolumnNow(Integer volumnNow) {
		this.volumnNow = volumnNow;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}
	
	

}

Command接口

package command;

/**
 * 命令接口
 * author terry
 *
 */
public interface Command {
	//执行
	public void execute();
	//撤销
	public void undo();

}

Command实现类

package command;

public class LightOnCommand implements Command{
	
	Light light;

	public LightOnCommand(Light light) {
		super();
		this.light = light;
	}

	@Override
	public void execute() {
		light.on();
	}

	@Override
	public void undo() {
		light.off();
	}
	

}
package command;

public class LightOffCommand implements Command {
	
	Light light;
	

	public LightOffCommand(Light light) {
		super();
		this.light = light;
	}

	@Override
	public void execute() {
		light.off();
	}

	@Override
	public void undo() {
		light.on();
	}
	
	
}
package command;

public class TVOnCommand implements Command{
	
	TV tv;

	public TVOnCommand(TV tv) {
		super();
		this.tv = tv;
	}

	@Override
	public void execute() {
		tv.on();
	}

	@Override
	public void undo() {
		tv.off();
	}
	
}
package command;

public class TVOffCommand implements Command {
	
	TV tv;

	public TVOffCommand(TV tv) {
		super();
		this.tv = tv;
	}

	@Override
	public void execute() {
		tv.off();
	}

	@Override
	public void undo() {
		tv.on();
	}
	
	
}
package command;

public class TVTurnUpVolumnCommand implements Command{
	
	TV tv;

	public TVTurnUpVolumnCommand(TV tv) {
		super();
		this.tv = tv;
	}

	@Override
	public void execute() {
		tv.turnUpVolumn();
	}

	@Override
	public void undo() {
		tv.turnDownVolumn();
	}
	
}
package command;

public class TVTurnDownVolumnCommand implements Command{
	
	TV tv;
	

	public TVTurnDownVolumnCommand(TV tv) {
		super();
		this.tv = tv;
	}

	@Override
	public void execute() {
		tv.turnDownVolumn();
	}

	@Override
	public void undo() {
		tv.turnUpVolumn();
	}
	
}

Client(测试类)

package command;

public class Test {

	public static void main(String[] args) {
		//创建遥控器
		Invoker invoker=new Invoker();
		
		//绑定命令(1.将receiver绑定到command中 2.invoker调用setCommand设置command)
		Light light=new Light();
		LightOnCommand lightOnCommand=new LightOnCommand(light);
		LightOffCommand lightOffCommand=new LightOffCommand(light);
		invoker.setCommand(0, lightOnCommand);
		invoker.setCommand(1, lightOffCommand);
		
		TV tv=new TV();
		TVOnCommand tvOnCommand=new TVOnCommand(tv);
		TVOffCommand tvOffCommand=new TVOffCommand(tv);
		TVTurnDownVolumnCommand tvTurnDownVolumnCommand=new TVTurnDownVolumnCommand(tv);
		TVTurnUpVolumnCommand tvTurnUpVolumnCommand=new TVTurnUpVolumnCommand(tv);
		invoker.setCommand(2, tvOnCommand);
		invoker.setCommand(3, tvOffCommand);
		invoker.setCommand(4, tvTurnDownVolumnCommand);
		invoker.setCommand(5, tvTurnUpVolumnCommand);
		
		System.out.println(invoker.toString());
		System.out.println("====================action====================");
		invoker.buttonPushed(0);
		invoker.buttonPushed(1);
		invoker.buttonPushed(2);
		invoker.buttonPushed(4);
		invoker.buttonPushed(5);
		invoker.buttonPushed(3);
		
		System.out.println("====================undo====================");
		invoker.undo();
		invoker.undo();
		invoker.undo();
		invoker.undo();
		invoker.undo();
		invoker.undo();

	}

}

又是一个通过抽象松耦合的模式。原来只是client通过invoker'操作receiver的一个流程,引进的Command这样的“傻瓜”抽象层,使得invoker与receiver解耦。命令模式中,invoker只要调用command的execute就好了,不需要知道具体是什么command,command是怎么实现execute的,觉得有点像工厂模式的感觉,毕竟都是依赖了抽象解耦。觉得这就是架构的美,添加了一些多余的代码,虽然让不熟悉的人觉得可能降低了代码可读性,但是却为以后需求变化的代码修改做出了巨大便利。

欢迎批评指正^ ^








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值