?? pat5b.htm
字號:
<HTML><HEAD><TITLE>Command</TITLE><SCRIPT>function setFocus() { if ((navigator.appName != "Netscape") && (parseFloat(navigator.appVersion) == 2)) { return; } else { self.focus(); }}</SCRIPT></HEAD><BODY BGCOLOR = #FFFFFFonLoad="setFocus()";><A NAME="top"></A><A NAME="Command"></A><A NAME="intent"></A><H2><A HREF="#alsoknownas"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Also Known As"></A> Intent</H2> <A NAME="auto1000"></A><P>Encapsulate a request as an object, thereby letting you parameterizeclients with different requests, queue or log requests, and supportundoable operations.</P><A NAME="alsoknownas"><A><H2><A HREF="#motivation"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Motivation"></A> Also Known As</H2> <A NAME="auto1001"></A><P>Action, Transaction</P><A NAME="motivation"></A><H2><A HREF="#applicability"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Applicability"></A> Motivation</H2> <A NAME="auto1002"></A><P>Sometimes it's necessary to issue requests to objects without knowinganything about the operation being requested or the receiver of therequest. For example, user interface toolkits include objects likebuttons and menus that carry out a request in response to user input.But the toolkit can't implement the request explicitly in the buttonor menu, because only applications that use the toolkit know whatshould be done on which object. As toolkit designers we have no wayof knowing the receiver of the request or the operations that willcarry it out.</P><A NAME="toolkit2"></A><P>The Command pattern lets toolkit objects make requests of unspecifiedapplication objects by turning the request itself into an object. Thisobject can be stored and passed around like other objects. The key tothis pattern is an abstract Command class, which declares an interfacefor executing operations. In the simplest form this interfaceincludes an abstract Execute operation. Concrete Command subclassesspecify a receiver-action pair by storing the receiver as an instancevariable and by implementing Execute to invoke the request. Thereceiver has the knowledge required to carry out the request.</P><A NAME="233c"></A><P ALIGN=CENTER><IMG SRC="Pictures/comma081.gif"></P><A NAME="document-234"></A><P>Menus can be implemented easily with Command objects. Each choice ina Menu is an instance of a MenuItem class. An Application class createsthese 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 hasopened.</P><A NAME="auto1003"></A><P>The application configures each MenuItem with an instance of aconcrete Command subclass. When the user selects a MenuItem, theMenuItem calls Execute on its command, and Execute carries out theoperation. MenuItems don't know which subclass of Command they use.Command subclasses store the receiver of the request and invoke one ormore operations on the receiver.</P><A NAME="auto1004"></A><P>For example, PasteCommand supports pasting text from the clipboardinto a Document. PasteCommand's receiver is the Document object it issupplied upon instantiation. The Execute operation invokes Paste onthe receiving Document.</P><A NAME="234c"></A><P ALIGN=CENTER><IMG SRC="Pictures/comma078.gif"></P><A NAME="auto1005"></A><P>OpenCommand's Execute operation is different: it prompts the userfor a document name, creates a corresponding Document object, adds thedocument to the receiving application, and opens the document.</P><P ALIGN=CENTER><IMG SRC="Pictures/comma079.gif"><A NAME="macrocommand"></A><A NAME="sequence-request"></A><P>Sometimes a MenuItem needs to execute a <EM>sequence</EM> of commands.For example, a MenuItem for centering a page at normal size could beconstructed from a CenterDocumentCommand object and aNormalSizeCommand object. Because it's common to string commandstogether in this way, we can define a MacroCommand class to allow aMenuItem to execute an open-ended number of commands. MacroCommand isa concrete Command subclass that simply executes a sequence ofCommands. MacroCommand has no explicit receiver, because the commandsit sequences define their own receiver.</P><A NAME="command-eg-macro"></A><P ALIGN=CENTER><IMG SRC="Pictures/comma080.gif"></P><A NAME="auto1006"></A><P>In each of these examples, notice how the Command pattern decouplesthe object that invokes the operation from the one having theknowledge to perform it. This gives us a lot of flexibility indesigning our user interface. An application can provide both a menuand a push button interface to a feature just by making the menu andthe push button share an instance of the same concrete Command subclass.We can replace commands dynamically, which would be useful forimplementing context-sensitive menus. We can also support commandscripting by composing commands into larger ones. All of this ispossible because the object that issues a request only needs to knowhow to issue it; it doesn't need to know how the request will be carried out.</P><A NAME="applicability"></A><H2><A HREF="#structure"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Structure"></A> Applicability</H2> <A NAME="auto1007"></A><P>Use the Command pattern when you want to</P><UL><A NAME="auto1008"></A><LI> parameterize objects by an action to perform, as MenuItem objects did above. You can express such parameterization in a procedural language with a <STRONG>callback</STRONG> function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks.</LI><A NAME="auto1009"></A><P></P><A NAME="request-sequence"></A><LI> specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there.</LI><A NAME="auto1010"></A><P></P><A NAME="support-undo"></A><LI> 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.</LI><A NAME="auto1011"></A><P></P><A NAME="auto1012"></A><LI> 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 reexecuting them with the Execute operation.</LI><A NAME="auto1013"></A><P></P><A NAME="def-transaction"></A><LI> structure a system around high-level operations built on primitives operations. Such a structure is common in information systems that support <STRONG>transactions</STRONG>. A transaction encapsulates a set of changes to data. The Command pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also makes it easy to extend the system with new transactions.</LI></UL><A NAME="structure"></A><H2><A HREF="#participants"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Participants"></A> Structure</H2> <P ALIGN=CENTER><IMG SRC="Pictures/command.gif"></P><A NAME="participants"></A><H2><A HREF="#collaborations"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Collaborations"></A> Participants</H2><UL><A NAME="auto1014"></A><LI><B>Command</B><A NAME="auto1015"></A><P></P><UL> <A NAME="auto1016"></A><LI>declares an interface for executing an operation.</LI></UL><A NAME="auto1017"></A><P></P><A NAME="auto1018"></A><LI><B>ConcreteCommand</B> (PasteCommand, OpenCommand)<A NAME="auto1019"></A><P></P><UL> <A NAME="auto1020"></A><LI>defines a binding between a Receiver object and an action.</LI> <A NAME="auto1021"></A><P><!-- extra space --></P> <A NAME="auto1022"></A><LI>implements Execute by invoking the corresponding operation(s) on Receiver.</LI></UL><A NAME="auto1023"></A><P></P><A NAME="auto1024"></A><LI><B>Client</B> (Application)</LI><A NAME="auto1025"></A><P></P><UL> <A NAME="auto1026"></A><LI>creates a ConcreteCommand object and sets its receiver.</LI></UL><A NAME="auto1027"></A><P></P><A NAME="auto1028"></A><LI><B>Invoker</B> (MenuItem)<A NAME="auto1029"></A><P></P><UL> <A NAME="auto1030"></A><LI>asks the command to carry out the request.</LI></UL><A NAME="auto1031"></A><P></P><A NAME="receiver-part-command"></A><LI><B>Receiver</B> (Document, Application)<A NAME="auto1032"></A><P></P><UL> <A NAME="auto1033"></A><LI>knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.</LI></UL></UL><A NAME="collaborations"></A><H2><A HREF="#consequences"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Consequences"></A> Collaborations</H2><UL><A NAME="auto1034"></A><LI>The client creates a ConcreteCommand object and specifies its receiver.</LI><A NAME="auto1035"></A><P></P><A NAME="auto1036"></A><LI>An Invoker object stores the ConcreteCommand object.</LI><A NAME="auto1037"></A><P></P><A NAME="auto1038"></A><LI>The invoker issues a request by calling Execute on the command. Whencommands are undoable, ConcreteCommand stores state for undoing thecommand prior to invoking Execute.</LI><A NAME="auto1039"></A><P></P><A NAME="auto1040"></A><LI>The ConcreteCommand object invokes operations on its receiver to carryout the request.</LI></UL><A NAME="auto1041"></A><P>The following diagram shows the interactions between these objects.It illustrates how Command decouples the invoker from the receiver(and the request it carries out).</P><A NAME="command-237i"></A><P ALIGN=CENTER><IMG SRC="Pictures/comma077.gif"></P><A NAME="consequences"></A><H2><A HREF="#implementation"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Implementation"></A> Consequences</H2> <A NAME="auto1042"></A><P>The Command pattern has the following consequences:</P><OL><A NAME="auto1043"></A><LI>Command decouples the object that invokes the operation from the onethat knows how to perform it.</LI><A NAME="auto1044"></A><P></P><A NAME="auto1045"></A><LI>Commands are first-class objects. They can be manipulated and extendedlike any other object.</LI><A NAME="auto1046"></A><P></P><A NAME="auto1047"></A><LI>You can assemble commands into a composite command. An example is theMacroCommand class described earlier. In general, composite commandsare an instance of the <A HREF="pat4cfs.htm" TARGET="_mainDisplayFrame">Composite (163)</A> pattern.</LI><A NAME="auto1048"></A><P></P><A NAME="auto1049"></A><LI>It's easy to add new Commands, because you don't have to changeexisting classes.</LI></OL><A NAME="implementation"></A><H2><A HREF="#samplecode"><IMG SRC="gifsb/down3.gif" BORDER=0 ALT="next: Sample Code"></A> Implementation</H2> <A NAME="auto1050"></A><P>Consider the following issues when implementing the Command pattern:</P><OL><A NAME="auto1051"></A><LI><EM>How intelligent should a command be?</EM>A command can have a wide range of abilities. At one extreme itmerely defines a binding between a receiver and the actions that carryout the request. At the other extreme it implements everything itselfwithout delegating to a receiver at all. The latter extreme is usefulwhen you want to define commands that are independent of existingclasses, when no suitable receiver exists, or when a command knows itsreceiver implicitly. For example, a command that creates anotherapplication window may be just as capable of creating the window as
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -