当前位置: 移动技术网 > IT编程>软件设计>设计模式 > 设计模式之状态模式(二)

设计模式之状态模式(二)

2019年08月28日  | 移动技术网IT编程  | 我要评论
在上一次的文章里,我们看到,需求的变更,迫使我们需要重新改造现有的糖果机代码来符合这个新提的需求。但是,也并没有难倒我们,至少我们在文末给出了思路和类图,不知道你想的怎么样了呢。 我们不来虚的,直接进入正题,开启我们的学习之旅。 实现我们的状态类 现在是实现一个状态的时候了:我们知道我们要的行为是什 ...

在上一次的文章里,我们看到,需求的变更,迫使我们需要重新改造现有的糖果机代码来符合这个新提的需求。但是,也并没有难倒我们,至少我们在文末给出了思路和类图,不知道你想的怎么样了呢。

我们不来虚的,直接进入正题,开启我们的学习之旅。

实现我们的状态类

现在是实现一个状态的时候了:我们知道我们要的行为是什么,我们只需要把它变成代码。我们打算完全遵守所写下的状态机代码,但是这一次是分散在不同的类中。比如我们以noquarterstate类为例。

public class noquarterstate implements state {
    gumballmachine gumballmachine;
 
    public noquarterstate(gumballmachine gumballmachine) {
        this.gumballmachine = gumballmachine;
    }
 
    public void insertquarter() {
        system.out.println("you inserted a quarter");
        gumballmachine.setstate(gumballmachine.gethasquarterstate());
    }
 
    public void ejectquarter() {
        system.out.println("you haven't inserted a quarter");
    }
 
    public void turncrank() {
        system.out.println("you turned, but there's no quarter");
     }
 
    public void dispense() {
        system.out.println("you need to pay first");
    } 
    
}

在完成这些状态类之前,我们需要重新改造糖果机,好让你了解这一切的原理。我们把原来使用整数代表的状态改为状态对象:

    state soldoutstate;
    state noquarterstate;
    state hasquarterstate;
    state soldstate;
 
    state state;
    int count = 0;

这样,我们就有了一个完整的糖果机类

public class gumballmachine {
 
    state soldoutstate;
    state noquarterstate;
    state hasquarterstate;
    state soldstate;
 
    state state;
    int count = 0;
 
    public gumballmachine(int numbergumballs) {
        soldoutstate = new soldoutstate(this);
        noquarterstate = new noquarterstate(this);
        hasquarterstate = new hasquarterstate(this);
        soldstate = new soldstate(this);

        this.count = numbergumballs;
        if (numbergumballs > 0) {
            state = noquarterstate;
        } else {
            state = soldoutstate;
        }
    }
 
    public void insertquarter() {
        state.insertquarter();
    }
 
    public void ejectquarter() {
        state.ejectquarter();
    }
 
    public void turncrank() {
        state.turncrank();
        state.dispense();
    }
 
    void releaseball() {
        system.out.println("a gumball comes rolling out the slot...");
        if (count != 0) {
            count = count - 1;
        }
    }
 
    // 后面部分省略
}

好了,这样子,我们就能继续实现更多的状态类了。比如我们能实现hasquarterstate和soldstate类

public class hasquarterstate implements state {
    gumballmachine gumballmachine;
 
    public hasquarterstate(gumballmachine gumballmachine) {
        this.gumballmachine = gumballmachine;
    }
  
    public void insertquarter() {
        system.out.println("you can't insert another quarter");
    }
 
    public void ejectquarter() {
        system.out.println("quarter returned");
        gumballmachine.setstate(gumballmachine.getnoquarterstate());
    }
 
    public void turncrank() {
        system.out.println("you turned...");
        gumballmachine.setstate(gumballmachine.getsoldstate());
    }

    public void dispense() {
        system.out.println("no gumball dispensed");
    }
    
}
public class soldstate implements state {
 
    gumballmachine gumballmachine;
 
    public soldstate(gumballmachine gumballmachine) {
        this.gumballmachine = gumballmachine;
    }
       
    public void insertquarter() {
        system.out.println("please wait, we're already giving you a gumball");
    }
 
    public void ejectquarter() {
        system.out.println("sorry, you already turned the crank");
    }
 
    public void turncrank() {
        system.out.println("turning twice doesn't get you another gumball!");
    }
 
    public void dispense() {
        gumballmachine.releaseball();
        if (gumballmachine.getcount() > 0) {
            gumballmachine.setstate(gumballmachine.getnoquarterstate());
        } else {
            system.out.println("oops, out of gumballs!");
            gumballmachine.setstate(gumballmachine.getsoldoutstate());
        }
    }
    
}

检查一下,到目前为止我们做了啥

你现在有了一个糖果机的实现,他在结构上和前一个版本差异很大,但是功能上却是一样的。我们发现,你已经实现了以下几点:

  • 将每个状态的行为局部化到它自己的类中

  • 将容易产生问题的if语句删除,以方便日后的维护

  • 让每个状态“对修改关闭”,让糖果机“对扩展开放”,因为可以加入新的状态类

  • 创建一个新的代码基和类结构,这更能映射万能糖果公司的图,而且更容易阅读和理解

定义状态模式

是的,就在刚才,我们已经实现了状态模式。现在让我们来看看什么是状态模式。

状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

让我们好好看下状态模式的类图:

这个类图和策略模式的类图是一样的。但是虽然类图是一样的,但是两个模式的差别在于它们的“意图”不同。状态模式将一群行为封装在状态对象中,context行为随时可委托到那些状态对象中的一个。对于策略模式而言,客户通常主动指定context所要组合的策略对象是哪一个。

等等等等,之前不是说有十次抽中一次的游戏吗?怎么还没写出来呢?哈哈哈哈,不急不急,以上内容你都消化了吗?如果你消化的话,请你耐心等待,倘若没有,那请你先好好学习这些吧。我将在下次把抽奖这个搞定。

拜拜!

「奔跑吧攻城狮」感谢大家的关注,现在后台回复「设计模式」赠你小编精心挑选设计模式书籍。小编最近开窍,组建了一个技术交流群,回复「加群」即可解锁。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网