设计模式14 - 命令模式 Command Pattern

来源:互联网 发布:python最突出的优点 编辑:程序博客网 时间:2024/05/22 14:59


Command design pattern is used to encapsulate a request as an object and pass to an invoker, wherein the invoker does not knows how to service the request but uses the encapsulated command to perform an action.

To understand command design pattern we should understand the associated key terms like client, command, command implementation, invoker, receiver.

  • Command is an interface with execute method. It is the core of contract.
  • A client creates an instance of a command implementation and associates it with a receiver.
  • An invoker instructs the command to perform an action.
  • A Command implementation’s instance creates a binding between the receiver and an action.
  • Receiver is the object that knows the actual steps to perform the action.

Command Pattern Discussion

It will be easier to understand all the above with an example. Let us think of developing a universal remote. Our UnversalRemote will have only two buttons, one is to power on and another is to mute all associated ConsumerElectronics.

For ConsumerElectronics we will have couple of implementations Television and SoundSystem. Button is a class that is the invoker of an action.

OnCommand is used to switch on a ConsumerElectronics. While instantaiting OnCommand client needs to set the receiver. Here receiver is either Television or SoundSystem. UniversalRemote class will maintain all the receivers and will provide a method to identify the currently active receiver.

When an instance of a invoker is created, a concrete command is passed to it. Invoker does not know how to perform an action. All it does is honoring the agreement with the Command. Invoker calls the execute() method of the set concrete command.

UML Diagram for Command Pattern

Command Pattern Example Implementation

Command.java

public interface Command {    void execute();                                                                                           }

OnCommand.java

public class OnCommand implements Command {    private ConsumerElectronics ce;    public OnCommand(ConsumerElectronics ce) {        this.ce = ce;    }    public void execute() {                                                                                           ce.on();    }}

MuteAllCommand.java

import java.util.List;public class MuteAllCommand implements Command {    List<ConsumerElectronics> ceList;    public MuteAllCommand(List<ConsumerElectronics> ceList) {        this.ceList = ceList;    }    public void execute() {        for (ConsumerElectronics ce : ceList) {                                                                           ce.mute();        }    }}

ConsumerElectronics.java

public interface ConsumerElectronics {    void on();    void mute();                                                                                              }

Television.java

public class Television implements ConsumerElectronics {    public void on() {        System.out.println("Television is on!");    }    public void mute() {        System.out.println("Television is muted!");                                                               }}

SoundSystem.java

public class SoundSystem implements ConsumerElectronics {    public void on() {        System.out.println("Sound system is on!");                                                                }    public void mute() {        System.out.println("Sound system is muted!");    }}

Button.java

public class Button {    private Command c;    public Button(Command c) {        this.c = c;    }    public void click() {        c.execute();                                                                                              }}

UniversalRemote.java

public class UniversalRemote {    public static ConsumerElectronics getActiveDevice() {        // Here we will have a complex electronic circular :-)        // that will maintain current device        Television tv = new Television();        return tv;                                                                                                }}

DemoCommandPattern.java

import java.util.List;import java.util.ArrayList;public class DemoCommandPattern {    public static void main(String[] args) {        // OnCommand is instantiated based active device supplied by Remote        ConsumerElectronics ce = UniversalRemote.getActiveDevice();        OnCommand onCommand = new OnCommand(ce); // Create an instance of a command implementation        Button onButton = new Button(onCommand);        onButton.click();             Television tv = new Television();        SoundSystem ss = new SoundSystem();        List<ConsumerElectronics> all = new ArrayList<ConsumerElectronics>();        all.add(tv);        all.add(ss);        MuteAllCommand muteAll = new MuteAllCommand(all);        Button muteAllButton = new Button(muteAll);        muteAllButton.click();    }}

Output:


Important Points on Command Pattern

  • Command pattern helps to decouple the invoker and the receiver. Receiver is the one which knows how to perform an action.
  • Command helps to implement call back in java.
  • Helps in terms of extensibility as we can add new command without changing existing code.
  • Command defines the binding between receiver and action.
  • A command should be able to implement undo and redo operations. That is restting the state of the receiver. It can be done from the support of receiver.




原创粉丝点击