命令模式的简单使用

19 篇文章 0 订阅
1 篇文章 0 订阅

前言

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

角色扮演

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类里面。

后记

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值