博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式(10)状态模式(讲解+应用)
阅读量:5897 次
发布时间:2019-06-19

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

目录

  1. 状态模式

  2. 为什么使用状态模式?

  3. 应用实例

状态模式

状态模式,顾名思义,肯定是和状态有关,进一步思考,我们在讨论的是设计模式,设计模式中的重要原则对变化的进行封装,顺着这个思路去想,那么是有很多的变化的状态,然后通过状态设计模式,来对这些变化的状态进行封装,故状态设计模式。

状态模式:对于对象内部的状态,允许其在不同的状态下,拥有不同的行为,对状态单独封装成类。

和策略模式类似,这里是将每一个状态单独封装成类,每个状态下拥有不同行为。

为什么使用状态模式?

为什么要使用状态模式?通过一个例子来看,对于一些问题,当我们通过一个例子将其具体化之后,我们会发现问题处理起来变得简单,同时理解起来也不会和之前那样晦涩难懂。通过什么来举例子呢?设计到多状态,不同状态下各自具有不同行为的东西,而且理解起来相对容易的。最近在地铁站发现了有个叫5个橙子的投币榨汁机,我们投币10元前,我们就可以获得一杯用5个橙子榨出来的橙汁一杯,如果让我们设计这套系统,要怎么设计呢?首先要有的feature,投币,退币,出橙子,然后其要有的state有没有钱币,10元钱币,大于10元的钱币,小于10元的钱币,橙子售空,还有橙子。动手来写。

//榨汁机public class MillMachine{//各种状态    final static int SOLD_OUT = 0;    final static int SOLD = 1;    final static int NO_MONEY = 3;    final static int HAS_MONEY = 4;    int state;     int count;    public MillMachine(int count){        this.count = count;        if(count>0)            state = NO_MONEY;    } //插入钱币    public void insertMoney(){        if(state == HAS_MONEY)            System.out.println("You can't insert Money");        else if(state == NO_MONEY){            System.out.println("You insert 10");            state = HAS_MONEY;        }        else if(state == SOLD_OUT)            System.out.println("Nothing can be bought");        else if(state == SOLD)            System.out.prinltn("You will get a cup of juice");    }//取出钱币    public void withdrawMoney(){        if(state == HAS_MONEY){            System.out.println("You will get Money");            state = NO_MONEY;        }else if(state == NO_MONEY){            System.out.println("You haven't insert money");        }else if(state == SOLD){            System.out.println("You can't get back the money");        }else if(state == SOLD_OUT){            System.out.println("You haven't insert money");        }    }//按下榨汁按钮    public void pressKnob(){        if(state == SOLD){            System.out.println("Please wait a minute,you will get a cup of juice");        }else if(state == SOLD_OUT){            System.out.prinltn("Sorry,three are't juice for you");        }else if(state == NO_MONEY){            System.out.println("Please insert Money");        }else if(state == HAS_MONEY){            System.out.pritln("You will get a cup of juice")            state = SOLD;            produce();        }    }//产生果汁    public void produce(){        if(state == SOLD){            System.out.println("You get a cup of juice");            count--;            if(count<0)                state=SOLD_OUT;            else state=NO_MONEY;        }else if(state==SOLD_OUT){            System.out.println("Nothing");        }else if(state==NO_MONEY){            System.out.println("Nothing");        }        else if(state==HAS_MONEY){            System.out.println("Nothing");        }    }}

根据代码,我们可以看出,我们一共拥有四种状态,分别为有钱,没钱,售空,未售空。操作有按下榨汁按钮,插入钱币,取出钱币,榨汁,当然榨汁操作并不是我们手动可以触发的。对于其中相应的方法写的也比较详细,各个操作下状态的转换,根据上面的代码,我们可以看出是很繁琐的,而且一旦增加状态,或者是操作,需要我们修改很多的代码,灵活性和可扩展性很差,现在就到了我们的状态设计模式大显身手的时候了。既然是有很多的状态,不同状态下相同的操作行为不同,那么我们就将每一种状态单独封装成类,然后这些状态分别实现各自不同操作下的行为,这样我们的榨汁机只需要对几个状态对象进行操作就可以了,使得代码变得简洁也方便以后的修改.Show the code

public class MillMachine{    State noMoneyState;    State hasMoneyState;    State soldState;    State soldOutState;    State state;     int count;    public MillMachine(int count){        noMoneyState = new NoMoneyState(this);        //.....        this.count = count;        if(count>0)            state = NoMoneyState;    }     public void insertMoney(){        state.insertMoney();    }    public void withdrawMoney(){        state.withdrawMoney();    }    public void pressKnob(){        state.pressKnob();    }    public void produce(){        state.produce();    }    public State getNoMoneyState(){        return this.NoMoneyState;    }    public void setState(State state){        this.state = state;    }    }public interface State{    public void insertMoney();    public void withdrawMoney();    public void pressKnob();    public void produce();}public class HasMoneyState implements State{    MillMachine machine;    public HasMoneyState(MillMachine machine){        this.machine = machine;    }    public void insertMoney(){        //.......    }    public void withdrawMoney(){        System.out.pritln("you will get your money");        machine.setState(machine.getNoMoney());    }    public void pressKnob(){        //......    }    public void produce(){        //......    }}

通过这种方式来写,让我们的榨汁机类内部的代码量变得更加简洁,针对接口进行编程,同时带来一个弊端就是使得我们的额外的增加了许多的状态类,使得我们的代码量增加了很多。

应用实例

Android中的一个应用实例即使context和state之间,有兴趣的可以针对源码仔细了解,这里先贴出来。

图片描述

用番茄钟计时来写这篇博客,用掉4个番茄。第五个也已经完成了一半,国庆之后,能有这么充足的时间再来写真的不容易了。

下篇更新适配器模式

转载地址:http://evasx.baihongyu.com/

你可能感兴趣的文章
spring SchedulerFactoryBean 没有创建 Scheduler的实现类bea
查看>>
基于cobbler实现自动化安装系统
查看>>
java基础专栏—IOUtils(4)
查看>>
TimeUnit使用
查看>>
The Shared folder with you
查看>>
GNU GRUB version 0.97 (630K lower /2053824K upper memory)
查看>>
BodyPaint__操作步骤
查看>>
curl
查看>>
1、(w3school)javascript学习总结--javascript的功能
查看>>
poj 2234 Matches Game
查看>>
2018年全国多校算法寒假训练营练习比赛(第五场)
查看>>
080_Dataloader.io
查看>>
sax方式解析XML学习笔记
查看>>
Springboot配置(上)
查看>>
TensorFlow从入门到理解(一):搭建开发环境【基于Ubuntu18.04】
查看>>
Luogu345: [POI2007]POW-The Flood
查看>>
java--Eclipse for mac 代码提示(代码助手,代码联想)快捷键修改
查看>>
ECC椭圆曲线详解(有具体实例)
查看>>
收集C#常用类:产生一个验证码,改了下
查看>>
Jdom的简单操作
查看>>