Java再会命令模式

GOF定义

命令模式 ( 别名 : 动作, 事务)
将一个请求封装为一个对象, 从而使用户可用不同的请求对客户进行参数化; 对请求排队或记录请求日志, 以及支持可撤销的操作

概述

在命令模式中, 当一个对象请求调用其方法时, 不和被请求的对象直接打交道, 而是把这种"请求"封装到一个称为"命令"的对象中, 其封装的手段是将"请求"封装在"命令"对象的一个方法中。
命令模式的核心就是使用命令对象来封装方法调用, 即将请求者的请求:"接收者的调用方法"封装到命令对象的一个方法中, 这样一来, 当一个对象请求另一个对象调用方法来完成某项任务时, 只需和命令对象打交道, 即让命令对象调用封装了"请求"的那个方法即可。

命令模式的优点和适合使用命令模式的情景

优点:

  1. 在命令模式中, 请求者Invoker不直接与接收者Receiver交互, 即请求者 Invoker 不包含接收者Receiver的引用, 因此彻底消除了彼此的耦合;
  2. 命令模式满足 开闭原则 , 如果增加新的具体命令和该命令的接收者, 不必修改调用者的代码, 调用者就可以使用新的命令对象; 反之, 如果增加新的调用者, 不必修改现有的具体命令和接收者, 新增加的调用者就可以使用已有的具体命令
  3. 由于请求者的请求被封装到了具体命令中, 那么就可以将具体命令保存到持久化的媒介中, 在需要的时候, 重新执行这个具体命令, 因此, 使用命令模式可以记录日志
  4. 使用命令模式可以对请求者的"请求"进行排队, 每个请求都各自对应一个具体命令, 因此可以按一定顺序执行这些具体命令。

适用情景

  1. 程序需要在不同的时刻 指定, 排列 和 执行请求;
  2. 程序需要提供撤销操作
  3. 程序需要支持宏操作

模式的结果与使用

四种角色

接收者 Receiver

接收者是一个类的实例,该实例负责执行与请求相关的操作

命令接口 Command

命令是一个接口, 规定了用来封装“请求”的若干个方法,比入 execute() 方法, undo() 方法等

具体命令 ConcreteCommand

具体命令是实现命令接口的类的实例, 具体命令必须实现命令接口中的方法, 比如 execute() 方法, 使得该方法成为一个"请求"

请求者 Invoker

请求者是一个包含Command接口变量的类的实例. 请求者中的Command接口的变量可以存放任何具体命令的引用, 请求者负责调用具体命令, 让具体命令执行那些封装了"请求"的方法, 比如 execute() 方法

案例1:简单命令模式

在这里插入图片描述

package com.beyond.cwq.command;

/**
 * 接收者 Receiver
 */
class CompanyArmy {
    
    
	public void sneakAttack() {
    
    
		System.out.println("我们知道着么偷袭敌人, 保证完成任务");
	}

}

/**
 * 命令接口
 */
interface Command1{
    
    
	public abstract void execute();
}

/**
 * 具体实现命令
 */
class ConcreteCommend1 implements Command1{
    
    
	CompanyArmy army;
	public ConcreteCommend1(CompanyArmy army) {
    
    
		this.army = army;
	}
	@Override
	public void execute() {
    
    
		army.sneakAttack();
	}
}
/**
 * 请求者 Invoker
 */
class ArmySuperior{
    
    
	Command1 command;
	public void setCommend(Command1 command) {
    
    
		this.command = command;
	}
	public void startExecuteCommend() {
    
    
		command.execute();
	}
	
}

public class CommandTest{
    
    
	public static void main(String[] args) {
    
    
		CompanyArmy SanLian = new CompanyArmy();
		Command1 command = new ConcreteCommend1(SanLian);
		ArmySuperior as = new ArmySuperior();
		as.setCommend(command);
		as.startExecuteCommend();
	}
}



在这里插入图片描述

案例2: 命令接口中的撤销方法 (使用ArrayList)

在这里插入图片描述

package com.beyond.cwq.command;

import java.io.File;
import java.util.ArrayList;

/**
 * 命令接口
 */
interface Command{
    
    
	public void execute(String name);
	public void undo();
}

/**
 * 具体实现
 */
class ConcreteCommand implements Command{
    
    
	MakeDir makedir;
	ArrayList<String> dirNameList;
	
	public ConcreteCommand(MakeDir makeDir) {
    
    
		dirNameList = new ArrayList<String>();
		this.makedir = makeDir;
	}
	
	
	@Override
	public void execute(String name) {
    
    
		makedir.createDir(name);
		dirNameList.add(name);
	}
	@Override
	public void undo() {
    
    
		if (dirNameList.size()>0) {
    
    
			int m = dirNameList.size();
			String str = dirNameList.get(m-1);
			makedir.deleteDir(str);
			dirNameList.remove(m-1);
		}else {
    
    
			System.out.println("没有需要撤销的操作!");
		}
	}
}

/**
 * 请求者 Invoker
 */
class RequestMakedir{
    
    
	Command command ;
	public void setCommand(Command command) {
    
    
		this.command = command;
	}
	public void startExcuteCommand(String name) {
    
    
		command.execute(name);
	}
	public void undoCommand() {
    
    
		command.undo();
	}
}

/**
 * 执行者  Receiver
 * @author DHL
 *
 */
class MakeDir{
    
    
	public MakeDir() {
    
    }
	public void createDir(String name) {
    
    
		File dir = new File(name);
		dir.mkdir();
	}
	public void deleteDir(String name) {
    
    
		File dir = new File(name);
		dir.delete();
	}
}


public class CommandTest01 {
    
    
	public static void main(String[] args) {
    
    
		MakeDir makeDir = new MakeDir();
		RequestMakedir rm = new RequestMakedir();
		Command command = new ConcreteCommand(makeDir);
		rm.setCommand(command);
		rm.startExcuteCommand("Beyond");
		rm.startExcuteCommand("Beyond1");
		rm.startExcuteCommand("Beyond2");
		rm.startExcuteCommand("Beyond3");
		rm.undoCommand();
		rm.undoCommand();
		rm.undoCommand();
		
	}
}

在这里插入图片描述

案例3: 宏命令

宏命令也是一个具体命令, 只不过它包含了其他具体命令的引用。当一个宏命令执行其 execute() 方法时, 将会导致所引用的其他具体命令执行 execute() 方法, 因此, 执行一个宏命令相当于执行了许多具体命令。
在这里插入图片描述

package com.beyond.cwq.command;

import java.util.ArrayList;

/**
 * 接收者 1号
 */
class PrintLetter {
    
    
	public void printEnglish() {
    
    
		System.out.println("打印的是英文字母~");
	}

	public void printRussian() {
    
    
		System.out.println("打印的是俄语~~");
	}
}

/**
 * 接收者 2号
 */
class PrintNumber {
    
    
	public void printNumber() {
    
    
		System.out.println("打印的是数字~");
	}
}

/**
 * 命令接口
 */
interface Command02 {
    
    
	public void execute();
}

/**
 * 具体命令1
 */
class PrintEnglishCommand implements Command02 {
    
    
	PrintLetter printLetter;

	public PrintEnglishCommand(PrintLetter printLetter) {
    
    
		this.printLetter = printLetter;
	}

	@Override
	public void execute() {
    
    
		printLetter.printEnglish();
	}
}

/**
 * 具体命令2
 */
class PrintRussianCommand implements Command02 {
    
    
	PrintLetter printLetter;

	public PrintRussianCommand(PrintLetter printLetter) {
    
    
		this.printLetter = printLetter;
	}

	@Override
	public void execute() {
    
    
		printLetter.printRussian();
	}
}

/**
 * 具体命令3
 */
class PrintNumberCommand implements Command02 {
    
    
	PrintNumber printNumber;

	public PrintNumberCommand(PrintNumber printNumber) {
    
    
		this.printNumber = printNumber;
	}

	@Override
	public void execute() {
    
    
		printNumber.printNumber();
	}
}

/**
 * 宏命令
 */
class MacroCommand implements Command02 {
    
    
	ArrayList<Command02> commandList;

	public MacroCommand(ArrayList<Command02> commandList) {
    
    
		this.commandList = commandList;
	}

	@Override
	public void execute() {
    
    
		for (int x = 0; x < commandList.size(); x++) {
    
    
			Command02 command = commandList.get(x);
			command.execute();
		}
	}
}

/**
 * 请求者 
 */
class RequestPerson{
    
    
	Command02 command;
	public RequestPerson(Command02 command) {
    
    
		this.command = command;
	}
	public void startExecuteCommand() {
    
    
		command.execute();
	}
}


public class CommandDemo02 {
    
    
	public static void main(String[] args) {
    
    
		PrintLetter printLetter = new PrintLetter();
		PrintNumber printNumber = new PrintNumber();
		ArrayList<Command02> commandList = new ArrayList<Command02>();
		Command02 command1 = new PrintEnglishCommand(printLetter);
		Command02 command2 = new PrintNumberCommand(printNumber);
		
		commandList.add(command1);
		commandList.add(command2);
		MacroCommand macroCommand = new MacroCommand(commandList);
		RequestPerson rp = new RequestPerson(macroCommand);
		rp.startExecuteCommand();
	}

}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Beyond_Nothing/article/details/111880930
今日推荐