Command mode is not complicated, simply, is to encapsulate some responsibilities into objects, and the object's exciteor and recide are not asking the execution of the command. In this way, the coupling between the excitation and the recipient is released to provide a clearer hierarchy for the program. The actual use is often the abstraction of the commands in the system into an interface, all commands are the implementation of this interface, as shown below:
The Command class is an implementation of ICommand. The Command class implements the Execute method, and the other command classes are subclasses of the Command method. Such an environment facing the excitation recipient and the recipient is very simple: unified as a Command type can be handled.
The implementation code of the simplest command mode is as follows:
/// Define Command Interface Public Interface ICOMMAND {void Execute ();} // Implementing the ICOMMAND interface /// Command class is the base class of all commands, here implements a common processing process of some commands Public Abstract Class Command: iCommand { Public Virtual Void Execute () {} // Implementing other methods ...} // Immand1 PUBLIC CLASS Command1: command {public void override execute () {// specific processing process} // / Implement a specific Command2 Public Class Command2: Command {Public Void Override Execute () {// Specific Processing Procedure}} // Immand3 PUBLIC CLASS COMMAND3: Command {Public Void Override EXECUTE () {// Specific processing process}}}}
The actual application of command mode
Next, look at the application of command mode from a system instance. ReportingService is part of a report system that is a Service program running on a Windows system, and the functions you need are: Every evening 11pm to 2 am, generate hundreds of reports in the database. The distribution of the report is more complicated. Some requirements are published on the web server, and some requires outputting the report data into a text file, and there is still to save the report in the database system.
The design of the system uses command mode, part of which is as follows:
The ICommand interface is defined in the program, implements multiple Command classes (only 3 representations here), performing the generation tasks of each report, respectively. The COMMAND class provides the following interfaces:
Category Name Type Description Property FinishedBool Indicates whether the task has been completed by the Attribute ContextiapplicationContext task, including database connections, file systems, etc. Executevoid execution tasks
Service's main thread initializes the system running the system every day to create an instance of an ApplicationContext class (Application is a class of SINGLTON mode, the figure is not reflected), which saves all the resources you need to use in the class. Then initialize a list of Command objects, perform each Command one by one. In this way, the complex business logic is separated from the main frame of the program, and all the work that Service's main thread needs to do is to coordinate resource allocation and abnormal processing, and you can constantly check the status execution of the command, see The finished property is true. If you find that some commands are not successful, you must do appropriate processing. The program uses the development of unit testing, and a virtual Command implementation is used when testing the program main thread. The virtual ApplicationContext is implemented for each Command class when testing each Command class. Such a structure provides a lot of convenience for unit testing. Testability on the improvement can be found in another article: How to test the part of the test code.
Combination of command mode and other modes
In order to provide a neat and simple way to Command, Command mode is often used in conjunction with Factory, using a factory to manage the COMMAND object, reducing the degree of coupling between command excitation and command objects.
In a form program, Command mode is often used in conjunction with combination modes. You can combine the menu items, toolbars, buttons, etc. on the screen with the corresponding Command, which calls the corresponding Command, which calls the corresponding Command when the control is clicked.
In the "Programmer" magazine, I introduced an article using the COMMAND Mode to implement the UNDO function in the program. The "execution" and "cancellation" operations are defined for each Command, as follows:
The action in the figure is a COMMAMND object, but the name is different, the meaning is the same. Action objects There are DO and UNDO methods, namely "execution" and "revocation" methods. You can set the Done property of the executed Action object to True, and save it in a list --ActionList. Finding the last Done property in ActionList is True's action, and perform its UNDO method to implement "revocation" operation.
Serialization of the order class
If you serialize the Command base class and each of its subcates, more powerful features can be achieved. During the execution of the program, if an exception occurs, such as an abnormality such as a network occurs, the file loss is exception, and the Command serialization without execution can be saved. When you can perform it, you can reload these objects, and the command can continue. Even the user has restarted the computer, and the command can continue. The serialization of the Command object is also convenient for distributed operations. In a network environment, a Command object can be created somewhere, which is transmitted to another computer on the network after sequencement. In this case, don't forget the serialization of the anomalous class. If you define the subclass of Exception, you should serialize it to capture and process an exception that COMMAND execution in the network environment. There is an article on the Microsoft website to introduce the serialization of objects in .NET, detail the concept of object serialization.
references
"Practical J2EE Design Mode Programming Guide" (US) Graig a.berry John Carnell Matjaz B.juric Qiu Zhongpan