设计模式学习(二) 命令模式

版权声明:有抱负的小狮子 https://blog.csdn.net/weixin_38087538/article/details/82703792

引入


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

UML类图

命令模式的角色介绍:

  • Receiver:接收者角色
  • 该类负责具体实施或执行一个请求,说的通俗一点就是,执行具体逻辑的角色,以上面说到的“关机”操作命令为例,其接收者角色就是真正执行各项关机逻辑的底层代码。任何一个类都能成为一个接收者,而接收者类中封装具体操作逻辑的方法我们则称为行动方法;
  • Command :命令接口
  • 定义所有具体命令类基本行为的抽象接口;
  • ConreteCommand:具体命令角色
  • 该类实现了 Command 接口,在 execute 方法中调用接收者角色的相关方法,在接收者和命令执行的具体行为之间加以弱耦合。而 execute 则通常称为执行方法,如上面提到的“关机”操作实现,具体可能还包含很多相关的操作,比如保存数据、关闭文件、结束进程等,如果将这一些列的具体逻辑处理看作接收者,那么调用这些具体逻辑的方法就可以看作是执行方法;
  • Invoker :请求者角色
  • 该类的职责就是调用命令对象执行具体的请求,相关的方法我们称为行动方法,“关机”命令为例,关机这个命令一般就对应着一个关机方法,执行关机命令就相当于由这个关机方法去执行具体的逻辑,这个关机方法就可以看作是请求者;
  • Client:客户端角色

示例

package com.zpkj.project12;

public class Light {

	public void onLight(){
		System.out.println("开灯");
	}

	public void offLight(){
		System.out.println("关灯");

	}
	
}
package com.zpkj.project12;

public class Door {

	public void onDoor(){
		System.out.println("开门");
	}

	public void offDoor(){
		System.out.println("关门");
	}


}
package com.zpkj.project12;

public interface DoorCommandInter {
	
	
	public abstract void execute();
	
	public abstract void undo();
}
package com.zpkj.project12;

public interface LightCommandInter {
	
	public abstract void execute();
	
	public abstract void undo();

}
package com.zpkj.project12;

public class DoorCommand implements DoorCommandInter {
	
	private Door door;
	
	public DoorCommand(Door door) {
		this.door = door;
	}

	@Override
	public void execute() {
		door.onDoor();
		
	}

	@Override
	public void undo() {
		door.offDoor();
	}

}
package com.zpkj.project12;

public class LightCommand implements LightCommandInter{

	private Light light;
	
	public LightCommand(Light light) {
		this.light = light;
	}

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

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

}
package com.zpkj.project12;

public class DoorInvoker {
	
	private int status;
	
	private DoorCommandInter doorCommandInter;
	
	public DoorInvoker(DoorCommandInter doorCommandInter,int status) {
		this.doorCommandInter = doorCommandInter;
		this.status = status;
		
	}
	
	public void action(){
		if(status==1){
			doorCommandInter.undo();
		}else if(status==2){
			doorCommandInter.execute();
		}else{
			System.out.println("指令错误");
		}	
	}
	

}
package com.zpkj.project12;

public class LightInvoker {
	
	private int status;
	
	private LightCommandInter lightCommandInter;
	
	public LightInvoker(LightCommandInter lightCommandInter, int status) {
		this.lightCommandInter = lightCommandInter;
		this.status = status;
	}
	
	public void action(){
		if(status==1){
			lightCommandInter.undo(); 
		}else if(status==2){
			lightCommandInter.execute();
		}else{
			System.out.println("指令错误");
		}	
	}
	
	
}
package com.zpkj.project12;

public class Client {
	
	public static void main(String[] args) {
		Door door = new Door();
		DoorCommandInter doorCommandInter = new DoorCommand(door);
		DoorInvoker doorInvoker = new DoorInvoker(doorCommandInter, 2);
		DoorInvoker doorInvoker2 = new DoorInvoker(doorCommandInter, 1);
		doorInvoker.action();
		doorInvoker2.action();
		System.out.println("--------------------------------------------");
		Light light = new Light();
		LightCommandInter lightCommandInter = new LightCommand(light);
		LightInvoker lightInvoker = new LightInvoker(lightCommandInter, 2);
		LightInvoker lightInvoker2 = new LightInvoker(lightCommandInter, 1);
		lightInvoker.action();
		lightInvoker2.action();
		System.out.println("--------------------------------------------");
	}
}

测试结果

优点

1.降低对象之间的耦合度。

2.新的命令可以很容易地加入到系统中。

3.可以比较容易地设计一个组合命令。

4.调用同一方法实现不同的功能

缺点

使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

总结

1.命令模式将发出的请求对象和执行请求的对象解耦

2.在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接受者和一个或一组动作

3.调用者通过调用命令对象的execute()发出的请求,这样会使接受者的动作被调用

4.调用者可以接受命令当做参数,甚至在运行时动态地进行。

5.命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态

6.宏命令是命令的一种简单的延伸,允许调用多个命令。宏方法也可以支持撤销

7.实际操作时,很常见使用“聪明”命令对象,也就是直接实现了请求,而不是将工作委托给接受者。

8.命令也可以用来实现日志和事务系统

引用

[1] 弗里曼. Head First 设计模式(中文版)[Z]. 中国电力出版社: O'Reilly Taiwan公司 ,2007.

  https://blog.csdn.net/self_study/article/details/52091539

  https://blog.csdn.net/jason0539/article/details/45110355

源码下载

https://github.com/isheroleon/design

猜你喜欢

转载自blog.csdn.net/weixin_38087538/article/details/82703792