Analysis of Android source code design patterns and practices (11)

Source: Internet
Author: User

Analysis of Android source code design patterns and practices (11)
Chapter 2 command mode

Command mode is one of the behavior modes. In general, it is not difficult to understand, but it is complicated. It decouples the simple call relationship into multiple parts to increase the complexity of the class. However, even so, the structure of the command mode is still clear.

1. Definition

Encapsulate a request into an object so that users can parameterize the client using different requests; queue requests or record request logs, and support auditable operations.

2. Use Cases

(1) extract the action to be executed and provide it as a parameter.

(2) specify, sort, and execute requests at different times. A command object can have a lifetime unrelated to the initial request.

(3) The operation must be canceled.

(4) The log modification function is supported, so that the modifications can be redone when the system crashes.

(5) transaction operations must be supported.

3. Simple implementation

In a push box game, for example, there are five buttons in the game: Left shift, right shift, move down, move up, And undo. The player is the client, and the five buttons are the caller. The command role is used to execute the specific button command.

Receiver role: Push box game

Public class PushBox {/*** execute the left command */public void toLeft () {System. out. println ("Left");}/*** execute the right command */public void toRight () {System. out. println ("to the right");}/*** execute the following command */public void toDown () {System. out. println ("down");}/*** execute the up command */public void toUp () {System. out. println ("up");}/*** run the undo command */public void revoke () {System. out. println ("undo ");}}

Imperative Abstraction

Public interface Command {/*** Command Execution Method */void execute ();/*** GET Command type */void getCommand ();}

Specific imperative, left shift command class

Public class LeftCommand implements Command {// hold a reference to the private PushBox pushBox for accepting the push box game object; public LeftCommand (PushBox pushBox) {this. pushBox = pushBox;} @ Override public void execute () {// call the pushBox command. toLeft () ;}@ Override public void getCommand () {System. out. print ("left --> ");}}

Specific imperative, right shift command class

Public class RightCommand implements Command {// hold a reference to the private PushBox pushBox for accepting the push box game object; public RightCommand (PushBox pushBox) {this. pushBox = pushBox;} @ Override public void execute () {// call the pushBox command. toRight () ;}@ Override public void getCommand () {System. out. print ("Right --> ");}}

Specific imperative, move up command class

Public class UpCommand implements Command {// hold a reference to the private PushBox pushBox for a game object that accepts the push box; public UpCommand (PushBox pushBox) {this. pushBox = pushBox;} @ Override public void execute () {// call the pushBox command. toUp () ;}@ Override public void getCommand () {System. out. print ("up --> ");}}

The specific writer moves down the command class.

Public class DownCommand implements Command {// hold a reference to the private PushBox pushBox for a game object that accepts the push box; public DownCommand (PushBox pushBox) {this. pushBox = pushBox;} @ Override public void execute () {// call the pushBox command. toDown () ;}@ Override public void getCommand () {System. out. print ("down --> ");}}

Specific commander, undo command class

Public class RevokeCommand implements Command {// hold a reference to the private PushBox pushBox for accepting the push box game object; public RevokeCommand (PushBox pushBox) {this. pushBox = pushBox;} @ Override public void execute () {// call the pushBox command. revoke () ;;}@ Override public void getCommand (){}}

Requester class. commands are initiated by buttons.

Public class Buttons {private LeftCommand leftCommand; // reference private RightCommand rightCommand to the command object that is moved to the left; // reference private UpCommand upCommand to the command object that moves to the right; // The command object to be moved up references private DownCommand downCommand; // The command object to be moved down references private RevokeCommand revokeCommand; // The command object to be revoked references private ArrayListCommandList = new ArrayList(); // Used to record Command actions/*** get execution Command */public void getCommandList () {for (Command c: commandList) {c. getCommand ();} System. out. println ("");}/*** sets the command object to be moved to the left ** @ param leftCommand refers to the command object to be moved to the left */public void setLeftCommand (LeftCommand leftCommand) {this. leftCommand = leftCommand;}/*** set the command object to move to the right ** @ param rightCommand the command object to move to the right */public void setRightCommand (RightCommand rightCommand) {this. rightCommand = rightCommand;}/*** set the command object to move up ** @ param upCommand the command object to move up */public void setUpCommand (UpCommand upCommand) {this. upCommand = upCommand;}/*** set the command object to move down ** @ param downCommand the command object to move down */public void setDownCommand (DownCommand downCommand) {this. downCommand = downCommand;}/*** set the undo command object ** @ param revokeCommand undo command object */public void setRevokeCommand (RevokeCommand revokeCommand) {this. revokeCommand = revokeCommand;}/*** press the left button */public void toLeft () {leftCommand.exe cute (); commandList. add (leftCommand);}/*** press the right button */public void toRight () {rightCommand.exe cute (); commandList. add (rightCommand);}/*** press the up button */public void toUp () {upCommand.exe cute (); commandList. add (upCommand);}/*** press the down button */public void toDown () {downCommand.exe cute (); commandList. add (downCommand);}/*** press the Undo button */public void torevke () {revokeCommand.exe cute (); commandList. remove (commandList. size ()-1 );}}

Client call

Public class Client {public static void main (String [] args) {// first create the game PushBox pushBox = new PushBox (); // construct Five Commands LeftCommand leftCommand = new LeftCommand (pushBox) based on the game; RightCommand rightCommand = new RightCommand (pushBox); UpCommand upCommand = new UpCommand (pushBox ); downCommand downCommand = new DownCommand (pushBox); RevokeCommand revokeCommand = new RevokeCommand (pushBox); // The button can execute different commands Buttons buttons = new Buttons (); buttons. setLeftCommand (leftCommand); buttons. setRightCommand (rightCommand); buttons. setUpCommand (upCommand); buttons. setDownCommand (downCommand); buttons. setRevokeCommand (revokeCommand); // execute the buttons operation. toLeft (); buttons. toDown (); buttons. toDown (); buttons. toRight (); buttons. getCommandList (); buttons. torevke (); buttons. toUp (); buttons. toLeft (); buttons. toDown (); buttons. toUp (); buttons. getCommandList ();}}

Execution result

To the left down to the right to the left --> down --> to the right --> undo up to the left down to the left --> down --> up --> to the left --> down --> up -->

After such a long code, do you think it is very cumbersome? It can be implemented easily, as shown below:

Public class Client {public static void main (String [] args) {// first create the game PushBox pushBox = new PushBox (); pushBox. toDown (); pushBox. toRight (); pushBox. toUp ();}}

In fact, there is an important principle in the design pattern: the modification is closed and open to the extension. If you use the preceding simple method, you can only modify the PushBox class and then modify the Client class in the future. This obviously violates this principle. If you use the command mode, the Client class does not need to be modified. You only need to modify the internal operations of the PushBox class. The Client class does not need to know the specific internal implementation.

The use of the design model has also been mentioned before. It mainly depends on the complexity of the current scenario and the need for expansion and maintenance in the future. It is not recommended to fully use the design model, this requires the designers to weigh the advantages and disadvantages.

4. Implementation of the command mode in the Android Source Code 1. PackageHandler

In PackageManagerService, The PackageHandler class is responsible for packet-related message processing. The PackageHandler takes the request to be processed as an object and passes it to the relevant method through the message, the package installation, movement, and package size measurement are encapsulatedHandlerParamsSpecific subclassInstallParams,MoveParamsAndMeasureParams. The source code is as follows:

private abstract class HandlerParams {        private static final int MAX_RETRIES = 4;        /**         * Number of times startCopy() has been attempted and had a non-fatal         * error.         */        private int mRetries = 0;        final boolean startCopy() {            boolean res;            try {                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy");                if (++mRetries > MAX_RETRIES) {                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");                    mHandler.sendEmptyMessage(MCS_GIVE_UP);                    handleServiceError();                    return false;                } else {                    handleStartCopy();                    res = true;                }            } catch (RemoteException e) {                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");                mHandler.sendEmptyMessage(MCS_RECONNECT);                res = false;            }            handleReturnCode();            return res;        }        final void serviceError() {            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");            handleServiceError();            handleReturnCode();        }        abstract void handleStartCopy() throws RemoteException;        abstract void handleServiceError();        abstract void handleReturnCode();    }

We can see thatHandlerParamsIt is also an abstract imperative.

5. Summary 1. Advantages

The command mode has good encapsulation, weaker coupling, more flexible control, and better scalability.

2. Disadvantages

Class expansion, creating a large number of category classes.

6. Reference

Link: Command mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.