博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析设计模式之八 状态模式
阅读量:5338 次
发布时间:2019-06-15

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

传统的状态大都是这样的(状态模式)

public class GumballMachine {    final static int SOLD_OUT = 0;    final static int NO_QUARTER = 1;    final static int HAS_QUARTER = 2;    final static int SOLD = 3;            }
然后嵌入大量的if - else
根究当前状态来进行某些操作,但是呢,现在我们是学过设计模式的人了,我们总是想搞出点幺蛾子来封装一下我们想要的东西,换句话说,我们要遵守"封装变化"原则
创建一个接口,填充我们需要的某些行为
/** * 状态接口 * @author Dougest 2017年7月16日    下午11:19:57 * */public interface State {    void insertQuarter();    void ejectQuarter();    void turnCrank();    void dispense();}

然后通过几个实现类来实现我们不同状态写的具体细节

/** * 状态实现类 * @author Dougest 2017年7月16日    下午11:19:57 * */public class SoldState {    void insertQuarter();    void ejectQuarter();    void turnCrank();    void dispense();}
/** * 状态实现类 * @author Dougest 2017年7月16日    下午11:19:57 * */public class SoldOutState {    void insertQuarter();    void ejectQuarter();    void turnCrank();    void dispense();}
/** * 状态实现类 * @author Dougest 2017年7月16日    下午11:19:57 * */public class NoQuarterState {    void insertQuarter();    void ejectQuarter();    void turnCrank();    void dispense();}
/** * 状态实现类 * @author Dougest 2017年7月16日    下午11:19:57 * */public class HasQuarterState {    void insertQuarter();    void ejectQuarter();    void turnCrank();    void dispense();}
现在来具体实现
接口不变,实现新的调用类
/** *  * @author Dougest 2017年7月17日    上午12:10:47 * */public class CompleMachine {    State noQuarterState;    State hasQuarterState;    State soldOutState;    State soldState;        State state = soldOutState;    int count = 0;            public CompleMachine(int numberCompleMachine) {        noQuarterState = new NoQuarterState(this);        hasQuarterState = new HasQuarterState(this);        soldOutState = new SoldOutState(this);        soldState = new SoldState(this);        this.count = numberCompleMachine;                if(numberCompleMachine > 0)            state = noQuarterState;    }        public void insertQuarter() {        state.insertQuarter();            }    public void ejectQuarter() {        state.ejectQuarter();    }    public void turnCrank() {        state.turnCrank();        state.dispense();    }    void setState(State state) {        this.state = state;    }        void releaseBall() {        if(count != 0)            count = count -1;    }        public int getCount() {        return this.count;    }    public State getNoQuarterState() {        return noQuarterState;    }    public void setNoQuarterState(State noQuarterState) {        this.noQuarterState = noQuarterState;    }    public State getHasQuarterState() {        return hasQuarterState;    }    public void setHasQuarterState(State hasQuarterState) {        this.hasQuarterState = hasQuarterState;    }    public State getSoldOutState() {        return soldOutState;    }    public void setSoldOutState(State soldOutState) {        this.soldOutState = soldOutState;    }    public State getSoldState() {        return soldState;    }    public void setSoldState(State soldState) {        this.soldState = soldState;    }    public State getState() {        return state;    }    public void setCount(int count) {        this.count = count;    }

简单的实现某一个状态对象

/** * 状态实现类 * @author Dougest 2017年7月17日    上午12:11:16 * */public class HasQuarterState implements State {    private CompleMachine compleMachine;        public HasQuarterState(CompleMachine compleMachine) {        this.compleMachine = compleMachine;    }            @Override    public void insertQuarter() {        System.out.println("");    }    @Override    public void ejectQuarter() {        System.out.println("");    }    @Override    public void turnCrank() {        System.out.println("");    }    @Override    public void dispense() {        compleMachine.releaseBall();        if(compleMachine.getCount() > 0)            compleMachine.setState(compleMachine.getHasQuarterState());        else             compleMachine.setState(compleMachine.getSoldOutState());    }
现在我们已经做到了如下几点
1.将每个状态的行为局部化到他自己的类中
2.将容易的产生问题的if语句删除,方便日后维护
3.让每一个状态对修改关闭,对扩展开放,因为可以加入新的状态
4.创建了一个新的代码基和类,更能映射我们关于状态的业务逻辑,更容易阅读和理解
 
上面的代码我们实现了
定义状态模式
定义状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修了他的类
 
这个就有点我们前面讲的命令模式的味道了, 定义状态模式将状态封装成对象,并将动作委托给代表当前状态的对象,我们知道行为会随着内部状态而改变
 
这里有一个习惯,如果没有共同的功能可以放在抽象类中,我们通常使用接口,就比如这个demo
 

 

 
要点:
状态模式允许一个对象基于内部的状态而拥有不同的行为
和程序状态机(PSM)不同,状态模式用类代表状态
context会将行为委托给当前状态对象
通过将每一个状态封装成对象,我们把以后需要做的任何改变局部化了
状态模式和策略模式有相同的类图,但是他们的意图不一样
策略模式通常会用行为或者算法来配置context类
状态模式允许context类随着状态的改变而改变行为
状态转换可以有State类或者context类控制
使用状态模式通常会使设计中出现大量的类
状态类可以被多个context共享
 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/dougest/p/7192562.html

你可能感兴趣的文章
HAL层三类函数及其作用
查看>>
Odoo 去掉 恼人的 "上午"和"下午"
查看>>
web@h,c小总结
查看>>
java编程思想笔记(一)——面向对象导论
查看>>
Data Structure 基本概念
查看>>
Ubuntu改坏sudoers后无法使用sudo的解决办法
查看>>
NEYC 2017 游记
查看>>
[搬运] 写给 C# 开发人员的函数式编程
查看>>
Python之旅Day14 JQuery部分
查看>>
core--线程池
查看>>
redux-effect
查看>>
Swift和OC混编
查看>>
Android轻量级的开源缓存框架ASimpleCache
查看>>
他山之石:加载图片的一个小问题
查看>>
shell - 常识
查看>>
mssql sqlserver 使用sql脚本 清空所有数据库表数据的方法分享
查看>>
分层图最短路【bzoj2763】: [JLOI2011]飞行路线
查看>>
linux下编译复数类型引发的错误:expected unqualified-id before '(' token
查看>>
codeforces 1041A Heist
查看>>
字典常用方法
查看>>