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

一、什么是状态模式

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

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

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

输出:

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

五、总结:

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

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

          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值