command explained. intent encapsulate a request as an object, thereby letting you parameterize...

33
Command Explained

Upload: dwight-nash

Post on 16-Dec-2015

218 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Command

Explained

Page 2: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Intent• Encapsulate a request as an object, thereby letting you

parameterize clients with different requests, queue or log requests, and support undoable operations.

• Behavioral Pattern• A command object encapsulates a request by binding together a set

of actions on a specific receiver.• When two objects communicate, often one object is sending a

command to the other object to perform a particular function. The most common way to accomplish this is for the first object (the “issuer”) to hold a reference to the second (the “recipient”). The issuer executes a specific method on the recipient to send the command.

• An object-oriented callback.

Page 3: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation

• Sometimes it's necessary to issue requests to objects without knowing anything about the operation being requested or the receiver of the request. For example, user interface toolkits include objects like buttons and menus that carry out a request in response to user input.

• But the toolkit can't implement the request explicitly in the button or menu, because only applications that use the toolkit know what should be done on which object.

• As toolkit designers we have no way of knowing the receiver of the request or the operations that will carry it out

Page 4: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation

• The Command pattern lets toolkit objects make requests of unspecified application objects by turning the request itself into an object.

• This object can be stored and passed around like other objects. The key to this pattern is an abstract Command class, which declares an interface for executing operations. In the simplest form this interface includes an abstract Execute operation.

• Concrete Command subclasses specify a receiver-action pair by storing the receiver as an instance variable and by implementing Execute to invoke the request.

• The receiver has the knowledge required to carry out the request

Page 5: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation

• Menus can be implemented easily with Command objects. Each choice in a Menu is an instance of a Menu Item class. An Application class creates these menus and their menu items along with the rest of the user interface. The Application class also keeps track of Document objects that a user has opened

Page 6: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation

• The application configures each Menu Item with an instance of a concrete Command subclass.

• When the user selects a Menu Item, the Menu Item calls Execute on its command, and Execute carries out the operation. Menu Items don't know which subclass of Command they use.

• Command subclasses store the receiver of the request and invoke one or more operations on the receiver

Page 7: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation

• For example, PasteCommand supports pasting text from the clipboard into a Document. PasteCommand's receiver is the Document object, it is supplied upon instantiation.

• The Execute operation invokes Paste on the receiving Document

Page 8: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation

• OpenCommand's Execute operation is different: it prompts the user for a document name, creates a corresponding Document object, adds the document to the receiving application, and opens the document

Page 9: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation• Sometimes a MenuItem needs to execute a sequence of commands. For example, a

MenuItem for centering a page at normal size could be constructed from a CenterDocumentCommand object and a NormalSizeCommand object. Because it's common to string commands together in this way, we can define a MacroCommand class to allow a MenuItem to execute an open-ended number of commands. MacroCommand is a concrete Command subclass that simply executes a sequence of Commands. MacroCommand has no explicit receiver, because the commands it sequences define their own receiver

Page 10: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Motivation• In each of these examples, notice how the command pattern

decouples the object that invokes the operation from the one having the knowledge to perform it. This gives us a lot of flexibility in designing our user interface.

• An application can provide both a menu and a push button interface to a feature just by making the menu and the push button share an instance of the same concrete Command subclass

• We can replace commands dynamically, which would be useful for implementing context-sensitive menus. We can also support command scripting by composing commands into larger ones. All of this is possible because the object that issues a request only needs to know how to issue it; it doesn't need to know how the request will be carried out

Page 11: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Applicability

Use Command pattern when you want to• Parameterize objects by an action to perform, as

MenuItem objects did above. You can express such parameterization in a procedural language with a callback function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks

• Specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request.

Page 12: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Applicability• Support undo. The Command's Execute operation can store state

for reversing its effects in the command itself. The Command interface must have an added Unexecute operation that reverses the effects of a previous call to Execute. Executed commands are stored in a history list. Unlimited-level undo and redo is achieved by traversing this list backwards and forwards calling Unexecute and Execute, respectively.

• Support logging changes so that they can be reapplied in case of a system crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash involves reloading logged commands from disk and re-executing them with the Execute operation

Page 13: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Structure

Page 14: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Participants• Command

– declares an interface for executing an operation• Concrete Command (PasteCommand, OpenCommand)

– defines a binding between a Receiver object and an action– implements Execute by invoking the corresponding operation(s) on

Receiver• Client (Application)

– creates a ConcreteCommand object and sets its receiver• Invoker (MenuItem)

– asks the command to carry out the request• Receiver (Document, Application)

– knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver

Page 15: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Collaborations• Command declares an interface for all commands, providing a

simple execute() method which asks the Receiver of the command to carry out an operation.

• The Receiver has the knowledge of what to do to carry out the request.

• The Invoker holds a command and can get the Command to execute a request by calling the execute method.

• The Client creates ConcreteCommands and sets a Receiver for the command.

• The ConcreteCommand defines a binding between the action and the receiver. When the Invoker calls execute the ConcreteCommand will run one or more actions on the Receiver.

Page 16: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Collaborations

Page 17: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Consequences

• The Command pattern has the following consequences:1. Command decouples the object that invokes the

operation from the one that knows how to perform it.

2. Commands are first-class objects. They can be manipulated and extended like any other object.

3. It's easy to add new Commands, because you don't have to change existing classes.

Page 18: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Understanding Command Pattern through the Diner Example

Burger & Shake

Order

takeOrder

orderUpMakeBurger &Shake

createOrder()

takeOrder()

orderUp()

make_X()

Page 19: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

How it works

• Customer know what he wants and creates an order

• Order consists of an order slip and the customer’s menu items that are written on it.

• The waiter takes the order and when he gets around it he calls orderup() to begin the order preparation

• Short order cook takes the order and prepares the meal according to the knowledge he has.

Page 20: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Example: Home Automation Remote

Problem Statement• Build a remote that will control variety of

home devices• Sample devices: lights, stereo, TV, ceiling light,

thermostat, sprinkler, hot tub, garden light, ceiling fan, garage door

Page 21: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

The Vendor Classes

Page 22: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Command Pattern Applied to Home Automation

action()

execute(){ receiver.action()}

execute()

execute()

execute()

An encapsulated Request

Invoker

Page 23: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Class Diagram

RemoteLoader/Client

RemoteControl/Invoker

onCommandsoffCommandssetCommand()onButtonPushed()offButtonPushed()

<<Interface>>Command

execute()undo()

Light/Receiver

on()off()

LightOnCommand

execute()undo()

LightOffCommand

execute()undo()

Page 24: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Command Interface

• All command objects implement the same interface which consists of one method. In the diner example it was the orderUp() method. Here we can use executepublic interface ICommand { //All we need is one method Execute() void Execute(); }

Page 25: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Concrete commands• Now its time to create the actual commands• We can create the commands for the Light object. The vendor classes give us the

detail about how to turn the light on and how to turn it off.public class Light { private string _DescLight = "Light"; public string DescLight { get { return _DescLight; } set { _DescLight = value; } } public Light(string place) { this._DescLight = place; } public void On()//Turning the Light on { System.Console.WriteLine(this.DescLight + " is ON."); } public void Off()//Turning the Light off { System.Console.WriteLine(this.DescLight + " is OFF."); } }

Page 26: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Concrete Commandspublic class LightOnCommand : ICommand { Light lg;

//The constructor is passed the specific light like Living room public LightOnCommand(Light my) { this.lg = my; } public void Execute() { this.lg.On(); } }

Page 27: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Concrete Commands

public class LightOffCommand : ICommand { Light lg; public LightOffCommand(Light my) { this.lg = my; } public void Execute() { this.lg.Off(); } }

Page 28: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Null Command

public class NoCommand : ICommand { public void Execute() { System.Console.WriteLine("No command"); } }

• The NoCommand is a Null object. The Null object is useful when you don’t have a meaningful object to return and yet you want to remove the responsibility of handling null, from the client.

Page 29: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Remote Controlpublic class RemoteControl //The Invoker { ICommand[] onCommands; //Array to store On commands ICommand[] offCommands;//Array to store Off commands public RemoteControl() {//Instantiating and initializing the Arrays in the constructor this.onCommands = new ICommand[7]; this.offCommands = new ICommand[7]; for (int i = 0; i < 7; i++) { this.onCommands[i] = new NoCommand(); this.offCommands[i] = new NoCommand(); } }

Page 30: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Setting up the Commandspublic void stCommand(int slot, ICommand on, ICommand off) {//This function sets the commands to take a slot position in the on and

//off arrays this.onCommands[slot] = on; this.offCommands[slot] = off; } public void onButtonPushed(int slot) {//On Button on the remote for a particular slot this.onCommands[slot].Execute(); } public void offButtonPushed(int slot) {//Off Button on the remote for a particular slot this.offCommands[slot].Execute(); } }

Page 31: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Client Class or Remote Loaderclass Program{ static void Main(string[] args) { RemoteControl remote = new RemoteControl();//Remote Control Object Light LivingRoomLight = new Light("Living Room");//Living Room Light Light KichenLight = new Light("Kichen");//Kichen Light

//Command Objects LightOnCommand LivingRoomLightOn = new LightOnCommand(LivingRoomLight); LightOnCommand KichenLightOn = new LightOnCommand(KichenLight); LightOffCommand LivingRoomLightOff = new LightOffCommand(LivingRoomLight); LightOffCommand KichenLightOff = new LightOffCommand(KichenLight);

//Setting Up Commands remote.stCommand(0, LivingRoomLightOn, LivingRoomLightOff); //Executing Commands

remote.onButtonPushed(0); remote.offButtonPushed(0); Console.ReadLine(); } }

Page 32: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Outputs

Page 33: Command Explained. Intent Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests,

Assignment # 2• Make a group of 3 people• Extend the above code and work out to design a full Remote

Control for home automation with following aspects– Friendly GUI for easy access to all the remote control functions– All the Vendor classes mentioned in this lecture should be included

in the scope.– The on and off functions could be shown graphically or with the

help of messages– Create an Undo Command button on the remote to undo current

command and go back to previous command’s results.• This assignment would be due on 01 Jan 2014. The teams

would have to show the outputs to the whole class in form of a presentation containing program output