Java设计模式 之 命令模式
1 从属模式分类
行为性模式
2 命令模式意图
命令模式可将动作的请求者和动作的执行者对象中解耦。
该模式将一个行为操作发起者的请求封装到对象中,该请求由另外一个对象执行。
将动作封装成命令对象,这样一来就可以随心所欲的储存、传递、调用。
做多件事,有多种做法。
3 命令模式结构
4 命令模式代码实现
这里假设有一个需要编程实现功能的遥控器,一共有10组开关按钮需要编程来实现不同的控制逻辑。比如说第一组开关可控制客厅的电灯的开关,第二组开关按钮可控制车库门的升起和落下,使用命令模式代码如下:
4.1 ICommon.java
|
package com.gof.pattern.command; /** * 命令接口 * @author Administrator */ public interface ICommand { // 执行 public void execute(); // 撤销 public void undo(); } |
4.2 Light.java
|
package com.gof.pattern.command; /** * 电灯 * @author Administrator */ public class Light { private Stringname; public Light(String name){ this.name = name; } public void on(){ System.out.println(name +" light is on!"); } public void off(){ System.out.println(name +" light is off!"); } } |
4.3 LightOnCommand.java
|
package com.gof.pattern.command; public class LightOnCommand implements ICommand { private Lightlight; public LightOnCommand(Light light){ this.light = light; } @Override public void execute() { light.on(); } @Override public void undo() { light.off(); } } |
4.4 LightOffCommand.java
|
package com.gof.pattern.command; /** * 关灯 * @author Administrator * */ public class LightOffCommand implements ICommand { private Lightlight; public LightOffCommand(Light light){ this.light = light; } @Override public void execute() { light.off(); } @Override public void undo() { light.on(); } } |
4.5 Stereo.java
|
package com.gof.pattern.command; /** * 音响 * @author Administrator */ public class Stereo { private Stringname; public Stereo(String name){ this.name = name; } public void on(){ System.out.println(name +" is on!"); } public void off(){ System.out.println(name +" is off!"); } public void setCd(){ System.out.println(name +" setCd!"); } public void setDvd(){ System.out.println(name +" setDvd!"); } public void setRadio(){ System.out.println(name +" setRadio!"); } public void setVolume(int size){ System.out.println(name +" setVolume is "+ size +"!"); } } |
4.6 StereoOffWithCDCommand.java
|
package com.gof.pattern.command; /** * 关闭音响 * @author Administrator * */ public class StereoOffWithCDCommand implements ICommand { private Stereostereo; public StereoOffWithCDCommand(Stereo stereo){ this.stereo = stereo; } @Override public void execute() { stereo.off(); } @Override public void undo() { stereo.setCd(); stereo.setVolume(11); stereo.on(); } } |
4.7 StereoOnWithCDCommand.java
|
package com.gof.pattern.command; /** * 打开音响 * @author Administrator * */ public class StereoOnWithCDCommand implements ICommand { private Stereostereo; public StereoOnWithCDCommand(Stereo stereo){ this.stereo = stereo; } @Override public void execute() { stereo.setCd(); stereo.setVolume(11); stereo.on(); } @Override public void undo() { stereo.off(); } } |
4.8 GarageDoor.java
|
package com.gof.pattern.command; /** * 车库实体类 * @author Administrator * */ public class GarageDoor { private Stringname; public GarageDoor(String name){ this.name = name; } public void up(){ System.out.println(name +" is up!"); } public void down(){ System.out.println(name +" is down!"); } } |
4.9 GarageDoorUpCommand.java
|
package com.gof.pattern.command; /** * 车库门升起 * @author Administrator */ public class GarageDoorUpCommand implements ICommand { private GarageDoorgarageDoor; public GarageDoorUpCommand(GarageDoor garageDoor){ this.garageDoor = garageDoor; } @Override public void execute() { garageDoor.up(); } @Override public void undo() { garageDoor.down(); } } |
4.10 GarageDoorDownCommand.java
|
package com.gof.pattern.command; /** * 车库们落下 * @author Administrator */ public class GarageDoorDownCommand implements ICommand { private GarageDoorgarageDoor; public GarageDoorDownCommand(GarageDoor garageDoor){ this.garageDoor = garageDoor; } @Override public void execute() { garageDoor.down(); } @Override public void undo() { garageDoor.up(); } } |
4.11 NoCommand.java
|
package com.gof.pattern.command; /** * 空命令 * @author Administrator * */ public class NoCommand implements ICommand { @Override public void execute() {} @Override public void undo() {} } |
4.12 RemoteControl.java
|
package com.gof.pattern.command; /** * 遥控器 * @author Administrator */ public class RemoteControl { private ICommand[]onCommands; private ICommand[]offCommands; private ICommandundoCommand; // 初始化遥控器按钮功能 public RemoteControl(){ onCommands = new ICommand[7]; offCommands = new ICommand[7]; ICommand noCommand = new NoCommand(); for(int i=0; i<7; i++){ onCommands[i] = noCommand; offCommands[i] = noCommand; } undoCommand = noCommand; } public void setCommand(int slot, ICommand onCommand, ICommand offCommand){ onCommands[slot] = onCommand; undoCommand.undo(); offCommands[slot] = offCommand; } // 按某个位置,on按钮 public void onButtonWasPushed(int solt){ onCommands[solt].execute(); undoCommand = onCommands[solt]; } // 按某个位置,off按钮 public void offButtonWasPushed(int solt){ offCommands[solt].execute(); undoCommand = offCommands[solt]; } // 按undo按钮 public void undoButtonWasPushed(){ } @Override public String toString(){ StringBuffer stringBuff = new StringBuffer(); stringBuff.append("\n------ Remote Control ------\n"); for(int i=0; i<onCommands.length; i++){ stringBuff.append("[solt "+ i +"]" +onCommands[i].getClass().getName() + " " +offCommands[i].getClass().getName() +"\n"); } return stringBuff.toString(); } } |
4.13 RemoteLoader.java 遥控器测试类
|
package com.gof.pattern.command; public class RemoteLoader { public static void main(String[] args) { // 创建一个遥控器 RemoteControl remoteControl = new RemoteControl(); // 将所有装置创建在合适位置 Light livingRoomLight = new Light("Living Room"); Light kitchenLight = new Light("Kitchen"); GarageDoor garageDoor = new GarageDoor(""); Stereo stereo = new Stereo("Living Room"); // 创建所有电灯命令对象 ICommand livingRoomLightOn = new LightOnCommand(livingRoomLight); ICommand livingRoomLightOff = new LightOffCommand(livingRoomLight); ICommand kitchenLightOn = new LightOnCommand(kitchenLight); ICommand kigcchenLightOff = newLightOffCommand(kitchenLight); // 创建车库门上下命令对象 ICommand garageDoorUp = new GarageDoorUpCommand(garageDoor); ICommand garageDoorDown = new GarageDoorDownCommand(garageDoor); // 创建音响开关命令对象 ICommand stereoOnWithCDCommand = new StereoOnWithCDCommand(stereo); ICommand stereoOffWithCdCommand = new StereoOffWithCDCommand(stereo); // 为遥控器某个位置设置命令 remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); remoteControl.setCommand(1, kitchenLightOn, kigcchenLightOff); remoteControl.setCommand(2, garageDoorUp, garageDoorDown); remoteControl.setCommand(3, stereoOnWithCDCommand, stereoOffWithCdCommand); System.out.println(remoteControl); 开关按钮测试 remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); remoteControl.onButtonWasPushed(1); remoteControl.offButtonWasPushed(1); remoteControl.onButtonWasPushed(2); remoteControl.offButtonWasPushed(2); remoteControl.onButtonWasPushed(3); remoteControl.offButtonWasPushed(3); remoteControl.undoButtonWasPushed(); } } |
5 命令模式总结
5.1 优点
降低了决策逻辑的复杂性
提供了可扩展能力
能够方便地提供撤销操作
能够将多个命令放在一个队列中
能够在不同的线程或远程执行命令
5.2 缺点
在对象的创建、销毁及使用过程中可能会增加系统开销
使应用程序的结构更加复杂
5.3 指导原则
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间松耦合设计而努力
类应该对扩展开发,对修改关闭
依赖抽象,不依赖具体类
|
命令模式:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志请求来参数化其它对象。命令模式也可以支持撤销操作。 |
Java设计模式 之 命令模式的更多相关文章
- 折腾Java设计模式之命令模式
博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...
- JAVA设计模式之 命令模式【Command Pattern】
一.概述 命令模式能够将请求发送者和接收者全然解耦.发送者与接收者之间没有直接引用关系,发送请求的对象仅仅须要知道怎样发送请求,而不必知道怎样完毕请求.核心在于引入了命令类,通过命令类来减少发送者和接 ...
- 14.java设计模式之命令模式
基本需求: 一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装app就可以控制对这些家电工作 这些智能家电来自不同的厂家,我们不想针对每一种家电都安装一个App分别控制,我们希望只要一个 ...
- java设计模式之命令模式
学校中.生活中.社会中总是会存在一定的阶层,虽然我们很多人都不可认可阶层的存在.命令这一词也就在阶层中诞生.家长命令孩子,老师命令学生,领导命令小娄娄.这些都在我们的生活存在的东西,相信这一个模式学习 ...
- java设计模式之命令模式以及在java中作用
命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请 ...
- 玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式
目录 示例 改进代码 命令模式 定义 意图 主要解决问题 何时使用 优缺点 玉帝传美猴王上天 命令模式和策略模式的区别 示例 系统需要设计一个命令行界面,用户可输入命令来执行某项功能,系统的功能会不断 ...
- 用Java 8 Lambda表达式实现设计模式:命令模式
在这篇博客里,我将说明如何在使用 Java 8 Lambda表达式 的函数式编程方式 时实现 命令 设计模式 .命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化 ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- Java设计模式——装饰者模式
JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...
随机推荐
- Yocto开发笔记之《根文件系统裁剪》(QQ交流群:519230208)
开了一个交流群,欢迎爱好者和开发者一起交流,转载请注明出处. QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 =============================== ...
- IIS------Http错误:50019,由于权限不足无法读取配置文件
转载: http://niutuku.com/tech/2008/273661.shtml 注意:该用户名称必须是:Everyone
- HIbernate的写法总结
普通表操作 普通操作莫过于CRUD,建好表了之后对表的数据进行操作.详见代码. package package2; import org.hibernate.Session; import org.h ...
- 编译安装redis
一.版本说明 CentOS版本 [root@localhost ~]# uname Linux [root@localhost ~]# uname -r 2.6.32-431.el6.i686 [ro ...
- vim的使用
vim的定位 home:光标移到行首 end:光标移到行尾 pageup:屏幕上翻页 pagedow:屏幕下翻页 shift+g:定位行 如转至10行 10shift+g shift+gg 转至 ...
- ecshop 团购-》调取评论
涉及到的文件及代码:lib_insert.php,comments.lbi,{insert name='comments' type=$type id=$id} html代码: <blockqu ...
- Hive部署
前置环境:CentOS 6.5 + JDK 1.7 + Hadoop 2.6 注:此处采用伪分布安装Hadoop,平时测试使用,Hive的元数据信息使用MySQL存储 一.安装MySQL 1.检查是否 ...
- MongoDB创建数据库和集合命令db.createCollection详解(转)
切换/创建数据库 use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库 完整的命令如下:db.createCollection(name, {capped: <Boo ...
- Android Studio-开启Preview视图
Preview视图会在切换"Design"和"Text"视图的时候自动显示,可在右侧工具栏开启: 今天无意中关闭了,找了半天,原来可以在这个地方再次开启:
- android-android获取navigationview 上的控件id
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); View headerView = navi ...