命令(command)模式
来源:互联网 发布:ktv 知乎 编辑:程序博客网 时间:2024/06/03 02:48
材料内容均取自head first dp
一、简介
命令模式是将请求(命令)封装为对象。以便于使用不同的请求(队列或者日志)来参数化其他对象。
命令模式把发出命令的责任(invoker)和执行命令的责任(receiver)分割开。
关于命令模式
1.命令模式将发出请求的对象和执行请求的对象解耦
2.在被解耦的两者之间间是通过命令对象进行沟通的,命令对象封装了一个或一组动作
3.调用者通过调用命令对象的execute方法发出请求,这使得接收者对象的劢作被调用
4.宏命令是命令的一种简单延伸,允许调用多个命令
二、遥控器控制家电的例子
有一个综合遥控器(remoteController),可以控制点灯(light)的开关,电视(TV)的开关等等。然后电灯的开关和电视的开关方式不同,如何可扩展的集中到一个遥控器上,例如当增加新的电器空调时,可以遵循开闭原则,不更改现有代码。
在这个例子中,主人作为client来操作所有电器。remoteController作为一个invoker,因为主人直接操作的是遥控器来控制各个电器,而电灯、电视等当然是以receiver的身份出现。我们这里需要抽象出command,以及实现控制具体家电的command。
Command(命令)接口
- public interface Command {
- //命令对象方法
- public void execute();
- }
遥控器(发出命令对象)类:RemoteControl.java
- import java.util.ArrayList;
- import java.util.List;
- public class RemoteControl {
- //用于存放命令
- private List<Command> commandList = new ArrayList<Command>();
- /**
- * 向遥控器中添加命令
- * @param command
- */
- public void setCommand(Command command){
- commandList.add(command);
- }
- /**
- * 按下按键执行第几个命令
- * @param index
- */
- public void buttonWasPressed(int index){
- commandList.get(index - 1).execute();
- }
- }
两个电器(执行命令对象):电灯类、电视类
- //1.电灯类
- public class Light {
- public void on(){
- System.out.println("灯亮了!");
- }
- }
- //2.电视类
- public class Tv {
- public void on(){
- System.out.println("打开电视!");
- }
- }
Java代码
- //1.控制电灯
- public class LightOnCommand implements Command{
- private Light light;
- /**
- * 传入控制的对象:电灯
- * @param light
- */
- public LightOnCommand(Light light){
- this.light = light;
- }
- /**
- * 执行命令:打开灯
- */
- @Override
- public void execute() {
- light.on();
- }
- }
Java代码
- //2.控制电视
- public class TurnTvCommand implements Command{
- private Tv tv;
- public TurnTvCommand (Tv tv){
- this.tv = tv;
- }
- @Override
- public void execute() {
- tv.on();
- }
- }
- package com.kaishengit.command;
- public class Test {
- public static void main(String[] args) {
- //创建遥控器
- RemoteControl remoteControl = new RemoteControl();
- //开灯命令
- LightOnCommand lightOnCommand = new LightOnCommand(new Light());
- //打开电视命令
- TurnTvCommand turnTvCommand = new TurnTvCommand(new Tv());
- //将命令捆绑到遥控器上
- remoteControl.setCommand(turnTvCommand);
- remoteControl.setCommand(lightOnCommand);
- //按下按钮
- remoteControl.buttonWasPressed(1);//执行第一个命令
- //remoteControl.buttonWasPressed(2);//执行第二个命令
- }
- }
宏命令:是对子命令的结合体,一连串命令。
比如这里,我们创建一个宏命令:先开灯,再开电视
宏命令对象(实现Command接口):MacroCommand.java
Java代码
- //宏命令
- public class MacroCommand implements Command{
- private Command[] commands;
- /**
- * 传入命令列表
- * @param commands
- */
- public MacroCommand(Command...commands){
- this.commands = commands;
- }
- /**
- * 依次执行命令列表中的命令
- */
- @Override
- public void execute() {
- for(Command command : commands){
- command.execute();
- }
- }
- }
试一下我们新建的宏命令对象
Java代码
- package com.kaishengit.command;
- public class Test {
- public static void main(String[] args) {
- //创建遥控器
- RemoteControl remoteControl = new RemoteControl();
- //开灯命令
- LightOnCommand lightOnCommand = new LightOnCommand(new Light());
- //开电视命令
- TurnTvCommand turnTvCommand = new TurnTvCommand(new Tv());
- //我们创建的宏命令,传入命令列表:1.开灯命令、2.开电视命令
- MacroCommand mc = new MacroCommand(lightOnCommand,turnTvCommand);
- //将宏命令捆绑到遥控器上
- remoteControl.setCommand(mc);
- //按下按钮,执行宏命令
- remoteControl.buttonWasPressed(1);
- }
- }
三、命令模式的拓展
命令模式支持undo操作,日志操作和事物操作等,如果做到呢?
我们可以在remoteController中增加一个栈域,每undo一次,从栈中弹出上一次的操作。日志也是在invoker中记录所有的操作。事物其实就undo操作的完整版了,当遇到异常时rollback,rollback的依据,也就是invoker中记录的操作。
- 命令模式--command模式
- 命令(Command)模式
- 命令模式(Command Pattern)
- 命令(Command)模式
- 命令者(Command)模式
- 命令模式(Command Pattern)
- 命令(Command)模式
- Command命令模式
- 命令模式(Command)
- Command Pattern(命令模式)
- Command 命令模式
- Command 命令模式
- 命令(Command)模式
- Command 命令模式
- 命令模式Command
- 命令模式(Command)
- 命令模式(Command)
- Command(命令模式)
- 2013-04-06 二叉树的创建,遍历,统计度为2的节点的个数。
- C#中string与stringbuilder性能差异的原因详解
- 使用EM来查看表空间视图
- 一键无线共享
- stl map用法和make_pair函数
- 命令(command)模式
- jQuery 入门教程(36): jQuery UI Menu 示例
- 基于stm32f103zet6的FAT16文件系统学习3(初步分析ff9a)
- 学习Gtkmm系列之五
- jQuery 选择器
- 结构体和类
- Codeforces Round #173 (Div. 2) A.Bit++
- 我的架构师成长之路
- centos 下安装g++