目录

1、App抽奖活动问题

2、状态模式基本介绍

3、原理类图

4、状态模式解决APP抽奖活动问题

5、注意事项和细节


1、App抽奖活动问题

请编写程序完成APP抽奖活动,具体抽奖要求如下:

  • 假如没参加一次这个活动要扣除用户50积分,中奖概率是10%
  • 奖品数量有限,抽完就不能抽奖了
  • 活动有四个状态:可以抽奖、不能抽奖、发放奖品和奖品领完。
  • 活动的四个状态转换关系如下图:

2、状态模式基本介绍

  • 状态模式基本介绍(State pattern):主要用来解决对象在多个状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间是可以相互转换的。
  • 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

3、原理类图

4、状态模式解决APP抽奖活动问题

package com.mayun.study.designpattern.state;/*** 状态抽象类* @author Administrator**/
public abstract class State {// 扣除积分 - 50public abstract void deductMoney();// 是否抽中奖品public abstract boolean raffle();// 发放奖品public abstract  void dispensePrize();}
package com.mayun.study.designpattern.state;/*** 不能抽奖状态* @author Administrator**/
public class NoRaffleState extends State {// 初始化时传入活动引用,扣除积分后改变其状态RaffleActivity activity;public NoRaffleState(RaffleActivity activity) {this.activity = activity;}// 当前状态可以扣积分 , 扣除后,将状态设置成可以抽奖状态@Overridepublic void deductMoney() {System.out.println("扣除50积分成功,您可以抽奖了");activity.setState(activity.getCanRaffleState());}// 当前状态不能抽奖@Overridepublic boolean raffle() {System.out.println("扣了积分才能抽奖喔!");return false;}// 当前状态不能发奖品@Overridepublic void dispensePrize() {System.out.println("不能发放奖品");}
}
package com.mayun.study.designpattern.state;
/*** 发放奖品的状态* @author Administrator**/
public class DispenseState extends State {// 初始化时传入活动引用,发放奖品后改变其状态RaffleActivity activity;public DispenseState(RaffleActivity activity) {this.activity = activity;}//@Overridepublic void deductMoney() {System.out.println("不能扣除积分");}@Overridepublic boolean raffle() {System.out.println("不能抽奖");return false;}//发放奖品@Overridepublic void dispensePrize() {if(activity.getCount() > 0){System.out.println("恭喜中奖了");// 改变状态为不能抽奖activity.setState(activity.getNoRafflleState());}else{System.out.println("很遗憾,奖品发送完了");// 改变状态为奖品发送完毕, 后面我们就不可以抽奖activity.setState(activity.getDispensOutState());//System.out.println("抽奖活动结束");//System.exit(0);}}
}
package com.mayun.study.designpattern.state;
/*** 奖品发放完毕状态* 说明,当我们activity 改变成 DispenseOutState, 抽奖活动结束* @author Administrator**/
public class DispenseOutState extends State {// 初始化时传入活动引用RaffleActivity activity;public DispenseOutState(RaffleActivity activity) {this.activity = activity;}@Overridepublic void deductMoney() {System.out.println("奖品发送完了,请下次再参加");}@Overridepublic boolean raffle() {System.out.println("奖品发送完了,请下次再参加");return false;}@Overridepublic void dispensePrize() {System.out.println("奖品发送完了,请下次再参加");}
}
package com.mayun.study.designpattern.state;import java.util.Random;/*** 可以抽奖的状态* @author Administrator**/
public class CanRaffleState extends State {RaffleActivity activity;public CanRaffleState(RaffleActivity activity) {this.activity = activity;}//已经扣除了积分,不能再扣@Overridepublic void deductMoney() {System.out.println("已经扣取过了积分");}//可以抽奖, 抽完奖后,根据实际情况,改成新的状态@Overridepublic boolean raffle() {System.out.println("正在抽奖,请稍等!");Random r = new Random();int num = r.nextInt(10);// 10%中奖机会if(num == 0){// 改变活动状态为发放奖品 contextactivity.setState(activity.getDispenseState());return true;}else{System.out.println("很遗憾没有抽中奖品!");// 改变状态为不能抽奖activity.setState(activity.getNoRafflleState());return false;}}// 不能发放奖品@Overridepublic void dispensePrize() {System.out.println("没中奖,不能发放奖品");}
}
package com.mayun.study.designpattern.state;/*** 抽奖活动 //** @author Administrator**/
public class RaffleActivity {// state 表示活动当前的状态,是变化State state = null;// 奖品数量int count = 0;// 四个属性,表示四种状态State noRafflleState = new NoRaffleState(this);State canRaffleState = new CanRaffleState(this);State dispenseState =   new DispenseState(this);State dispensOutState = new DispenseOutState(this);//构造器//1. 初始化当前的状态为 noRafflleState(即不能抽奖的状态)//2. 初始化奖品的数量public RaffleActivity( int count) {this.state = getNoRafflleState();this.count = count;}//扣分, 调用当前状态的 deductMoneypublic void debuctMoney(){state.deductMoney();}//抽奖public void raffle(){// 如果当前的状态是抽奖成功if(state.raffle()){//领取奖品state.dispensePrize();}}public State getState() {return state;}public void setState(State state) {this.state = state;}//这里请大家注意,每领取一次奖品,count--public int getCount() {int curCount = count;count--;return curCount;}public void setCount(int count) {this.count = count;}public State getNoRafflleState() {return noRafflleState;}public void setNoRafflleState(State noRafflleState) {this.noRafflleState = noRafflleState;}public State getCanRaffleState() {return canRaffleState;}public void setCanRaffleState(State canRaffleState) {this.canRaffleState = canRaffleState;}public State getDispenseState() {return dispenseState;}public void setDispenseState(State dispenseState) {this.dispenseState = dispenseState;}public State getDispensOutState() {return dispensOutState;}public void setDispensOutState(State dispensOutState) {this.dispensOutState = dispensOutState;}
}
package com.mayun.study.designpattern.state;
/*** 状态模式测试类* @author Administrator**/
public class ClientTest {public static void main(String[] args) {// TODO Auto-generated method stub// 创建活动对象,奖品有1个奖品RaffleActivity activity = new RaffleActivity(1);// 我们连续抽300次奖for (int i = 0; i < 30; i++) {System.out.println("--------第" + (i + 1) + "次抽奖----------");// 参加抽奖,第一步点击扣除积分activity.debuctMoney();// 第二步抽奖activity.raffle();}}}

5、注意事项和细节

  • 代码有很强的可读性,状态模式将每个状态的行为封装到对应的类中。
  • 方便维护。将容易产生问题的if-else 语句删除了,如果把每个状态的行为都放到一个类中,每次调用方法时,都要判断当前是什么状态,不但会产生很多if-else语句,而且容易出错。
  • 符合“开闭原则”,容易增删状态。
  • 会产生很多类,每个状态都要有一个类,当状态过多时,会产生过多的类,加大维护量。
  • 应用场景:当一个事件或者对象有很多状态时,状态之间会相互转换,对不同的状态要求有不同的行为的时候,可以考虑状态模式。

设计模式---状态模式(State Pattern)相关推荐

  1. php 状态模式,PHP设计模式(十九)—状态模式 (State Pattern)

    状态模式 (State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类.其别名为状态对象(Objects for States) (一)为什么需要状态模式 ...

  2. 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)

    说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对"状态模式"并不陌生,因为我们之前使用到了状态模式进行 ...

  3. 极速理解设计模式系列:22.状态模式(State Pattern)

    四个角色:抽象状态类(State).具体状态类(ConcreateState).情景类(Context).客户端(Client) 抽象状态类(State):提供一个与情景类有关的State行为. 具体 ...

  4. 趣谈设计模式 | 状态模式(State):如何实现游戏中的状态切换?

    文章目录 案例:马里奥积分竞赛 有限状态机 分支逻辑法 查表法 状态模式 状态模式与策略模式 总结 完整代码与文档 案例:马里奥积分竞赛 喜欢马里奥的小伙伴们都应该知道,前不久马里奥为了庆祝35周年, ...

  5. C++设计模式--状态模式(state)

    概述 前面文章介绍了代理模式(在这里),代理模式和状态模式都提供一个代理类,从结构上看,可以认为代理模式只是状态模式的一个特例,不同之处在于,代理模式控制对其实现类的访问,而状态模式动态地改变其实现类 ...

  6. 状态模式(State Pattern)

    状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类 考虑如下场景,自动售票机: 每一个方格表示自动售票机的一种状态,每一个箭头线表示自动售票机由一个状态转换到另一个状态所需要的 ...

  7. 41状态模式(State Pattern)

    对象状态影响对象行为:     对象拥有不同的状态,往往会行使不同的行为...                     动机:     在软件构建过程中,某些对象的状态如果改变以及其行为也会随之而发生 ...

  8. C++设计模式——状态模式(state pattern)

    一.原理讲解 别名状态对象(object for state). 1.1意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 1.2应用场景 一个对象的行为取决于它的状态,并 ...

  9. 【转】设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  10. Python设计模式-状态模式

    Python设计模式-状态模式 代码基于3.5.2,代码如下; #coding:utf-8 #状态模式class state():def writeProgram(self,work):raise N ...

最新文章

  1. R可视化在回归曲线中添加回归方程式
  2. sql的nvl()函数
  3. npm 查看当前生效的配置
  4. dedecms首页怎么调用公司简介的内容
  5. 【dfs】民生问题(2011特长生 T4)
  6. 2014牡丹江网络赛ZOJPretty Poem(暴力枚举)
  7. 这可能是新手最容易入门的JVM讲解(不过是一场恋爱)
  8. 支持向量机在风控竞赛数据集上的应用
  9. PPT_设计师的十大秘诀
  10. 手机端,网站页面被浏览器转码
  11. 腾讯AI加速器招募再启,AI开放既是工具箱也是方法库?
  12. 由Table_locks_waited想到的mysql 表锁问题
  13. coreseek 词库 导入搜狗词库
  14. window中的cmd中设置别名(alias)及设置快捷键打开cmd
  15. P4944 PION贪吃蛇 题解
  16. 总结今年一些公司的待遇
  17. 这个在线文本编辑器的源代码
  18. 成功解决Unable to allocate xxx MiB for an array with shape (xxxx, xxxx)
  19. 机器学习之K近邻(KNN)模型
  20. 虫师JAVA接口自动化pdf下载,2019虫师自动化 Python接口自动化虫师 robotframework虫师 虫师接口自动化源码下载...

热门文章

  1. 浅谈加速度计旋转补偿
  2. 东华大学计算机专业分数线,2019年东华大学各专业录取分数线
  3. NIST 网络安全框架导读
  4. redhat linux下安装jq和jq的简单应用
  5. 做短视频可以选哪些领域?推荐五种类型短视频,选对方向很重要
  6. 期货价格什么意思(期货价格是指什么)
  7. 最简单的Lambda入门教程
  8. HTML生成word文档
  9. 小米8Lite刷机教程(大多数手机操作基本通用)
  10. 定位服务器的功能是提供用户位置信息和什么,LBS是什么意思 LBS的现有模式和功能介绍...