博客
关于我
设计模式(21)——状态模式
阅读量:557 次
发布时间:2019-03-09

本文共 5587 字,大约阅读时间需要 18 分钟。

APP抽奖活动状态模式设计与实现

状态模式概述

状态模式是一种设计模式,主要用于解决对象在不同状态下表现出不同的行为问题。通过将状态和行为分开管理,可以让对象在状态变化时灵活地展示不同的行为,实现更灵活的状态管理。

状态模式在抽奖活动中的应用

活动状态说明

抽奖活动可以处于以下四个状态:

  • 不能抽奖状态(NoRaffleState)

    • 用户未扣除积分或抽奖次数已用完。
    • 扣除积分后转换为可以抽奖的状态。
  • 可以抽奖状态(CanRaffleState)

    • 用户已经扣除积分,当前可以进行抽奖。
    • 抽奖后根据结果转换为发放奖品状态或不能抽奖状态。
  • 发放奖品状态(DispenseState)

    • 用户中奖后进入该状态。
    • 发放奖品后转换为不能抽奖状态。
  • 奖品发放完毕状态(DispenseOutState)

    • 所有奖品已发放,活动结束。
    • 用户无法再进行抽奖或扣除积分。
  • 状态转换关系

    • 从 NoRaffleState 转换到 CanRaffleState

      扣除积分成功后,用户可以抽奖。

    • 从 CanRaffleState 转换到 DispenseState 或 NoRaffleState

      抽奖成功则转换为 DispenseState,抽奖失败则转换为 NoRaffleState。

    • 从 DispenseState 转换到 NoRaffleState

      发放完毕后,用户无法继续抽奖。

    • 从 DispenseOutState 无法转换

    状态模式的实现类图

    • State 接口

      提供与上下文相关的基本操作,如扣除积分、抽奖、发放奖品。

    • ConcreteState 实现类

      定义具体的状态行为,如 CanRaffleState、NoRaffleState 等。

    • Context 类

      维护当前状态实例,提供状态切换的方法。

    具体实现代码

    状态接口定义

    package com.lm.state;public interface State {    void deduceMoney();    boolean raffle();    void dispensePrize();}

    各状态实现类

    package com.lm.state;public class NoRaffleState extends State {    RaffleActivity activity;    public NoRaffleState(RaffleActivity activity) {        this.activity = activity;    }    @Override    public void deduceMoney() {        System.out.println("扣除50积分成功,您可以抽奖了");        activity.setState(activity.getCanRaffleState());    }    @Override    public boolean raffle() {        System.out.println("扣了积分才能抽奖喔!");        return false;    }    @Override    public void dispensePrize() {        System.out.println("不能发放奖品");    }}
    package com.lm.state;public class CanRaffleState extends State {    RaffleActivity activity;    public CanRaffleState(RaffleActivity activity) {        this.activity = activity;    }    @Override    public void deduceMoney() {        System.out.println("已经扣取过了积分");    }    @Override    public boolean raffle() {        System.out.println("正在抽奖,请稍等!");        Random r = new Random();        int num = r.nextInt(10);        if (num == 0) {            activity.setState(activity.getDispenseState());            return true;        } else {            System.out.println("很遗憾没有抽中奖品!");            activity.setState(activity.getNoRaffleState());            return false;        }    }    @Override    public void dispensePrize() {        System.out.println("没中奖,不能发放奖品");    }}

    抽奖活动类

    package com.lm.state;public class RaffleActivity {    private State state;    private int count;    NoRaffleState noRaffleState = new NoRaffleState(this);    CanRaffleState canRaffleState = new CanRaffleState(this);    DispenseState dispenseState = new DispenseState(this);    DispenseOutState dispenseOutState = new DispenseOutState(this);    public RaffleActivity(int count) {        state = getNoRaffleState();        this.count = count;    }    public void deduceMoney() {        state.deduceMoney();    }    public void raffle() {        if (state.raffle()) {            state.dispensePrize();        }    }    public State getState() {        return state;    }    public void setState(State state) {        this.state = state;    }    public int getCount() {        int curCount = count;        count--;        return curCount;    }    public void setCount(int count) {        this.count = count;    }    public NoRaffleState getNoRaffleState() {        return noRaffleState;    }    public void setNoRaffleState(NoRaffleState noRaffleState) {        this.noRaffleState = noRaffleState;    }    public CanRaffleState getCanRaffleState() {        return canRaffleState;    }    public void setCanRaffleState(CanRaffleState canRaffleState) {        this.canRaffleState = canRaffleState;    }    public DispenseState getDispenseState() {        return dispenseState;    }    public void setDispenseState(DispenseState dispenseState) {        this.dispenseState = dispenseState;    }    public DispenseOutState getDispenseOutState() {        return dispenseOutState;    }    public void setDispenseOutState(DispenseOutState dispenseOutState) {        this.dispenseOutState = dispenseOutState;    }}

    测试案例

    package com.lm.state;public class Client {    public static void main(String[] args) {        RaffleActivity activity = new RaffleActivity(1);        for (int i = 0; i < 30; i++) {            System.out.println("--------第 " + (i + 1) + " 次抽奖--------");            activity.deduceMoney();            activity.raffle();        }    }}

    借贷平台订单状态管理

    状态模式在借贷平台中的应用

    借贷平台的订单管理涉及多个状态转换,如审核、发布、抢单等。状态模式可以有效地管理这些状态转换,提高代码的可读性和维护性。

    状态转换流程图

    +------------+    +----------------+|            |    |                 ||            | --> |                 |+------------+    +----------------+        |                     |        v                     v+------------+    +----------------+|            |    |                 ||            | <-- |审核通过          |+------------+    +----------------+        |                     |        v                     v+------------+    +----------------+|            |    |                 ||            | --> |发布              |+------------+    +----------------+        |                     |        v                     v+------------+    +----------------+|            |    |                 ||            | <-- |已发布            |+------------+    +----------------+

    事件状态关系表

    | 事件 | 状态转换 | 备注 ||------|----------|------|| 审核 | 通过     | 修改为已审核状态 || 审核 | 未通过   | 修改为已拒绝状态 || 发布 |          | 将订单状态改为已发布 || 接单 |          | 将订单状态改为已接单 || 失效 |          | 将订单状态改为已失效 ||付款 |          | 将订单状态改为已付款 || 失败 |          | 将订单状态改为已失败 || 反馈 |          | 将订单状态改为已反馈 |

    状态模式的注意事项

  • 可读性

    状态模式将每个状态的行为封装到对应的类中,代码结构清晰,便于维护和理解。

  • 可扩展性

    状态模式支持轻松添加新的状态,减少了大量的 if-else 判断,提高了代码的可维护性。

  • 开闭原则

    状态模式符合开闭原则,便于新增状态或修改现有状态的行为。

  • 适用性

    适用于状态多且互相转换的场景,特别是在需要动态管理对象行为的系统中。

  • 潜在问题

    状态模式会增加类的数量,管理大量状态时可能导致代码复杂化。

  • 转载地址:http://eugiz.baihongyu.com/

    你可能感兴趣的文章
    Java面试题整理,闭关在家37天“吃透”这份345页PDF,纯干货
    查看>>
    laravel server error 服务器内部错误
    查看>>
    iJ配置Maven环境详解
    查看>>
    面试题 08.01. 三步问题
    查看>>
    剑指 Offer 11. 旋转数组的最小数字
    查看>>
    作为我的第一篇csdn博客吧
    查看>>
    一道简单的访问越界、栈溢出pwn解题记录
    查看>>
    响应的HTTP协议格式+常见的响应码
    查看>>
    将windows里的内容直接复制粘贴到ubuntu,提高效率
    查看>>
    [PHP] error_reporting(0)可以屏蔽Fatal error错误
    查看>>
    thinkphp 的一些重要知识点
    查看>>
    Java学习第二章——Java基本语句
    查看>>
    遇到问题之-yum update无法连接镜像问题解决
    查看>>
    pycharm如何设置(错误、警告类的标准提醒)
    查看>>
    Python3运行的时候错误:ModuleNotFoundError: No module named 'PIL'
    查看>>
    PHP是世界上最好的语言?Phython第一个不服
    查看>>
    Bugku CTF-web6
    查看>>
    python入门到秃顶(10):异常
    查看>>
    百度背景换肤案例
    查看>>
    输出对象的值——踩坑
    查看>>