状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了它的类,属于对象的行为模式。
状态模式如何选择:
1.如果代码中存在大量的if-else情况语句。
2.对象的行为跟随状态而改变。
这个模式将状态封装成独立的类,并将动作委托到当前状态的对象,我们知道行为会随着内部状态的改变而改变。从客户的角度来看:如果你使用的对象能够完全改变他的行为,呢么你会觉得,这个对象是从别的类实例化而来的。然而,实际上,你知道我们是在使用组合通过简单引用不同的状态对象来造成类改变的假象。
类图如下:
public class GumballMachine {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state = soldOutState;
int count = 0 ; //记录有多少糖果
public GumballMachine(int numberGumballs) { //初始化,取得糖果数量
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldOutState(this);
this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
}
}
public void insertQuarter(){
state.insertQuarter();
}
public void ejectQuarter(){
state.ejectQuarter();
}
public void turnCrank(){
state.turnCrank();
state.dispense();
}
public void setState(State state){
this.state = state;
}
public void releaseBall(){ //释放糖果
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count -= 1;
}
}
public static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(5);
gumballMachine.setState(gumballMachine.noQuarterState);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
}
}
public class HasQuarterState implements State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You can't insert another quarter");
}
@Override
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.noQuarterState);
}
@Override
public void turnCrank() {
System.out.println("You rurned...");
gumballMachine.setState(gumballMachine.soldState);
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
public class NoQuarterState implements State{
GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.state = gumballMachine.hasQuarterState;
}
@Override
public void ejectQuarter() {
System.out.println("You haven't inserted a quarter");
}
@Override
public void turnCrank() {
System.out.println("You need to pay first");
}
@Override
public void dispense() {
// TODO Auto-generated method stub
}
}
public class SoldOutState implements State{
GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You insert a quarter");
gumballMachine.setState(gumballMachine.hasQuarterState);
}
@Override
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.noQuarterState);
}
@Override
public void turnCrank() {
System.out.println("Sorry,there is no quarter.");
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
public class SoldState implements State{
GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("Please wait,we're already giving you a gumball");
}
@Override
public void ejectQuarter() {
System.out.println("Sorry, you already truned the crank");
}
@Override
public void turnCrank() {
System.out.println("Turning twice doesn't get you another gumball!");
}
@Override
public void dispense() {
gumballMachine.releaseBall();
if (gumballMachine.count > 0) {
gumballMachine.state = gumballMachine.noQuarterState;
}else {
System.out.println("Oops, out of gumballs!");
gumballMachine.state = gumballMachine.soldOutState;
}
}
}
public interface State {
public void insertQuarter();//这里加入投币代码
public void ejectQuarter();//这里加入退币代码
public void turnCrank();//这里加入转动曲柄代码
public void dispense();//这里加入发放糖果代码
}