Android 状态模式实践应用

2019-02-20  本文已影响0人  liguiyun

什么是状态模式

在不同状态下,具有不同的行为

使用场景

比如 我们发货方式有两种方式 快递,物流,使用快递 都需要 打包,计算费用,因为使用快递比较小,物流往往比较大的,所以打包方式不一样,计算费用也不一样,需要这种情况我们都会 用 if else if() 下面我随便写一下代码

  
  //我们都是先判断湿 那种方式 然后打包,计算金额 如果快递有很多种费用都不一样,就会一直 if else if 下面我
  //用项目实战中用到的状态模式 来表述状态模式是什么东西
  if (status.equals("快递")) {
            packageExpressDelivery();
            calculateAmountExpressDelivery();
        } else if (status.equals("物流")) {
            packageLogistics();
            calculateLogisticsAmount();
        }
         /**
     * 打包物流
     */
    private void packageLogistics() {

    }

    /**
     * 计算费用
     */
    private double calculateLogisticsAmount() {
        return 0;
    }

    /**
     * 打包快递
     */
    private void packageExpressDelivery() {

    }

    /**
     * 计算快递费用
     */
    private double calculateAmountExpressDelivery() {
        return 0;
    }

项目实战用的状态模式

一,项目需求

选择充值金额方式,目前有两种,1,快捷充值(速度快,手续费比较高,转账到任何账户里面)2,转账充值(速度满,手续费低 转账到银行卡里面) 以后会添加 平安,富有,支付宝,微信 等充值方式

二,为了以后充值方式的扩展,到达改动小,添加快

确定需求:1,选择不同的支付方式跳转到不同界面去充值

2,手续费计算方式不一样

3,因为手续费不一样 到账金额也不一样

三,定义接口
public interface RechargeState {
//跳转到不同界面
    void jumpActivity(Context context);
//计算到账金额
    BigDecimal getArrivalAmount(BigDecimal rechargeAmount,BigDecimal serviceFee,BigDecimal minServiceCharge);
//计算服务费用
    BigDecimal getServiceAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge);
}

四 不同的充值方式实现上面接口,并且业务不同实现不同业务逻辑
public class QuitRechargeState implements RechargeState {

    @Override
    public void jumpActivity(Context context) {
    //跳转到快捷充值界面去充值
        context.startActivity(new Intent(context, QuitRechargeActivity.class));
    }

    @Override
    public BigDecimal getArrivalAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
    //金额-金额*费率就是 到账金额
        return rechargeAmount.subtract(getRechargeFee(rechargeAmount, serviceFee));
    }

    @Override
    public BigDecimal getServiceAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
//如果手续费小于最小金额  就去最小金额 否则 取 金额*费率
        if (getRechargeFee(rechargeAmount, serviceFee).compareTo(minServiceCharge) < 0) {
            return minServiceCharge;
        } else {
            return getRechargeFee(rechargeAmount, serviceFee);
        }
    }
/*
*计算手续费
*/
    private BigDecimal getRechargeFee(BigDecimal rechargeAmount, BigDecimal serviceFee) {
        return rechargeAmount.multiply(serviceFee).setScale(2, RoundingMode.HALF_UP);
    }
}

public class TransferRechargeState implements RechargeState {

    @Override
    public void jumpActivity(Context context) {
    //跳转到转账金额
        context.startActivity(new Intent(context, TransferRechargeActivity.class));
    }

    @Override
    public BigDecimal getArrivalAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
    //金额-金额*手续费-0.1  0.1 元是 短信通知费用
        return rechargeAmount.subtract(getRechargeFee(rechargeAmount, serviceFee))-2;
    }

    @Override
    public BigDecimal getServiceAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
    //金额*费率 等于 手续费
        return getRechargeFee(rechargeAmount, serviceFee);
    }

    private BigDecimal getRechargeFee(BigDecimal rechargeAmount, BigDecimal serviceFee) {
        return rechargeAmount.multiply(serviceFee).setScale(2, RoundingMode.HALF_UP);
    }
}

public class RechargeController   {

    private RechargeState rechargeState;
    
//设置当前模式是快捷充值
    public void setQuitRecharge() {
        rechargeState = new QuitRechargeState();
    }
//设置当前模式为转账充值
    public void setTransferRecharge() {
        rechargeState = new TransferRechargeState();
    }

  
    public void jumpActivity(Context context) {
        if(rechargeState==null){
            new Throwable("please set state");
        }
        rechargeState.jumpActivity(context);
    }

   
    public BigDecimal calculateArrivalAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
        if(rechargeState==null){
            new Throwable("please set state");
        }
        return rechargeState.getArrivalAmount(rechargeAmount, serviceFee, minServiceCharge);
    }

   
    public BigDecimal calculateServiceAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
        if(rechargeState==null){
            new Throwable("please set state");
        }
        return rechargeState.getServiceAmount(rechargeAmount, serviceFee, minServiceCharge);
    }
}

上面 代码已经写好了,下面我门看看怎么用

  //创建充值对象
  final RechargeController rechargeController = new RechargeController();
  //设置转账充值
        btn_transfer.setOnClickListener(new View.OnClickListener() {
                                            @Override
                                            public void onClick(View v) {
                                                rechargeController.setTransferRecharge();
                                            }
                                        }
        );
        //设置快捷充值
        btn_quit.setOnClickListener(new View.OnClickListener() {
                                        @Override
                                        public void onClick(View v) {
                                            rechargeController.setTransferRecharge();
                                        }
                                    }
        );
        //跳转到Activity
        rechargeController.jumpActivity(this);
        //计算到账金额
        rechargeController.calculateArrivalAmount(new BigDecimal(100), new BigDecimal(0.0038), new BigDecimal(2));
        //计算手续费
        rechargeController.calculateServiceAmount(new BigDecimal(100), new BigDecimal(0.0038), new BigDecimal(2));

看到上面代码 是不是很清晰明了,光清晰 还不算,如果续费变更 需要 添加 支付宝充值,看看我怎么添加 首先创建一个对象并且实现 我们定义的接口 看下面的代码

public class AlipayRechargeState implements RechargeState {
    @Override
    public void jumpActivity(Context context) {
        context.startActivity(new Intent(context, AlipayRechargeActivity.class));
    }

    @Override
    public BigDecimal getArrivalAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
        return rechargeAmount.subtract(getRechargeFee(rechargeAmount, serviceFee));
    }

    @Override
    public BigDecimal getServiceAmount(BigDecimal rechargeAmount, BigDecimal serviceFee, BigDecimal minServiceCharge) {
        return getRechargeFee(rechargeAmount, serviceFee);
    }

    private BigDecimal getRechargeFee(BigDecimal rechargeAmount, BigDecimal serviceFee) {
        return rechargeAmount.multiply(serviceFee).setScale(2, RoundingMode.HALF_UP);
    }
}

然后我们修改 RechargeController 添加一个设置支付宝充值模式

//设置当前模式为转账充值  把这句到吗添加到  RechargeController
 public void setAlipayRecharge() {
 rechargeState = new AlipayRechargeState();
 }

是不是很简单 原来的代码逻辑,一句也没动,只需要 在控制添加 支付方式就ok 具体显示教给自己的类

状态模式优点

每个状态是在一个子类里面,业务逻辑都在自己的子类里面实现,易于扩张和维护

结构清晰,避免过多的if else if语句 以及状态判断过多,易于混乱,

状态模式缺点

导致子类过多

上一篇 下一篇

猜你喜欢

热点阅读