命令模式的简单使用

来源:互联网 发布:json数组转换java对象 编辑:程序博客网 时间:2024/06/06 19:03

前言

命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,从而解耦的执行相关的操作。命令模式也叫行动模式或者交易模式;使用命令模式的优点就是在新加入命令的时候很容易扩展,而且如果要存储命令执行顺序也很容易维护一个这样的队列,很容易实现命令的撤销与恢复,大多数优点都基于维护一个队列。

角色扮演

Receiver:具体执行请求操作类,其具体方法叫行动方法。
Command:声明了一个命令类的抽象接口。
ConcreteCommand:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。
Invoker:负责调用命令对象执行请求,相关的方法叫做行动方法。
Client:调用类,创建相关执行类和接受类。

适用场景

当需要对行事务操作优先考虑命令模式;系统需要调用者和接收者不直接交互时优先选择命令模式;需要在不同时间指定请求、请求排队和执行请求时;系统需要将一组操作组合在一起时。

Demo

对于我在写demo的时候就总觉得这个模式在使用中完全可以直接调用Receiver的相关方法就能够完成,但是这样做有什么不一样呢,一方面提高了代码阅读性,记住开发的原则是对修改关闭对扩展开发,这样使用如果后期别人维护该项目会方便很多,咱们开发可是团队作业,demo我就抽象出一个存取款模型,满足4个功能:存钱、取钱、查余额、查账单。

Receiver

package com.demo.command;import java.util.ArrayList;import java.util.List;/** * Created by italkbb on 2017/12/22. */public class Account {    private int totalAmount = 0;    // 简单的维护一个账单流水    private List<Integer> moperations = new ArrayList<>();    /**     * 存钱     * @param money 存钱金额     */    public void accountIn(int money){        this.totalAmount += money;        moperations.add(money);    }    /**     * 取钱     * @param money 取钱金额     */    public void accountOut(int money){        totalAmount -= money;        moperations.add(money);    }    /**     * 查询余额     * @return     */    public int getAccountAmout(){        return totalAmount;    }    /**     * 获取账单流水     * @return     */    public String getBill(){        String simpleBill = new String();        for (Integer money:moperations){            if(money < 0){                simpleBill += "取钱:" + money + "\n";            }else {                simpleBill += "存钱:" + money + "\n";            }        }        return simpleBill;    }}

Command:

package com.demo.command;/** * Created by italkbb on 2017/12/22. */public abstract class Command {    // 账户类    protected Account account;    public Command(Account account)    {        this.account = account;    }    // 抽象命令执行方法    public abstract void action();}

然后定义ConcreteCommand类,这里只定义存钱和取钱:

ConcreteCommand存钱:

package com.demo.command;/** * Created by italkbb on 2017/12/22. */public class AccountInCommand extends Command {    private int money;    public AccountInCommand(Account account,int money){        super(account);        this.money = money;    }    /**     * 存钱操作     */    @Override    public void action() {        account.accountIn(money);    }}

ConcreteCommand取钱:

package com.demo.command;/** * Created by italkbb on 2017/12/22. */public class AccountOutCommand extends Command {    private int money;    public AccountOutCommand(Account account,int money){        super(account);        this.money = money;    }    /**     * 取钱操作     */    @Override    public void action() {        account.accountOut(money);    }}

然后是具体的Invoker类:

Invoker

package com.demo.command;/** * Created by italkbb on 2017/12/22. */public class Invoker {    private Command command;    public void setCommand(Command command){        this.command = command;    }    /**     * 具体执行类     */    public void executeCommand(){        command.action();    }}

最后是调用类,这里就是Activity了
Client

package com.demo.command;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.TextView;import teltplay.example.com.kotlindemo.R;/** * Created by italkbb on 2017/12/22. */public class CommandActivity extends AppCompatActivity {    private Account account = null;    private TextView mAccountDisplay = null;    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_command);        mAccountDisplay = findViewById(R.id.account_display);        // 创建银行帐号        account = new Account();        // 存钱        findViewById(R.id.account_in).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                // 存200块钱                Command commandIn = new AccountInCommand(account,200);                // 创建一个调度者                Invoker invoker = new Invoker();                // 告诉调度者我要存钱                invoker.setCommand(commandIn);                // 干活                invoker.executeCommand();            }        });        // 取钱        findViewById(R.id.account_out).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                // 取200块钱                Command commandOut = new AccountOutCommand(account,200);                // 创建一个调度者                Invoker invoker = new Invoker();                // 告诉调度者我要存钱                invoker.setCommand(commandOut);                // 干活                invoker.executeCommand();            }        });        // 查询余额        findViewById(R.id.account_balance).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                // 显示余额                mAccountDisplay.setText(account.getAccountAmout());            }        });        // 查询账单        findViewById(R.id.account_balance).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                // 显示账单                mAccountDisplay.setText(account.getBill());            }        });    }}

这就实现了简单的命令模式下存取钱的流程,当然可以把查账单之类的也列入Commod类里面。

后记

设计模式的目的是为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 但是问题还得具体分析,如果设计模式离开了生产实际,那么就发挥不出它的长处了,所以具体情况适合用什么设计模式就可以使用,怎么说,设计模式就像是追妹子,你要在交往中明确对方喜欢什么套路,然后选择适合对方的套路放手去追,这样基本就能成了,设计模式也是的,在逻辑和需求的总结中,站在前人的键盘上,确定一套行之有效的设计模式,这件事就算成功了。

原创粉丝点击