zoukankan      html  css  js  c++  java
  • 第二节:状态模式——基本介绍&应用

    一、状态模式基本介绍

      1、基本介绍

        (1)状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换;

        (2)当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类;

      2、状态模式的原理类图

         对原理类图的说明——即(状态模式的角色及职责)

        (1)Context 类为环境角色,用于维护 State 实例,这个实例定义当前状态;

        (2)State 是抽象状态角色,定义一个接口封装与 Context 的一个特点接口相关行为;

        (3)ConcreteState 具体的状态角色,每个子类实现一个与 Context 的一个状态相关行为;

     

    二、状态模式解决 APP抽奖问题

      1、应用实例要求

        完成 APP 抽奖活动项目,使用状态模式

      2、思路分析和图解

        定义出一个接口叫状态接口,每个状态都实现它。

        接口有扣除积分方法、抽奖方法、发放奖品方法。

        

      3、代码实现

        状态接口类:

     1 /**
     2  * 状态 接口
     3  */
     4 public interface State {
     5 
     6     /**
     7      * 扣除积分  - 50
     8      */
     9     public void deductMoney();
    10 
    11     /**
    12      * 是否抽中奖品
    13      * @return
    14      */
    15     public boolean raffle();
    16 
    17 
    18     /**
    19      * 发放奖品
    20      */
    21     public void dispensePrize();
    22 }

        各个状态实现类:

      1 /**
      2  * 不能抽奖状态
      3  */
      4 public class NoRaffleState implements State{
      5 
      6     /**
      7      * 初始化时传入活动引用,扣除积分后改变其状态
      8      */
      9     RaffleActivity activity;
     10 
     11     public NoRaffleState(RaffleActivity activity) {
     12         this.activity = activity;
     13     }
     14 
     15     /**
     16      * 当前状态可以扣积分,扣除后,将状态设置成可以抽奖状态
     17      */
     18     @Override
     19     public void deductMoney() {
     20         System.out.println("扣除50积分成功,您可以抽奖了");
     21         activity.setState(activity.getCanRaffleState());
     22     }
     23 
     24     /**
     25      * 抽奖,当前状态是不能抽奖的
     26      * @return
     27      */
     28     @Override
     29     public boolean raffle() {
     30         System.out.println("扣了积分才能抽奖哦!");
     31         return false;
     32     }
     33 
     34     @Override
     35     public void dispensePrize() {
     36         System.out.println("不能发放奖品");
     37     }
     38 }
     39 ------------------------------------------------------
     40 /**
     41  * 可以抽奖的状态
     42  */
     43 public class CanRaffleState implements State{
     44 
     45     /**
     46      * 初始化时传入活动引用,扣除积分后改变其状态
     47      */
     48     RaffleActivity activity;
     49 
     50     public CanRaffleState(RaffleActivity activity) {
     51         this.activity = activity;
     52     }
     53 
     54     @Override
     55     public void deductMoney() {
     56         System.out.println("已经扣取过了积分");
     57     }
     58 
     59     /**
     60      * 可以抽奖,抽完奖后,根据实际情况,设置新的状态
     61      * @return
     62      */
     63     @Override
     64     public boolean raffle() {
     65         System.out.println("正在抽奖,请稍等!");
     66         Random random = new Random();
     67         int num = random.nextInt(10);
     68         if (num == 0) {
     69             //改变活动状态为发放奖品 context
     70             activity.setState(activity.getDispenseState());
     71             return true;
     72         }else {
     73             System.out.println("很遗憾没有抽中奖品!");
     74             //改变状态为不能抽奖
     75             activity.setState(activity.getNoRaffleState());
     76             return false;
     77         }
     78     }
     79 
     80     /**
     81      * 不能发放奖品
     82      */
     83     @Override
     84     public void dispensePrize() {
     85         System.out.println("没有中奖,不能发放奖品");
     86     }
     87 }
     88 ------------------------------------------------------
     89 /**
     90  * 发送奖品的状态
     91  */
     92 public class DispenseState implements State{
     93 
     94     /**
     95      * 初始化时传入活动引用,扣除积分后改变其状态
     96      */
     97     RaffleActivity activity;
     98 
     99     public DispenseState(RaffleActivity activity) {
    100         this.activity = activity;
    101     }
    102 
    103     /**
    104      * 不能扣除积分
    105      */
    106     @Override
    107     public void deductMoney() {
    108         System.out.println("不能扣除积分");
    109     }
    110 
    111     /**
    112      * 不能抽奖
    113      * @return
    114      */
    115     @Override
    116     public boolean raffle() {
    117         System.out.println("不能抽奖");
    118         return false;
    119     }
    120 
    121     /**
    122      * 发放奖品
    123      */
    124     @Override
    125     public void dispensePrize() {
    126         if (activity.getCount() > 0) {
    127             System.out.println("恭喜中奖了!");
    128             // 改变状态为不能抽奖
    129             activity.setState(activity.getNoRaffleState());
    130         }else {
    131             System.out.println("很遗憾,奖品发送完了");
    132             //改变状态为奖品发送完毕,后面就不可以再抽奖了
    133             activity.setState(activity.getDispenseOutState());
    134             System.out.println("抽奖结束,多谢参与");
    135             System.exit(0);
    136         }
    137     }
    138 }
    139 ------------------------------------------------------
    140 /**
    141  * 奖品发放完毕状态
    142  * 说明:当我们 activity 改变成 DispenseOutState,抽奖活动结束了
    143  */
    144 public class DispenseOutState implements State{
    145 
    146     /**
    147      * 初始化时传入活动引用,扣除积分后改变其状态
    148      */
    149     RaffleActivity activity;
    150 
    151     public DispenseOutState(RaffleActivity activity) {
    152         this.activity = activity;
    153     }
    154 
    155     @Override
    156     public void deductMoney() {
    157         System.out.println("奖品发送完了,请下次再参加");
    158     }
    159 
    160     @Override
    161     public boolean raffle() {
    162         System.out.println("奖品发送完了,请下次再参加");
    163         return false;
    164     }
    165 
    166     @Override
    167     public void dispensePrize() {
    168         System.out.println("奖品发送完了,请下次再参加");
    169     }
    170 }

        Context 上下文对象:

      1 /**
      2  * 抽奖活动
      3  */
      4 public class RaffleActivity {
      5 
      6     /**
      7      * 表示当前的状态,是变化的
      8      */
      9     private State state = null;
     10 
     11     /**
     12      * 奖品数量
     13      */
     14     int count = 0;
     15 
     16     /**
     17      * 下面四个属性,表示四种状态
     18      */
     19     State noRaffleState = new NoRaffleState(this);
     20     State canRaffleState = new CanRaffleState(this);
     21     State dispenseState = new DispenseState(this);
     22     State dispenseOutState = new DispenseOutState(this);
     23 
     24     /**
     25      * 构造器
     26      *  1、初始化当前的状态为 noRaffleState 不能抽奖的状态
     27      *  2、初始化奖品的数量
     28      * @param count
     29      */
     30     public RaffleActivity(int count) {
     31         this.state = getNoRaffleState();
     32         this.count = count;
     33     }
     34 
     35     /**
     36      * 扣分,调用当前状态的 deductMoney
     37      */
     38     public void debuctMoney() {
     39         state.deductMoney();
     40     }
     41 
     42     /**
     43      * 抽奖
     44      */
     45     public void raffle() {
     46         //如果当前的状态是抽奖成功
     47         if (state.raffle()) {
     48             //领取奖品
     49             state.dispensePrize();
     50         }
     51     }
     52 
     53 
     54 
     55 
     56 
     57     public State getState() {
     58         return state;
     59     }
     60 
     61     public void setState(State state) {
     62         this.state = state;
     63     }
     64 
     65 
     66     /**
     67      * 注意:每领取一次奖品,count--
     68      * @param
     69      */
     70     public int getCount() {
     71         int curCount = count;
     72         count--;
     73         return curCount;
     74     }
     75 
     76     public void setCount(int count) {
     77         this.count = count;
     78     }
     79 
     80     public State getNoRaffleState() {
     81         return noRaffleState;
     82     }
     83 
     84     public void setNoRaffleState(State noRaffleState) {
     85         this.noRaffleState = noRaffleState;
     86     }
     87 
     88     public State getCanRaffleState() {
     89         return canRaffleState;
     90     }
     91 
     92     public void setCanRaffleState(State canRaffleState) {
     93         this.canRaffleState = canRaffleState;
     94     }
     95 
     96     public State getDispenseState() {
     97         return dispenseState;
     98     }
     99 
    100     public void setDispenseState(State dispenseState) {
    101         this.dispenseState = dispenseState;
    102     }
    103 
    104     public State getDispenseOutState() {
    105         return dispenseOutState;
    106     }
    107 
    108     public void setDispenseOutState(State dispenseOutState) {
    109         this.dispenseOutState = dispenseOutState;
    110     }
    111 }

        客户端:

     1 public class Client {
     2     public static void main(String[] args) {
     3         RaffleActivity activity = new RaffleActivity(1);
     4 
     5         for (int i = 0; i < 30; i++) {
     6             System.out.println("-----第" + (i + 1) + "次抽奖-----");
     7             //参加抽奖,第一步点击扣除积分
     8             activity.debuctMoney();
     9 
    10             //第二步抽奖
    11             activity.raffle();
    12         }
    13     }
    14 }

      

  • 相关阅读:
    MongoDB
    Mac下将Python2.7改为Python3
    Kafka
    Server 基础概念 备忘
    应用内支付
    Sign in with apple
    Linux三剑客grep/sed/awk
    React-Native中使用到的一些JS特性
    Date Picker控件:
    Picker View控件:
  • 原文地址:https://www.cnblogs.com/niujifei/p/14466210.html
Copyright © 2011-2022 走看看