zoukankan      html  css  js  c++  java
  • 《Head First 设计模式》学习笔记——命令模式

    在软件系统,“行为请求者”与“行为实施者”通常存在一个“紧耦合”。但在某些场合,比方要对行为进行“记录、撤销/重做、事务”等处理,这样的无法抵御变化的紧耦合是不合适的。在这样的情况下。怎样将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象实现二者之间的松耦合。这就是命令模式(Command Pattern)————题记

    设计模式
    命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来參数化其它对象。

    命令模式也支持可撤销的操作。


    模式分析
    1. 命令模式的本质是对命令进行封装,将发出命令的责任和运行命令的责任切割开
    2. 每个命令都是一个操作:请求的一方发出请求,要求运行一个操作;接收的一方收到请求,并运行操作
    3. 命令模式同意请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被运行、何时被运行,以及是怎么被运行的。
    4. 命令模式使请求本身成为一个对象,这个对象和其它对象一样能够被存储和传递。
    5. 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,仅仅有实现了抽象命令接口的详细命令才干与接收者相关联

    // Invoker:要求命令对象运行请求,一般会持有命令对象,能够持有非常多的命令对象。这个是client真正触发命令并要求命令运行对应操作的地方,也就是说相当于使用命令对象的入口。
    public class RemoteControl {
    	//这时候。遥控器要处理7个开与关的命令,使用对应数组记录这些命令
    	Command[] onCommands;
    	Command[] offCommands;
     
    	public RemoteControl() {
    		//在构造器中。仅仅须要实例化并初始化两个开与关的数组
    		onCommands = new Command[7];
    		offCommands = new Command[7];
    		//NoCommand对象是一个空对象(null obeject)的样例。当你不想返回一个有意义的对象时,空对象就非常实用,客户也能够将处理null的责任转义给空对象。

    //举例来说。遥控器不可能一出厂就设置了有意义的命令对象,所以提供了NoCommand对象作为替代品。当调用它的execute() //方法时。这样的对象什么也不做。 Command noCommand = new NoCommand(); for (int i = 0; i < 7; i++) { onCommands[i] = noCommand; offCommands[i] = noCommand; } } //setCommand()方法须有三个參数,各自是插槽的位置、开的命令、关的命令。 public void setCommand(int slot, Command onCommand, Command offCommand) { onCommands[slot] = onCommand; offCommands[slot] = offCommand; } //当按下开或关的button。硬件就会负责调用对应的方法 public void onButtonWasPushed(int slot) { onCommands[slot].execute(); } public void offButtonWasPushed(int slot) { offCommands[slot].execute(); } //覆盖toString(),打印出每一个插槽和它对应的命令。 public String toString() { StringBuffer stringBuff = new StringBuffer(); stringBuff.append(" ------ Remote Control ------- "); for (int i = 0; i < onCommands.length; i++) { stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName() + " " + offCommands[i].getClass().getName() + " "); } return stringBuff.toString(); } } //定义命令的接口。声明运行的方法。 public interface Command { public void execute(); } //命令接口实现对象,是“虚”的实现。一般会持有接收者,并调用接收者的功能来完毕命令要运行的操作。 public class StereoOnWithCDCommand implements Command { Stereo stereo; public StereoOnWithCDCommand(Stereo stereo) { this.stereo = stereo; } public void execute() { stereo.on(); stereo.setCD(); stereo.setVolume(11); } } //接收者,真正运行命令的对象。

    不论什么类都可能成为一个接收者。仅仅要它能够实现命令要求实现的对应功能。 public class Stereo { String location; public Stereo(String location) { this.location = location; } public void on() { System.out.println(location + " stereo is on"); } public void off() { System.out.println(location + " stereo is off"); } public void setCD() { System.out.println(location + " stereo is set for CD input"); } public void setDVD() { System.out.println(location + " stereo is set for DVD input"); } public void setRadio() { System.out.println(location + " stereo is set for Radio"); } public void setVolume(int volume) { // code to set the volume // valid range: 1-11 (after all 11 is better than 10, right?) System.out.println(location + " Stereo volume set to " + volume); } } //測试 public class RemoteLoader { public static void main(String[] args) { RemoteControl remoteControl = new RemoteControl(); //将所有的装置创建在合适的位置 Light livingRoomLight = new Light("Living Room"); Light kitchenLight = new Light("Kitchen"); CeilingFan ceilingFan= new CeilingFan("Living Room"); GarageDoor garageDoor = new GarageDoor(""); Stereo stereo = new Stereo("Living Room"); LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight); LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight); CeilingFanOnCommand ceilingFanOn = new CeilingFanOnCommand(ceilingFan); CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan); GarageDoorUpCommand garageDoorUp = new GarageDoorUpCommand(garageDoor); GarageDoorDownCommand garageDoorDown = new GarageDoorDownCommand(garageDoor); StereoOnWithCDCommand stereoOnWithCD = new StereoOnWithCDCommand(stereo); StereoOffCommand stereoOff = new StereoOffCommand(stereo); //如今已经有了所有的命令。能够将他们载入到遥控器插槽中。 remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff); remoteControl.setCommand(2, ceilingFanOn, ceilingFanOff); remoteControl.setCommand(3, stereoOnWithCD, stereoOff); //在这里,使用toString()方法打印出每一个遥控器的插槽和它被指定的命令 System.out.println(remoteControl); //一切就绪,逐步按下每一个插槽的开与关button。

    remoteControl.onButtonWasPushed(0); remoteControl.offButtonWasPushed(0); remoteControl.onButtonWasPushed(1); remoteControl.offButtonWasPushed(1); remoteControl.onButtonWasPushed(2); remoteControl.offButtonWasPushed(2); remoteControl.onButtonWasPushed(3); remoteControl.offButtonWasPushed(3); } }




    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    网上流行的学生选课相关的50个常用sql语句
    the interview questions of sql server
    ASP.NET 之 Chart Control for .Net Framework
    SQL Server之纵表与横表互转
    ASP.NET控件之RadioButtonList
    SQL Server通过钉钉机器人直接发送消息
    使用AMO对象,更改款属性名称
    常用MDX函数
    Excel 插入图片
    Sql Server 2008查询数据库中各表记录行数
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4878240.html
Copyright © 2011-2022 走看看