设计模式--命令模式
时间:2022-07-24
本文章向大家介绍设计模式--命令模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
家电自动化遥控器API项目
传统设计方案
package com.java.jikexueyuan.commandmode.device;
//电灯
public class Light {
//电灯的位置
String loc = "";
public Light(String loc) {
this.loc = loc;
}
//开灯
public void On() {
System.out.println(loc + " On");
}
//关灯
public void Off() {
System.out.println(loc + " Off");
}
}
package com.java.jikexueyuan.commandmode.device;
//音响
public class Stereo {
static int volume = 0;
//开
public void On() {
System.out.println("Stereo On");
}
//关
public void Off() {
System.out.println("Stereo Off");
}
//选歌曲
public void SetCd() {
System.out.println("Stereo SetCd");
}
//设置音量
public void SetVol(int vol) {
volume = vol;
System.out.println("Stereo volume=" + volume);
}
//查看音量
public int GetVol() {
return volume;
}
//开始播放
public void Start() {
System.out.println("Stereo Start");
}
}
package com.java.jikexueyuan.commandmode;
//遥控器
public interface Control {
//开机按钮
public void onButton(int slot);
//关机按钮
public void offButton(int slot);
public void undoButton();
}
package com.java.jikexueyuan.commandmode;
import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
//遥控器实现类
public class TraditionControl implements Control {
Light light;
Stereo stereo;
public TraditionControl(Light light, Stereo stereo) {
this.light = light;
this.stereo = stereo;
}
@Override
public void onButton(int slot) {
// TODO Auto-generated method stub
switch (slot) {
case 0:
light.On();
break;
case 1:
stereo.On();
break;
case 2:
int vol = stereo.GetVol();
if (vol < 11) {
stereo.SetVol(++vol);
}
break;
}
}
@Override
public void offButton(int slot) {
// TODO Auto-generated method stub
switch (slot) {
case 0:
light.Off();
break;
case 1:
stereo.Off();
break;
case 2:
int vol = stereo.GetVol();
if (vol > 0) {
stereo.SetVol(--vol);
}
break;
}
}
@Override
public void undoButton() {
// TODO Auto-generated method stub
}
}
package com.java.jikexueyuan.commandmode;
import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
//使用遥控器
public class ControlTest {
public static void main(String[] args) {
Control ctl;
Light light = new Light("Bedroom");
Stereo stereo = new Stereo();
ctl = new TraditionControl(light, stereo);
ctl.onButton(0);
ctl.offButton(0);
ctl.onButton(1);
ctl.onButton(2);
ctl.offButton(2);
ctl.offButton(1);
}
}
命令模式:将请求、命令、动作等封装成对象,这样可以让项目使用这些对象来参数化其他对象。使得命令的请求者和执行者解耦
重新设计如下
package com.java.jikexueyuan.commandmode.command;
//所有命令的接口
public interface Command {
public void execute();
public void undo();
}
package com.java.jikexueyuan.commandmode.command;
import com.java.jikexueyuan.commandmode.device.Light;
//开灯
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light)
{
this.light=light;
}
@Override
public void execute() {
// TODO Auto-generated method stub
light.On();
}
@Override
public void undo() {
// TODO Auto-generated method stub
light.Off();
}
}
package com.java.jikexueyuan.commandmode.command;
import com.java.jikexueyuan.commandmode.device.Light;
//关灯
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light)
{
this.light=light;
}
@Override
public void execute() {
// TODO Auto-generated method stub
light.Off();
}
@Override
public void undo() {
// TODO Auto-generated method stub
light.On();
}
}
package com.java.jikexueyuan.commandmode.command;
import com.java.jikexueyuan.commandmode.device.Stereo;
//打开音响,并选择歌曲
public class StereoOnCommand implements Command {
private Stereo setreo;
public StereoOnCommand(Stereo setreo)
{
this.setreo=setreo;
}
@Override
public void execute() {
// TODO Auto-generated method stub
setreo.On();
setreo.SetCd();
}
@Override
public void undo() {
// TODO Auto-generated method stub
setreo.Off();
}
}
package com.java.jikexueyuan.commandmode.command;
//空指令
public class NoCommand implements Command {
@Override
public void execute() {
// TODO Auto-generated method stub
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
package com.java.jikexueyuan.commandmode.command;
import java.util.Stack;
import com.java.jikexueyuan.commandmode.Control;
import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
//遥控器实现类
public class CommandModeControl implements Control{
private Command[] onCommands;
private Command[] offCommands;
//使用栈 设置回退
private Stack<Command> stack=new Stack<Command>();
public CommandModeControl()
{
//假设左右各5个按钮
onCommands=new Command[5];
offCommands=new Command[5];
Command noCommand=new NoCommand();
for(int i=0,len=onCommands.length;i<len;i++)
{
//初始化按钮为未设置命令
onCommands[i]=noCommand;
offCommands[i]=noCommand;
}
}
//为指定按钮设置命令
public void setCommand(int slot,Command onCommand,Command offCommand)
{
onCommands[slot]=onCommand;
offCommands[slot]=offCommand;
}
//点击on按钮
@Override
public void onButton(int slot) {
onCommands[slot].execute();
stack.push(onCommands[slot]);
}
//点击off按钮
@Override
public void offButton(int slot) {
offCommands[slot].execute();
stack.push(offCommands[slot]);
}
@Override
public void undoButton() {
// TODO Auto-generated method stub
//返回在这个堆栈的顶部的对象--最后一次操作的对象
stack.pop().undo();
}
}
package com.java.jikexueyuan.commandmode.command;
//宏命令
public class MarcoCommand implements Command {
private Command[] commands;
//初始化多个命令给宏命令
public MarcoCommand(Command[] commands) {
this.commands = commands;
}
@Override
public void execute() {//执行时把所有初始化的命令全部执行
// TODO Auto-generated method stub
for (int i = 0, len = commands.length; i < len; i++) {
commands[i].execute();
}
}
@Override
public void undo() {
// TODO Auto-generated method stub
for (int i = commands.length - 1; i >= 0; i--) {
commands[i].undo();
}
}
}
package com.java.jikexueyuan.commandmode.command;
import com.java.jikexueyuan.commandmode.Control;
import com.java.jikexueyuan.commandmode.TraditionControl;
import com.java.jikexueyuan.commandmode.device.Light;
import com.java.jikexueyuan.commandmode.device.Stereo;
public class ControlTest {
//按钮设置和点击演示
public static void main(String[] args) {
CommandModeControl control = new CommandModeControl();
MarcoCommand onmarco,offmarco;
Light bedroomlight = new Light("BedRoom");
Light kitchlight = new Light("Kitch");
Stereo stereo = new Stereo();
LightOnCommand bedroomlighton = new LightOnCommand(bedroomlight);
LightOffCommand bedroomlightoff = new LightOffCommand(bedroomlight);
LightOnCommand kitchlighton = new LightOnCommand(kitchlight);
LightOffCommand kitchlightoff = new LightOffCommand(kitchlight);
Command[] oncommands={bedroomlighton,kitchlighton};
Command[] offcommands={bedroomlightoff,kitchlightoff};
onmarco=new MarcoCommand(oncommands);
offmarco=new MarcoCommand(offcommands);
StereoOnCommand stereoOn = new StereoOnCommand(stereo);
StereoOffCommand stereoOff = new StereoOffCommand(stereo);
StereoAddVolCommand stereoaddvol = new StereoAddVolCommand(stereo);
StereoSubVolCommand stereosubvol = new StereoSubVolCommand(stereo);
control.setCommand(0, bedroomlighton, bedroomlightoff);
control.setCommand(1, kitchlighton, kitchlightoff);
control.setCommand(2, stereoOn, stereoOff);
control.setCommand(3, stereoaddvol, stereosubvol);
control.setCommand(4, onmarco, offmarco);
control.onButton(0);
control.undoButton();
//control.offButton(0);
control.onButton(1);
control.offButton(1);
control.onButton(2);
control.onButton(3);
control.offButton(3);
control.undoButton();
control.offButton(2);
control.undoButton();
control.onButton(4);
control.offButton(4);
}
}
- 用Python的长短期记忆神经网络进行时间序列预测
- 【问底】许鹏:使用Spark+Cassandra打造高性能数据分析平台(一)
- 隐秘通讯与跳板?C&C服务器究竟是怎么一回事
- 灵活布置、可二次开发的乌云公开漏洞及知识库搜索
- 干货 | 2014年我国大数据发展分析报告
- 这个恶意软件“奇葩”的反虚拟机技巧
- Android漏洞CVE-2015-3825分析及exploit实战:从Crash到劫持PC
- VaultPasswordView:可用于查看windows Vault密码的工具
- 逆向工厂(二):静态分析技术
- 打开文件夹就运行?COM劫持利用新姿势
- Java集合总览
- 常见面试题之ListView的复用及如何优化
- 自定义圆形控件RoundImageView并认识一下attr.xml
- 自定义带图片和文字的ImageTextButton
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- java编程思想第四版第八章习题
- java编程思想第四版第八章总结
- ESP32从网络获取天气OLED显示(附源码)
- 02 . Zabbix配置监控项及聚合图形
- 01 . GitLab简介及环境部署
- 03 . Prometheus监控容器和HTTP探针应用及服务发现
- java编程思想第四版第九章习题
- 03 . Django之腾讯云短信
- ESP32 MQTT连接到中移OneNET物联网平台(附源码)
- 01 . Docker原理部署及常用操作命令
- SSH原理常见应用升级及端口转发
- 01 . Linux常用命令
- 私人订制属于自己的Linux系统
- 04 . Docker安全与Docker底层实现
- 03 . Docker数据资源管理与网络