设计模式-命令模式

257 阅读2分钟

命令模式

以下内容来自百度百科。

在一般情况下,“请求者”知道“行为实现者”的逻辑以及步骤,也就是直接通过请求者来对实现者操作。命令模式让两者之间实现松耦合。 请求者不知道实现者的具体操作,只按一定的命令便可实现具体操作者的功能。

生活实例

在我们的现实生活中,电视机和遥控器就相当于这个模式。遥控器上的按钮就是我们的请求者, 电视机是我们的“实现者”。当然,使用遥控器的人就是我们的客户端。

模式结构

命令模式包含如下角色:

  • Command: 抽象命令类

抽象出一个命令的执行类

public interface BaseCommand {

    /**
     * 执行命令
     */
    void execute();

}
  • ConcreteCommand: 具体命令类

不同的命令类,具体实现是重写抽象命令类的方法

电视开关机命令

public class TVOnOffCommand implements BaseCommand{


    private TV tv;

    public TVOnOffCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.onOff();
    }
}

频道加命令

public class ChannelUpCommand implements BaseCommand {

    private TV tv;

    public ChannelUpCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.channelUp();
    }
}

频道减命令

public class ChannelDownCommand implements BaseCommand {


    private TV tv;

    public ChannelDownCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        tv.channelDown();
    }
}
  • Invoker: 调用者

通过调用者来执行这个命令

public class Invoker {

    private HashMap<Integer, BaseCommand> commands;

    private BaseCommand command;
    public Invoker() {
        commands = new HashMap<>();
    }

    /**
     * 根据位置把命令存起来
     * @param position
     * @param command
     */
    public void setCommands(int position, BaseCommand command) {
        commands.put(position, command);
    }

    /**
     * 根据位置去发送命令
     * @param position
     */
    public void executeCommand(int position) {
        command = commands.get(position);
        if (command != null) {
            command.execute();
        }
    }
}
  • Receiver: 接收者

实现者本身

public class TV {

    public TV() { }

    public void channelUp() {
        System.out.println("电视机频道加");
    }

    public void channelDown() {
        System.out.println("电视机频道减");
    }

    public void onOff() {
        System.out.println("电视机开关机");
    }
}
  • Client:客户端

我们的程序入口,相当于一个测试类

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btPerform;
    private Button btUp;
    private Button btDown;
    private Invoker invoker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        initData();

    }

    private void initView() {
        btPerform = findViewById(R.id.bt_perform);
        btPerform.setOnClickListener(this);

        btDown = findViewById(R.id.bt_down);
        btDown.setOnClickListener(this);

        btUp = findViewById(R.id.bt_up);
        btUp.setOnClickListener(this);
        //context = new Context(5);
    }

    private void initData() {

        TV tv = new TV();
        BaseCommand onOffCommand = new TVOnOffCommand(tv);
        BaseCommand channelDownCommand = new ChannelDownCommand(tv);
        BaseCommand channelUpCommand = new ChannelUpCommand(tv);
        invoker = new Invoker();
        invoker.setCommands(1, onOffCommand);
        invoker.setCommands(2, channelUpCommand);
        invoker.setCommands(3, channelDownCommand);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.bt_perform: {
                invoker.executeCommand(1);
                break;
            }

            case R.id.bt_up: {
                invoker.executeCommand(2);
                break;
            }

            case R.id.bt_down: {
                invoker.executeCommand(3);
                break;
            }

            default:
                break;
        }
    }
}

总结

通过命令模式,就把执行和“电视”分离出来,执行者就不直接操作“电视”了。