设计模式学习四、状态模式

来源:互联网 发布:java开发桌面应用 编辑:程序博客网 时间:2024/06/05 03:11

一、什么是状态模式

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

二、什么时候用状态模式?

       当控制一个对象状态转换的条件表达式过于复杂时,使用状态模式。把状态的判断逻辑转移到表示不同的一系列类当中,可以把复杂的逻辑判断简单化。(避免了写很多的if。。。。else)

三、状态模式构成

          

    Context上下文:定义一个客户端需要的接口,维护一个具体状态角色的实例并将所有动作交由当前状态对象处理。
    State:一个接口,用于定义与Context行为相关的特定状态
    ConcreteState:具体的某个状态

四、举个例子

     一家公司发明了一款糖果机,需要你设计一个程序来控制糖果机的运行。初始状态下:糖果机中没有任何糖果,当有人投入硬币后,可以选择按钮以此来获得糖果,或者选择退钱按钮以此来退出钱。如果当前选择了获取糖果,糖果机中吐出一个糖果,当糖果机中的糖果数量为0时候,糖果机进入停运状态。
分析:这其中涉及糖果机状态的转换:
        起初:糖果机为未支付状态(noPayment)—(支付硬币)—>已支付状态—(按吐糖果按钮)—>售出糖果—[(如果糖果数量为0)—>停运状态,],[(如果不为0)->未支付状态] 
也可以是:未支付状态(noPayment)—(支付硬币)—>已支付状态—(退钱)—>未支付状态
     这里面涉及四个状态:未支付状态,以支付状态,出售糖果状态,停运状态
动作:投币,按吐糖果按钮,退钱,发放糖果

  

class SugerMachine{    private int count;    private State noPaymentState;    private State paymentState;    private State soldState;    private State outAgeState;    private State  currentState;    public  SugerMachine(int count){        this.count=count;        noPaymentState=new NoPaymentState(this);        paymentState=new PaymentState(this);        soldState=new SoldState(this);        outAgeState=new PaymentState(this);        this.currentState=noPaymentState;    }    public void payMent(){        this.currentState.payMent();    }    public void ejectMeney(){        this.currentState.ejectMoney();    }    public  void trunMoney(){        this.currentState.turnButton();        this.currentState.grantSuger();//这是一个内部动作,不需要外部用户访问    }    public void setState(State state){        this.currentState=state;    }    public State getNoPaymentState() {        return noPaymentState;    }    public State getOutAgeState() {        return outAgeState;    }    public State getSoldState() {        return soldState;    }    public State getPaymentState() {        return paymentState;    }    public int getCount() {        return count;    }    public void removeSuger(){        this.count-=1;    }}/** * 抽象状态 */interface  State{    public void payMent();    public void ejectMoney();    public void turnButton();    public void grantSuger();}/** * 以下为具体的四个状态 */class NoPaymentState implements  State{    private SugerMachine sugerMachine;    public NoPaymentState(SugerMachine SugerMachine) {        this.sugerMachine = SugerMachine;    }    @Override    public void payMent() {        sugerMachine.setState(sugerMachine.getPaymentState());        System.out.println("支付成功,继续操作");    }    @Override    public void ejectMoney() {        System.out.println("没有支付");    }    @Override    public void turnButton() {        System.out.println("没钱,按了没用~~");    }    @Override    public void grantSuger() {        System.out.println("没钱,不给你糖");    }}class PaymentState implements  State{    private SugerMachine sugerMachine;    public PaymentState(SugerMachine sugerMachine) {        this.sugerMachine=sugerMachine;    }    @Override    public void payMent() {        System.out.println("已经支付,不需要支付");    }    @Override    public void ejectMoney() {        sugerMachine.setState(sugerMachine.getNoPaymentState());        System.out.println("退钱成功,返回未支付状态");    }    @Override    public void turnButton() {        sugerMachine.setState(sugerMachine.getSoldState());        System.out.println("正在处理");    }    @Override    public void grantSuger() {        System.out.println("当前不支持");    }}class SoldState implements  State{    private SugerMachine sugerMachine;    public  SoldState(SugerMachine sugerMachine){        this.sugerMachine=sugerMachine;    }    @Override    public void payMent() {        System.out.println("当前不允许支付");    }    @Override    public void ejectMoney() {        System.out.println("当前不允许退钱");    }    @Override    public void turnButton() {        System.out.println("当前不允许按按钮");    }    @Override    public void grantSuger() {        int count=sugerMachine.getCount();        if (count>0){            System.out.println("给你,糖果~~");            sugerMachine.setState(sugerMachine.getNoPaymentState());        }else{            sugerMachine.setState(sugerMachine.getOutAgeState());            System.out.println("糖果没了,抱歉");        }    }}class OutAgeState implements  State{    private SugerMachine sugerMachine;    public OutAgeState(SugerMachine sugerMachine) {        this.sugerMachine = sugerMachine;    }    @Override    public void payMent() {        System.out.println("当前不支持");    }    @Override    public void ejectMoney() {        System.out.println("当前不支持");    }    @Override    public void turnButton() {        System.out.println("当前不支持");    }    @Override    public void grantSuger() {        System.out.println("当前不支持");    }}public class State1Test {    public  static  void main(String args[]){        SugerMachine sugerMachine=new SugerMachine(5);        sugerMachine.payMent();        sugerMachine.ejectMeney();        sugerMachine.payMent();        sugerMachine.trunMoney();    }}

输出:

支付成功,继续操作
退钱成功,返回未支付状态
支付成功,继续操作
正在处理
给你,糖果~~

五、总结:

        通过状态模式,在扩展新功能的时候,只需要添加新的状态类即可,实现了对扩展开放,对修改关闭的原则。

        将各种状态的转换放在子类中实现,减少了互相的依赖。但造成很多子类的生成。

          

原创粉丝点击