• 状态模式


    状态模式:允许对象在内部状态改变时,改变它的行为,对象看起来好像修改了它的类。

    状态模式将一个类的实例对象的状态封装成为独立的类,并把类的动作委托到代表当前状态的类去实现。这样当对象的状态发生改变时,这个对象就会呈现不同的动作表现。

    类图:

    糖果售卖机具有四种状态:没有25分钱状态,有25分钱状态,售出糖果状态,糖果售罄状态
    在糖果售卖机处于不同的状态下,糖果售卖机的动作表现不同。如在没有25分钱的状态下,投入25分钱的动作是合法的,在售出糖果的状态下,投入25分钱的动作是不合法的。
    这时,就要更具售卖机对象处于不同的状态,来输出不同的语句。

    状态接口  State接口

     1 /**
     2  * 这是糖果售卖机的状态接口  State
     3  * 糖果售卖机具有四种状态:没有25分钱状态,有25分钱状态,售出糖果状态,糖果售罄状态
     4  * 糖果售卖机 提供三个接口 给顾客调用  :投入25分钱,退出25分钱,转动曲柄(相当于确认购买)
     5  * 糖果售卖机 有一个接口 给自己调用:发放糖果 
     6  * @author wly
     7  *
     8  */
     9 public interface State {
    10      /**
    11       * 投入25分钱  的方法
    12       */
    13      public  void  insertQuarter();
    14      /**
    15       * 退出25分钱  的方法     
    16       */
    17      public  void  ejectQuarter();
    18      /**
    19       * 转动曲柄 确认购买 的方法
    20       */
    21      public  void  turnCrank();
    22      /**
    23       * 发放糖果 的方法
    24       */
    25      public void dispense();
    26 }

     糖果售卖机  GumballMachine类

      1 /**
      2  * 这是糖果售卖机   GumballMachine类
      3  * @author wly
      4  *
      5  */
      6 public class GumballMachine {
      7     //声明一个变量,来引用 没有25分钱状态对象
      8     private   NoQuarterState  noQuarterState;
      9     //声明一个变量,来引用 有25分钱状态对象
     10     private   HasQuarterState hasQuarterState;
     11     //声明一个变量,来引用 售卖状态对象
     12     private   SoldState       soldState;
     13     //声明一个变量,来引用 售罄状态对象
     14     private   SoldOutState    soldOutState;
     15     //声明一个变量 ,  来表示 当前糖果售卖机 是处于 哪一种状态   新的糖果机处于售罄状态(因为没有糖果)
     16     private   State   state = soldOutState;
     17     //声明一个变量 , 表示 糖果的剩余数量
     18     private   int count;
     19     /**
     20      * 糖果售卖机的构造器      
     21      * @param count
     22      */
     23     public GumballMachine(int count)
     24     {
     25         //为糖果售卖机 创建四种状态对象   并把糖果售卖机的对象引用传给状态对象
     26         this.noQuarterState  =  new NoQuarterState(this);
     27         this.hasQuarterState =  new HasQuarterState(this);
     28         this.soldState       =  new SoldState(this);
     29         this.soldOutState    =  new SoldOutState(this);
     30         this.count  = count;
     31         //如果 传入的糖果数量大于0  让糖果售卖机  到 没有25分钱的状态
     32         if(count > 0 )
     33         {
     34             this.setState(noQuarterState);
     35         }
     36     }
     37     /**
     38      * 用来设置糖果售卖机当前状态对象的 setter方法
     39      * @param state
     40      */
     41     public void setState(State state)
     42     {
     43         this.state = state;
     44     }
     45     /**
     46      * 发出一个糖果  ,糖果剩余数量减1
     47      */
     48     public void realseBall()
     49     {
     50         if(count > 0)
     51         {
     52             count--;
     53         }
     54         System.out.println("一个糖果已经发出...还剩"+count+"个糖果");
     55     }
     56     //放入25分钱 的方法 让已经持有糖果机对象的状态对象去处理
     57     public void insertQuarter() {
     58         state.insertQuarter();
     59     }
     60     //退回25分钱 的方法 让已经持有糖果机对象的状态对象去处理
     61     public void ejectQuarter() {
     62         state.ejectQuarter();
     63      }
     64     //转动曲柄 的方法 让已经持有糖果机对象的状态对象去处理
     65     public void turnCrank() {
     66         state.turnCrank();
     67         //现在糖果机处于售卖状态  会自动调用dispense()方法 来发放糖果
     68         state.dispense();
     69     }
     70     //以下是 四种状态对象 和  糖果剩余数量对象的  getter方法 和 setter方法
     71     public NoQuarterState getNoQuarterState() {
     72         return noQuarterState;
     73     }
     74     public void setNoQuarterState(NoQuarterState noQuarterState) {
     75         this.noQuarterState = noQuarterState;
     76     }
     77     public HasQuarterState getHasQuarterState() {
     78         return hasQuarterState;
     79     }
     80     public void setHasQuarterState(HasQuarterState hasQuarterState) {
     81         this.hasQuarterState = hasQuarterState;
     82     }
     83     public SoldState getSoldState() {
     84         return soldState;
     85     }
     86     public void setSoldState(SoldState soldState) {
     87         this.soldState = soldState;
     88     }
     89     public SoldOutState getSoldOutState() {
     90         return soldOutState;
     91     }
     92     public void setSoldOutState(SoldOutState soldOutState) {
     93         this.soldOutState = soldOutState;
     94     }
     95     public int getCount() {
     96         return count;
     97     }
     98     public void setCount(int count) {
     99         this.count = count;
    100     }
    101     
    102 } 

     没有25分钱状态 NoQuarterState类

     1 /**
     2  * 这是没有25分钱状态  NoQuarterState类 
     3  * 没有25分钱状态下  只有 放入钱的方法可用  可以引起状态改变
     4  * @author wly
     5  *
     6  */
     7 public class NoQuarterState implements State {
     8     //声明一个变量 ,来引用糖果售卖机对象
     9     private GumballMachine  gm;
    10     public NoQuarterState(GumballMachine gm)
    11     {
    12         this.gm = gm;
    13     }
    14     @Override
    15     public void insertQuarter() {
    16         System.out.println("你已经放入了25分钱...");
    17         //改变糖果售卖机的状态  到 有25分钱的状态
    18         gm.setState(gm.getHasQuarterState());
    19     }
    20     
    21     @Override
    22     public void ejectQuarter() {
    23         System.out.println("你还没有放入钱,不能要求退钱...");
    24     }
    25     
    26     @Override
    27     public void turnCrank() {
    28         System.out.println("你还没有放入钱,不能转动曲柄...");
    29     }
    30     
    31     @Override
    32     public void dispense() {
    33        System.out.println("你还没有放入钱,不能发放糖果...");
    34     }
    35 
    36 }

     有25分钱的状态 HasQuarterState类

     1 /**
     2  * 这是有25分钱的状态   HasQuarterState类 
     3  * 在有25分钱的状态下  可以使用 退回钱的方法  从而让糖果售卖机的状态回到   没有25分钱状态
     4  * 可以使用 转动曲柄的方法  让糖果售卖机的状态前进到   售卖状态
     5  * @author wly
     6  *
     7  */
     8 public class HasQuarterState implements State {
     9     //声明一个变量 ,来引用糖果售卖机对象
    10     private  GumballMachine  gm;
    11     public  HasQuarterState(GumballMachine gm)
    12     {
    13         this.gm = gm;
    14     }
    15     @Override
    16     public void insertQuarter() {
    17         System.out.println("你已经放入了钱,不能再放入钱...");
    18     }
    19     
    20     @Override
    21     public void ejectQuarter() {
    22         System.out.println("钱将退回给你...");
    23         //改变糖果售卖机的状态  到  没有25分钱的状态
    24         gm.setState(gm.getNoQuarterState());
    25     }
    26     
    27     @Override
    28     public void turnCrank() {
    29         System.out.println("转动曲柄...");
    30         //改变糖果售卖机的状态  到  售卖的状态
    31         gm.setState(gm.getSoldState());
    32     }
    33     
    34     @Override
    35     public void dispense() {
    36         System.out.println("糖果暂时不能发放...");
    37     }
    38 
    39 }

     售卖的状态 SoldState类

     1 /**
     2  * 这是售卖的状态   SoldState类 
     3  * 售卖状态的 糖果发放方法 调用之后   根据当前的糖果数量  来决定 到到哪个状态
     4  * @author wly
     5  *
     6  */
     7 public class SoldState implements State {
     8     //声明一个变量 ,来引用糖果售卖机对象
     9     private GumballMachine  gm;
    10     public SoldState(GumballMachine gm)
    11     {
    12         this.gm = gm;
    13     }
    14      
    15     @Override
    16     public void insertQuarter() {
    17        System.out.println("请稍等,上一次的购买还在发放中,现在不能放入钱...");
    18     }
    19     
    20     @Override
    21     public void ejectQuarter() {
    22        System.out.println("你已经转动曲柄,确认购买了,不能退钱了...");
    23     }
    24     
    25     @Override
    26     public void turnCrank() {
    27        System.out.println("曲柄已经转动了,不能转动两次...");
    28     }
    29     
    30     @Override
    31     public void dispense() {
    32          System.out.println("发放糖果中...");
    33          //发放糖果的方法,糖果数量减1
    34          gm.realseBall();
    35          //如果糖果售卖机中的 糖果数量  大于0 糖果售卖机的状态 到 没有25分钱的状态
    36          if(gm.getCount() > 0)
    37          {
    38              gm.setState(gm.getNoQuarterState());
    39          }
    40          else  //如果糖果售卖机中的 糖果数量  小于等于0 糖果售卖机的状态 到 售罄状态 
    41          {
    42              System.out.println("糖果已经售罄...");
    43              gm.setState(gm.getSoldOutState());
    44          }
    45     }
    46 
    47 }
    糖果售罄状态   SoldOutState类
     1 /**
     2  * 这是糖果售罄状态   SoldOutState类
     3  * @author wly
     4  *
     5  */
     6 public class SoldOutState implements State{
     7     //声明一个变量 ,来引用糖果售卖机对象
     8     private GumballMachine  gm;
     9     public SoldOutState(GumballMachine gm)
    10     {
    11         this.gm = gm;
    12     }
    13     @Override
    14     public void insertQuarter() {
    15        System.out.println("糖果已经售罄,不能再放入钱...");
    16     }
    17     
    18     @Override
    19     public void ejectQuarter() {
    20         System.out.println("糖果已经售罄,不能退回钱...");
    21     }
    22     
    23     @Override
    24     public void turnCrank() {
    25         System.out.println("糖果已经售罄,不能转动曲柄...");
    26     }
    27     
    28     @Override
    29     public void dispense() {
    30        System.out.println("糖果已经售罄,不能发放糖果...");
    31     }
    32 }
    最后提供一个测试类:
     1 public class TestClass {
     2 
     3     /**
     4      * @param args
     5      */
     6     public static void main(String[] args) {
     7          //创建一个糖果售卖机对象  ,并为这个糖果售卖机对象  放入5颗糖果
     8          //糖果售卖机  处于 没有25分钱状态
     9          GumballMachine gm = new GumballMachine(5);
    10          //放入25分钱  , 糖果售卖机处于有25分钱状态
    11          gm.insertQuarter();
    12          //转动曲柄  ,糖果售卖机处于售卖状态 ,自动调用发放糖果方法,糖果售卖机 将处于没有25分钱状态
    13          gm.turnCrank();
    14          System.out.println("********************");
    15          //放入25分钱  , 糖果售卖机处于有25分钱状态
    16          gm.insertQuarter();
    17          //退回25分钱 ,糖果售卖机处于没有25分钱状态
    18          gm.ejectQuarter();
    19          System.out.println("********************");
    20          gm.insertQuarter();
    21          gm.turnCrank();
    22          System.out.println("********************");
    23          gm.insertQuarter();
    24          gm.turnCrank();
    25          System.out.println("********************");
    26          gm.insertQuarter();
    27          gm.turnCrank();
    28          System.out.println("********************");
    29          //放入25分钱  , 糖果售卖机处于有25分钱状态
    30          gm.insertQuarter();
    31          //转动曲柄  ,糖果售卖机处于售卖状态 ,自动调用发放糖果方法,糖果售卖机 中的糖果数为0,糖果售卖机将到糖果售罄状态
    32          gm.turnCrank();
    33          
    34     }
    35 }
    运行结果如下:


     
  • 相关阅读:
    php-7.0.16 , apache2.4.25 配置
    一次完整的HTTP请求需要的7个步骤
    TypeScript 配置
    React Please wrap your <Route> in a <Routes>
    Typescript node 里使用 multer插件, req 没有 file这个属性
    node 操作mongodb 用 find() 第一个参数无效
    手机请求不到本地服务器 [Error: Network Error]
    模块 ""mongoose"" 没有默认导出。你是想改为使用 "import { Mongoose } from "mongoose"" 吗?
    小程序 自定义 tabBar Component “页面路径“ does not have a method “ 方法名“ to handle event “tap“
    react-native 初始化项目失败
  • 原文地址:https://www.cnblogs.com/wangliyue/p/4227820.html
Copyright © 2020-2023  润新知