设计模式学习笔记之状态模式
来源:互联网 发布:linux expect scp 编辑:程序博客网 时间:2024/05/16 07:53
什么是状态模式呢?
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。。。是不是听起来显示在内部进行零件调换的感觉,其实是有点类似这种想法的,只不过调换的零件就是封装好的状态。
让我们来举个例子
在我还上学的时候,寝室楼下有一台这样的自动贩售机,专门卖饮料。每天晚上寝室关门之后口渴了,在这里面买点饮料喝喝还是很方便的。
下面用程序来模拟一下这个售货机:
可乐售货机类:
/** * * 可乐自动贩售机类 * @author birdlove1987 * */public class VendingMachine {//售空final static int SoldOutState = 0;//在售final static int OnReadyState = 1;//有币final static int HasCoin = 2;//出货final static int SoldState = 3;//售货机状态private int state = SoldOutState;//机内可乐数量private int count = 0;//构造函数,初始化自动贩售机public VendingMachine(int count) {this.count = count;if (count > 0) {state = OnReadyState;}}//向贩售机投币函数public void insertCoin(){switch (state){case SoldOutState:System.out.println("请不要投币了,售货机里已经没有可乐了!");break;case OnReadyState:state = HasCoin;System.out.println("投币成功,请按出货按钮!");break;case HasCoin:System.out.println("售货机里以及有硬币了,请勿重复投币!");break;case SoldState:System.out.println("正在出货请勿投币!");break;}}//贩售机退币函数public void returnCoin() {switch (state){case SoldOutState:System.out.println("您还没有投币!");break;case OnReadyState:System.out.println("您还没有投币!");break;case HasCoin:System.out.println("请在退币口收好您的硬币");state = OnReadyState;break;case SoldState:System.out.println("可乐已售出,不能退币");break;}}//按出可乐按钮函数public void pressButton() {switch (state) {case SoldOutState:System.out.println("对不起,可乐已售空!");break;case OnReadyState:System.out.println("请您先投币!");break;case HasCoin:System.out.println("请稍等,出可乐中!");state = SoldState;appearCola();break;case SoldState:System.out.println("可乐已出,如想再次购买请再次投币!");break;}}//售货机出可乐函数private void appearCola() {count = count - 1;System.out.println("出货口,滚出了一瓶可乐!");if (count > 0){state = OnReadyState;} else{System.out.println("对不起,可乐已经售空了,请勿在投币!");state = SoldOutState;}}//打印目前售货机的状态public void printState() {switch (state) {case SoldOutState:System.out.println("=========售空=========");break;case OnReadyState:System.out.println("=========售卖中=========");break;case HasCoin:System.out.println("=========已投币=========");break;case SoldState:System.out.println("=========出货中=========");break;}}}
测试类
/** * 测试类 * @author birdlove1987 * */public class MainTest {public static void main(String[] args) {//创建售货机实例,并且只放入一瓶可乐VendingMachine mVendingMachine=new VendingMachine(1);//打印售货机状态mVendingMachine.printState();//投币mVendingMachine.insertCoin();//打印售货机状态mVendingMachine.printState();//按出货按钮mVendingMachine.pressButton();//打印售货机状态mVendingMachine.printState();//投币mVendingMachine.insertCoin();//打印售货机状态mVendingMachine.printState();//按出货按钮mVendingMachine.pressButton();//打印售货机状态mVendingMachine.printState();}}
嗯!模拟成功了!好像感觉还不错呢!不过买了一段时间,你可能发现,如果不搞一些促销活动,更本就搞不过那些有促销的商家!
所以自动售货机也要搞一个“再来一瓶”的活动啊!
但是!!!如果现在直接在自动售货机的类上去直接修改,就违背了软件设计里的“开-闭原则”了,破坏了我们已经闭合的类。所以现在看来,这种设计并不好。。
下面就轮到状态设计模式登场啦,我们从新构建类,这次以状态为类,来构建。
首先定义一下状态接口
/*** * 状态接口 * @author birdlove1987 * */public interface State {//投币函数public void insertCoin();//退币函数public void returnCoin();//按出可乐按钮函数public void pressButton();//出可乐函数public void appearCola();//打印状态函数public void printState();}
/*** * 在售状态类 * @author birdlove1987 * */public class OnReadyState implements State {//贩售机引用private VendingMachine mVendingMachine;//构造函数初始化public OnReadyState(VendingMachine mVendingMachine){this.mVendingMachine=mVendingMachine;}@Overridepublic void insertCoin() {// TODO Auto-generated method stubSystem.out.println("投币成功,请按出货按钮!");mVendingMachine.setState(mVendingMachine.mHasCoin);}@Overridepublic void returnCoin() {// TODO Auto-generated method stubSystem.out.println("您还没有投币!");}@Overridepublic void pressButton() {// TODO Auto-generated method stubSystem.out.println("请您先投币!");}@Overridepublic void appearCola() {// TODO Auto-generated method stub}@Overridepublic void printState() {// TODO Auto-generated method stubSystem.out.println("=========售卖中=========");}}/*** * 售空状态类 * @author birdlove1987 * */public class SoldOutState implements State {private VendingMachine mVendingMachine;public SoldOutState(VendingMachine mCandyMachine){this.mVendingMachine=mVendingMachine;}@Overridepublic void insertCoin() {// TODO Auto-generated method stubSystem.out.println("请不要投币了,售货机里已经没有可乐了!");}@Overridepublic void returnCoin() {// TODO Auto-generated method stubSystem.out.println("您还没有投币!");}@Overridepublic void pressButton() {// TODO Auto-generated method stubSystem.out.println("对不起,可乐已售空!");}@Overridepublic void appearCola() {// TODO Auto-generated method stub}@Overridepublic void printState() {// TODO Auto-generated method stubSystem.out.println("=========售空=========");}}/*** * 已投币状态类 * @author birdlove1987 * */public class HasCoin implements State {private VendingMachine mVendingMachine;public HasCoin(VendingMachine mVendingMachine) {this.mVendingMachine = mVendingMachine;}@Overridepublic void insertCoin() {// TODO Auto-generated method stubSystem.out.println("售货机里以及有硬币了,请勿重复投币!");}@Overridepublic void returnCoin(){// TODO Auto-generated method stubSystem.out.println("请在退币口收好您的硬币");mVendingMachine.setState(mVendingMachine.mOnReadyState);}@Overridepublic void pressButton(){// TODO Auto-generated method stubSystem.out.println("请稍等,出可乐中!");//创建随机中奖概率Random anotherOne = new Random();//20%的机会再来一瓶int luck = anotherOne.nextInt(5);if(luck==0){mVendingMachine.setState(mVendingMachine.mOneMoreCola);}else{mVendingMachine.setState(mVendingMachine.mSoldState);}}@Overridepublic void appearCola(){}@Overridepublic void printState() {// TODO Auto-generated method stubSystem.out.println("=========已投币=========");}}/** * 出可乐状态类 * @author birdlove1987 * */public class SoldState implements State {private VendingMachine mVendingMachine;public SoldState(VendingMachine mVendingMachine){this.mVendingMachine=mVendingMachine;}@Overridepublic void insertCoin() {// TODO Auto-generated method stubSystem.out.println("正在出货请勿投币!");}@Overridepublic void returnCoin() {// TODO Auto-generated method stubSystem.out.println("可乐已售出,不能退币");}@Overridepublic void pressButton(){// TODO Auto-generated method stubSystem.out.println("可乐已出,如想再次购买请再次投币!");}@Overridepublic void appearCola() {// TODO Auto-generated method stubmVendingMachine.appearCola();if (mVendingMachine.getCount() > 0) {mVendingMachine.setState(mVendingMachine.mOnReadyState);}else {System.out.println("对不起,可乐已经售空了,请勿在投币!");mVendingMachine.setState(mVendingMachine.mSoldOutState);}}@Overridepublic void printState(){// TODO Auto-generated method stubSystem.out.println("=========出货中=========");}}/*** * 再来一瓶类 * @author birdlove1987 * */public class OneMoreCola implements State {private VendingMachine mVendingMachine;public OneMoreCola(VendingMachine mVendingMachine) {this.mVendingMachine = mVendingMachine;}@Overridepublic void insertCoin() {// TODO Auto-generated method stubSystem.out.println("正在出货请勿投币!");}@Overridepublic void returnCoin() {// TODO Auto-generated method stubSystem.out.println("可乐已售出,不能退币");}@Overridepublic void pressButton() {// TODO Auto-generated method stubSystem.out.println("请稍等,出可乐中!");}@Overridepublic void appearCola() {// TODO Auto-generated method stubmVendingMachine.appearCola();if (mVendingMachine.getCount() == 0) {mVendingMachine.setState(mVendingMachine.mSoldOutState);} else {System.out.println("恭喜你获得了再来一瓶,马上为您再出一瓶可乐");mVendingMachine.appearCola();if (mVendingMachine.getCount() > 0) {mVendingMachine.setState(mVendingMachine.mOnReadyState);}else {System.out.println("对不起,可乐已经售空了,请勿在投币!");mVendingMachine.setState(mVendingMachine.mSoldOutState);}}}@Overridepublic void printState() {// TODO Auto-generated method stubSystem.out.println("=========再来一瓶=========");}}
/** * 自动售货机类 * @author birdlove1987 * */public class VendingMachine {//状态类引用State mSoldOutState;State mOnReadyState;State mHasCoin;State mSoldState;State mOneMoreCola;//目前状态private State state;//可乐计数器private int count = 0;//构造函数public VendingMachine(int count) {this.count = count;mSoldOutState = new SoldOutState(this);mOnReadyState = new OnReadyState(this);mHasCoin = new HasCoin(this);mSoldState = new SoldState(this);mOneMoreCola = new OneMoreCola(this);if (count > 0) {state = mOnReadyState;}else {state = mSoldOutState;}}//设置状态函数public void setState(State state) {this.state = state;}//投币函数public void insertCoin() {state.insertCoin();}//退币函数public void returnCoin() {state.returnCoin();}//按出可乐按钮函数public void pressButton() {state.pressButton();state.appearCola();}//出可乐函数void appearCola() {// TODO Auto-generated method stubif (count > 0){count = count - 1;System.out.println("出货口,滚出了一瓶可乐!");}}//可乐计数函数public int getCount() {return count;}//打印状态函数public void printState() {state.printState();}}
/** * 测试类 * @author birdlove1987 * */public class MainTest {public static void main(String[] args) {//实例化自动贩售机对象VendingMachine mVendingMachine = new VendingMachine(10);//打印状态mVendingMachine.printState();//投币mVendingMachine.insertCoin();//打印状态mVendingMachine.printState();//按出可乐按钮mVendingMachine.pressButton();//打印状态mVendingMachine.printState();//投币mVendingMachine.insertCoin();//打印状态mVendingMachine.printState();//按出可乐按钮mVendingMachine.pressButton();//打印状态mVendingMachine.printState();}}
卧槽!一次都没中奖,什么鬼!!!不行,买买买!!!
中了一次。。。好吧,我来作弊一下。。调到100%
哈哈哈!
状态模式的优点
1.状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
2.将与状态有关的行为封装到一个类中,方便地增加新的状态,只需改变对象状态即可改变对象的行为。
3.提供代码复用性,降低了程序的某些耦合性。
状态模式的缺点
1.有时候状态类会很多,而且逻辑复杂。
状态模式适用场景
1、对象的行为依赖于它的状态,并且其行为依据它的状态改变而改变。
2、代码中包含大量与对象状态有关的条件语句。
1 0
- 设计模式学习笔记之状态模式
- 设计模式学习笔记之状态模式
- 设计模式学习笔记之(状态设计模式)…
- (学习笔记)设计模式之状态模式(游戏场景切换)
- 设计模式学习笔记-状态模式
- 设计模式学习笔记(状态模式)
- 设计模式学习笔记-状态模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记--状态(State)模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记--状态模式
- 设计模式学习笔记-状态模式
- 设计模式学习笔记-状态模式
- [学习笔记]设计模式[a]-{状态模式}
- Hadoop基础学习记录(慕课学习记录,方便查询)
- DP+树状数组——FZU 2236 第十四个目标
- 面试-测试开发如何考察-非应届生
- hdu 1213 How Many Tables(简单的并查集)
- 离线下载安装 NLTK 的 nltk_data 模块
- 设计模式学习笔记之状态模式
- 第5章 广播实现强制下线功能
- 魔兽登陆页面
- 为你的深度学习任务挑选最合适GPU
- ES6十大常用特性
- LeetCode Weekly Contest 24 之 543. Diameter of Binary Tree
- Redis生成验证码
- linux0.11-高速缓冲区(buffer)底层原理
- fzu 2196 Escape 双向bfs