您的位置:首页 > 编程语言 > Java开发

设计模式 - 状态模式(state pattern) 详解

2014-07-11 17:42 218 查看

状态模式(state pattern) 详解

本文地址: http://blog.csdn.net/caroline_wendy

状态模式(state pattern): 允许对象在内部状态改变时改变它的行为, 对象看起来好像修改了它的类.

建立Context类, 包含多个具体状态(concrete state)类的组合, 根据状态的不同调用具体的方法, state.handle(), 包含set\get方法改变状态.
状态接口(state interface), 包含抽象方法handle(), 具体状态类(concrete state)继承(implement)状态类(state), 实现handle()方法;

具体方法:
1. Context类, 组合多个具体状态类(concrete state), 并提供set\get方法, 调用状态的方法(handle), 改变状态.
/**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public class GumballMachine {

State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;

State state = soldOutState;
int count = 0;

/**
*
*/
public GumballMachine(int numberGumballs) {
// TODO Auto-generated constructor stub
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(this);

this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
}
}

public void insertQuarter() {
state.insertQuarter();
}

public void ejectQuarter() {
state.ejectQuater();
}

public void turnCrank() {
state.turnCrank();
state.dispense();
}

void setState(State state) {
this.state = state;
}

void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0)
count --;
}

int getCount() {
return count;
}

void refill(int count) {
this.count = count;
state = noQuarterState;
}

public State getState() {
return state;
}

public State getSoldOutState() {
return soldOutState;
}

public State getNoQuarterState() {
return noQuarterState;
}

public State getHasQuarterState() {
return hasQuarterState;
}

public State getSoldState() {
return soldState;
}

public State getWinnerState() {
return winnerState;
}

public String toString() {
StringBuffer result = new StringBuffer();
result.append("\nMighty Gumball, Inc.");
result.append("\nJava-enabled Standing Gumball Model #2004\n");
result.append("Inventory: " + count + " gumball");
if (count != 1) {
result.append("s");
}
result.append("\nMachine is " + state + "\n");
return result.toString();
}
}
2. 状态接口(state interface), 包含抽象方法(handle)./**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public interface State {
void insertQuarter();
void ejectQuater();
void turnCrank();
void dispense();
}

3. 具体状态类(concrete state), 继承(implement)状态接口(state interface), 实现抽象方法(handle)./**
* @time 2014年7月11日
*/
package state.pattern;

import java.util.Random;

/**
* @author C.L.Wang
*
*/
public class HasQuarterState implements State {

Random randomWinner = new Random(System.currentTimeMillis());
GumballMachine gumballMachine;
/**
*
*/
public HasQuarterState(GumballMachine gumballMachine) {
// TODO Auto-generated constructor stub
this.gumballMachine = gumballMachine;
}

/* (non-Javadoc)
* @see state.pattern.State#insertQuarter()
*/
@Override
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("You can't insert another quarter.");
}

/* (non-Javadoc)
* @see state.pattern.State#ejectQuater()
*/
@Override
public void ejectQuater() {
// TODO Auto-generated method stub
System.out.println("Quarter returned.");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}

/* (non-Javadoc)
* @see state.pattern.State#turnCrank()
*/
@Override
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("You turned...");
int winner = randomWinner.nextInt(4);
if ((winner == 0) && (gumballMachine.getCount()>1)) { //需要多于1个糖果
gumballMachine.setState(gumballMachine.getWinnerState());
} else {
gumballMachine.setState(gumballMachine.getSoldState());
}
}

/* (non-Javadoc)
* @see state.pattern.State#dispense()
*/
@Override
public void dispense() {
// TODO Auto-generated method stub
System.out.println("No gumball dispensed.");
}

public String toString() {
return "waiting for turn of crank";
}

}

/**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public class NoQuarterState implements State {

GumballMachine gumballMachine;

/**
*
*/
public NoQuarterState(GumballMachine gumballMachine) {
// TODO Auto-generated constructor stub
this.gumballMachine = gumballMachine;
}

/* (non-Javadoc)
* @see state.pattern.State#insertQuarter()
*/
@Override
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("You inserted a quarter.");
gumballMachine.setState(gumballMachine.getHasQuarterState());

}

/* (non-Javadoc)
* @see state.pattern.State#ejectQuater()
*/
@Override
public void ejectQuater() {
// TODO Auto-generated method stub
System.out.println("You haven't inserted a quarter.");
}

/* (non-Javadoc)
* @see state.pattern.State#turnCrank()
*/
@Override
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("You turned, but there's no quarter.");
}

/* (non-Javadoc)
* @see state.pattern.State#dispense()
*/
@Override
public void dispense() {
// TODO Auto-generated method stub
System.out.println("You need to pay first.");

}

public String toString() {
return "waiting for quater";
}

}

/**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public class SoldOutState implements State {

GumballMachine gumballMachine;
/**
*
*/
public SoldOutState(GumballMachine gumballMachine) {
// TODO Auto-generated constructor stub
this.gumballMachine = gumballMachine;
}

/* (non-Javadoc)
* @see state.pattern.State#insertQuarter()
*/
@Override
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("You can't insert a quarter, the machine is sold out.");

}

/* (non-Javadoc)
* @see state.pattern.State#ejectQuater()
*/
@Override
public void ejectQuater() {
// TODO Auto-generated method stub
System.out.println("You can't eject, you haven't inserted a quarter yet");
}

/* (non-Javadoc)
* @see state.pattern.State#turnCrank()
*/
@Override
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("You turned, but there are no gambulls.");
}

/* (non-Javadoc)
* @see state.pattern.State#dispense()
*/
@Override
public void dispense() {
// TODO Auto-generated method stub
System.out.println("No gumball dispensed.");
}

public String toString() {
return "sold out";
}

}

/**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public class SoldState implements State {

GumballMachine gumballMachine;

/**
*
*/
public SoldState(GumballMachine gumballMachine) {
// TODO Auto-generated constructor stub
this.gumballMachine = gumballMachine;
}

/* (non-Javadoc)
* @see state.pattern.State#insertQuarter()
*/
@Override
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("Please wait, we're already giving you a gumball.");
}

/* (non-Javadoc)
* @see state.pattern.State#ejectQuater()
*/
@Override
public void ejectQuater() {
// TODO Auto-generated method stub
System.out.println("Sorry, you already turned the crank.");
}

/* (non-Javadoc)
* @see state.pattern.State#turnCrank()
*/
@Override
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("Turning twice doesn't give you another gumball.");
}

/* (non-Javadoc)
* @see state.pattern.State#dispense()
*/
@Override
public void dispense() {
// TODO Auto-generated method stub
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("Oops, out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}

public String toString() {
return "dispensing a gumball";
}

}

/**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public class WinnerState implements State {

GumballMachine gumballMachine;

/**
*
*/
public WinnerState(GumballMachine gumballMachine) {
// TODO Auto-generated constructor stub
this.gumballMachine = gumballMachine;
}

/* (non-Javadoc)
* @see state.pattern.State#insertQuarter()
*/
@Override
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("Please wait, we're already giving you a Gumball");
}

/* (non-Javadoc)
* @see state.pattern.State#ejectQuater()
*/
@Override
public void ejectQuater() {
// TODO Auto-generated method stub
System.out.println("Please wait, we're already giving you a Gumball");
}

/* (non-Javadoc)
* @see state.pattern.State#turnCrank()
*/
@Override
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("Turning again doesn't give you another gumball!");
}

/* (non-Javadoc)
* @see state.pattern.State#dispense()
*/
@Override
public void dispense() {
// TODO Auto-generated method stub
System.out.println("YOU'RE A WINNER! you get two gumballs for your quarter.");
gumballMachine.releaseBall();
if (gumballMachine.getCount() == 0) {
gumballMachine.setState(gumballMachine.getSoldOutState());
} else {
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0) {
gumballMachine.setState(gumballMachine.getNoQuarterState());
} else {
System.out.println("Oops, out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}

public String toString() {
return "despensing two gumballs for your quarter, because YOU'RE A WINNER!";
}
}

4. 测试类./**
* @time 2014年7月11日
*/
package state.pattern;

/**
* @author C.L.Wang
*
*/
public class GumballMachineTestDrive {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GumballMachine gumballMachine = new GumballMachine(5);

System.out.println(gumballMachine);

gumballMachine.insertQuarter();
gumballMachine.turnCrank();

System.out.println(gumballMachine);

gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();

System.out.println(gumballMachine);
}

}

5. 输出. 中奖2次.Mighty, Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 5 gumballs
Machine is waiting for quater

You inserted a quarter.
You turned...
A gumball comes rolling out the slot...

Mighty Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 4 gumballs
Machine is waiting for quater

You inserted a quarter.
You turned...
YOU'RE A WINNER! you get two gumballs for your quarter.
A gumball comes rolling out the slot...
A gumball comes rolling out the slot...
You inserted a quarter.
You turned...
YOU'RE A WINNER! you get two gumballs for your quarter.
A gumball comes rolling out the slot...
A gumball comes rolling out the slot...
Oops, out of gumballs!

Mighty Gumball, Inc.
Java-enabled Standing Gumball Model #2004
Inventory: 0 gumballs
Machine is sold out


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息