23种设计模式——命令模式

目录

命令模式

UML图

示例代码

使用场景

优点

实例——电脑开机

命令+备忘录模式


命令模式

本质:封装请求

命令模式又称为行动(Action)模式或交易(Transaction)模式。

命令模式:将一个请求封装为一个对象,对请求排队或记录请求日志,可以提供命令的撤销和恢复功能。

命令模式将发出操作的对象Invoker和实现操作的对象Receiver解耦。

UML图

23种设计模式——命令模式_第1张图片

共三级角色:发起人Ivoker、命令发出者Command、执行者Receiver。
Ivoker和Receive不直接交流,而是通过Command交流

将Receiver放到ConcreteCommand中,当请求到来(Invoker激活Command对象),ConcreteCommand将处理请求交给Receiver对象进行处理。
 

示例代码

public abstract class Command {
	protected Receiver receiver;

	public Command(Receiver receiver) {
		super();
		this.receiver = receiver;
	}
	
	public abstract void excute();

}
public class ConcreteCommand extends Command{

	public ConcreteCommand(Receiver receiver) {
		super(receiver);
	}

	@Override
	public void excute() {
		receiver.action();
	}

}
public class Invoker {
	private Command command;

	public void setCommand(Command command) {
		this.command = command;
	}
	
	public void excutecommand() {
		command.excute();
	}

}
public class Receiver{
	public void action() {
		System.out.println("执行请求");
	}
}
public class Main {

	public static void main(String[] args) {
		Receiver r=new Receiver();
		Command c=new ConcreteCommand(r);
		Invoker i=new Invoker();
		i.setCommand(c);
		i.excutecommand();
	}

}

使用场景

  • 请求队列化:把请求封装成为命令对象。
  • 取消操作:实现命令的撤销和重做
  • 把对系统的操作功能重新执行一遍:把这些操作功能的请求封装成命令对象,通过日志获取命令列表,从而重新执行一遍功能。
  • 需要事务的系统:如银行转账,买票。


优点

  • 容易设计一个命令队列。
  • 容易将命令记入日志。
  • 容易实现对请求的撤销和重做。
  • 容易增加新的具体命令类
  • 允许接收请求的一方决定是否要否决请求。
  • 把请求操作的对象和执行操作的对象分开。

实例——电脑开机

  • 发起人:机箱
  • 命令者:机箱上的按钮
  • 接收者:主板
//机箱:发起人
public class Box {
	private Command command;
	private String str;
	
	public void button() {
		command.execute(str);
	}

	public void setStr(String str) {
		this.str = str;
	}

	public void setCommand(Command command) {
		this.command = command;
	}
	
}
public interface Command {
	public void execute(String str);
}
//具体命令
public class ConcreteCommand implements Command{
	private MainBoardApi mainboard=null;
	
	public ConcreteCommand(MainBoardApi mainboard) {
		super();
		this.mainboard = mainboard;
	}


	@Override
	public void execute(String str) {
		this.mainboard.action(str);
	}
	
}
//把实现操作定义成接口,可以有不同的具体实现(但是我为了方便没有分成两个子类写)
public interface MainBoardApi {
	public void action(String str);
}

//实现操作
public class GigaMainBoard implements MainBoardApi{
	

	public GigaMainBoard() {
		super();
		// TODO Auto-generated constructor stub
	}

	@Override
	public void action(String str) {
		if(("open").equals(str)) {
			System.out.println("电脑打开");
		}else 
			System.out.println("电脑关闭");
	}
	
	
}
public class Main {

	public static void main(String[] args) {
		//实现操作的对象
		MainBoardApi mainboard=new GigaMainBoard();
		
		//命令列表
		ArrayList commands=new ArrayList();
		ConcreteCommand c1=new ConcreteCommand(mainboard);
		ConcreteCommand c2=new ConcreteCommand(mainboard);
		commands.add(c1);
		commands.add(c2);
		
		//发起人
		Box box=new Box();
		for(int i=0;i

命令+备忘录模式

将命令模式和备忘录模式结合,实现计算器的撤销和重做。

23种设计模式——命令模式_第2张图片

public class Calculator {
	private double total=0;
	
	public void Operation(char op,int oper) {
		switch(op) {
		case '+':
			total+=oper;
			break;
		case '-':
			total-=oper;
			break;
		case '*':
			total*=oper;
			break;
		case '/':
			total/=oper;
			break;
		}
		System.out.println("total:"+total);
	}

}
public abstract class Command {
	public abstract void execute();
	public abstract void unexcute();

}
public class CalculatorCommand extends Command{
	char op;
	int oper;
	Calculator calculator;

	public CalculatorCommand(char op, int oper, Calculator calculator) {
		super();
		this.op = op;
		this.oper = oper;
		this.calculator = calculator;
	}

	public char getOp() {
		return op;
	}

	public void setOp(char op) {
		this.op = op;
	}


	public int getOper() {
		return oper;
	}

	public void setOper(int oper) {
		this.oper = oper;
	}


	public Calculator getCalculator() {
		return calculator;
	}

	public void setCalculator(Calculator calculator) {
		this.calculator = calculator;
	}


	@Override
	public void execute() {
		calculator.Operation(op, oper);
	}

	@Override
	public void unexcute() {
		calculator.Operation(Undo(op), oper);
	}
	
	private char Undo(char op) {
		char undo=' ';
		switch(op) {
		case '+':undo='-';
			break;
		case '-':undo='+';
			break;
		case '*':undo='/';
			break;
		case '/':undo='*';
			break;
		}
		return undo;
		
	}

}
public class User {
	private Calculator calculator=new Calculator();
	private ArrayList commands=new ArrayList();
	private int current;
	
	public void Redo(int levels) {
		System.out.println("redo "+levels+" level");
		for(int i=0;i0)
				commands.get(--current).unexcute();
			else
				System.out.println("not undo");
		}
	}
	
	public void Compute(char op,int oper) {
		Command command =new CalculatorCommand(op,oper,calculator);
		command.execute();
		commands.add(command);
		current++;
	}
	
}
public class Main {

	public static void main(String[] args) {
		User user=new User();
		user.Compute('+',100);
		user.Compute('-',50);
		user.Compute('*',10);
		user.Compute('/',2);
		user.Undo(4);//撤销4次
		user.Redo(3);//重做3次
	}

}

你可能感兴趣的:(设计模式,设计模式,命令模式,java)