阅读 183

DesignPattern - 命令模式【行为型】

欢迎关注微信公众号:FSA全栈行动 👋

一、命令模式介绍

命令模式(Command Pattern)请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的对象,并把该命令传给相应的对象 执行命令,属于行为型模式。

命令模式是一种特殊的策略模式,体现的是多个策略执行的问题,而不是选择的问题

  • 核心组成

    • 抽象命令(Command):需要执行的所有命令都在这里声明
    • 具体命令(ConcreteCommand):定义一个接收者和行为之间的弱耦合,实现 execute() 方法,负责调用接收者的相应操作,execute() 方法通常叫做执行方法
    • 接受者(Receiver):负责具体实施和执行一个请求,干活的角色,命令传递到这里是应该被执行的,实施和执行请求的方法叫做行动方法
    • 请求者(Invoker):负责调用命令对象执行请求,相关的方法叫做行动方法
    • 客户端(Client):创建一个具体命令(ConcreteCommand)对象并确定其接收者
  • 应该场景

    • 只要是你认为是命令的地方,就可以采用命令模式
    • 日常每个界面、按钮、键盘事件操作都是命令模式
  • 优点

    • 调用者角色与接收者角色之间没有任何依赖关系,不需要了解到底是哪个接收者执行,降低了系统耦合度
    • 扩展性强,新的命令可以很容易添加到系统中去
  • 缺点

    • 过多的命令模式会导致某些系统有过多的具体命令类

二、命令模式代码实现

以手机 App 控制智能空调为例,三者关系为:InvokerApp --> Command(n 个) --> ConditionReceiver

创建接受者类:

/**
 * 接受者:空调
 *
 * @author GitLqr
 */
public class ConditionReceiver {

	public void on() {
		System.out.println("空调开机");
	}

	public void off() {
		System.out.println("空调关机");
	}

	public void cool() {
		System.out.println("空调开始制冷");
	}

	public void warm() {
		System.out.println("空调开始制暖");
	}
}
复制代码

创建抽象命令类:

/**
 * 抽象命令
 *
 * @author GitLqr
 */
public interface Command {

	void execute();
}
复制代码

创建具体命令类:

说明:一种命令一个类;命令类需要持有接受者实例引用,以便触发接受者相应方法

/**
 * 具体命令:开机命令
 *
 * @author GitLqr
 */
public class OnCommand implements Command {

	ConditionReceiver conditionReceiver;

	public OnCommand(ConditionReceiver conditionReceiver) {
		super();
		this.conditionReceiver = conditionReceiver;
	}

	@Override
	public void execute() {
		System.out.println("OnCommand -> execute");
		this.conditionReceiver.on();
	}
}
/**
 * 具体命令:关机命令
 *
 * @author GitLqr
 */
public class OffCommand implements Command {

	ConditionReceiver conditionReceiver;

	public OffCommand(ConditionReceiver conditionReceiver) {
		super();
		this.conditionReceiver = conditionReceiver;
	}

	@Override
	public void execute() {
		System.out.println("OffCommand -> execute");
		this.conditionReceiver.off();
	}
}
/**
 * 具体命令:制冷命令
 *
 * @author GitLqr
 */
public class CoolCommand implements Command {
	ConditionReceiver conditionReceiver;

	public CoolCommand(ConditionReceiver conditionReceiver) {
		super();
		this.conditionReceiver = conditionReceiver;
	}

	@Override
	public void execute() {
		System.out.println("CoolCommand -> execute");
		this.conditionReceiver.cool();
	}
}
/**
 * 具体命令:制暖命令
 *
 * @author GitLqr
 */
public class WarmCommand implements Command {

	ConditionReceiver conditionReceiver;

	public WarmCommand(ConditionReceiver conditionReceiver) {
		super();
		this.conditionReceiver = conditionReceiver;
	}

	@Override
	public void execute() {
		System.out.println("WarmCommand -> execute");
		this.conditionReceiver.warm();
	}
}
复制代码

创建请求者类:

说明:请求者类需要持有命令引用,负责各种命令的调用

/**
 * 请求者:遥控器App
 *
 * @author GitLqr
 */
public class AppInvoker {

	private Command onCommand;
	private Command offCommand;
	private Command coolCommand;
	private Command warmCommand;

	public void setOnCommand(Command onCommand) {
		this.onCommand = onCommand;
	}

	public void setOffCommand(Command offCommand) {
		this.offCommand = offCommand;
	}

	public void setCoolCommand(Command coolCommand) {
		this.coolCommand = coolCommand;
	}

	public void setWarmCommand(Command warmCommand) {
		this.warmCommand = warmCommand;
	}

	public void on() {
		onCommand.execute();
	}

	public void off() {
		offCommand.execute();
	}

	public void cool() {
		coolCommand.execute();
	}

	public void warm() {
		warmCommand.execute();
	}
}
复制代码

使用:

public static void main(String[] args) {
    // 创建接受者对象,空调
    ConditionReceiver conditionReceiver = new ConditionReceiver();

    // 创建命令对象,设置命令的接受者
    Command onCommand = new OnCommand(conditionReceiver);
    Command offCommand = new OffCommand(conditionReceiver);
    Command coolCommand = new CoolCommand(conditionReceiver);
    Command warmCommand = new WarmCommand(conditionReceiver);

    // 创建请求者,把命令对象设置进去,app就是请求的发起者
    AppInvoker appInvoker = new AppInvoker();
    appInvoker.setOnCommand(onCommand);
    appInvoker.setOffCommand(offCommand);
    appInvoker.setCoolCommand(coolCommand);
    appInvoker.setWarmCommand(warmCommand);

    appInvoker.on();
    appInvoker.cool();
    appInvoker.warm();
    appInvoker.off();
}
复制代码

如果文章对您有所帮助, 请不吝点击关注一下我的微信公众号:FSA全栈行动, 这将是对我最大的激励. 公众号不仅有Android技术, 还有iOS, Python等文章, 可能有你想要了解的技能知识点哦~

文章分类
代码人生
文章标签