在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。
在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。
状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if...else 等条件选择语句。
下面是一个糖果机的例子:
四个动作:插入硬币,回退硬币,转动把手,分发糖果(这个是糖果机内部的方法不需要暴露给用户)
五个状态:准备状态,有硬币状态,出售状态,售完状态,赢者状态(10%赢者可以得到两个糖果)
待机
投入一元硬币
转动把手
滑落一颗糖果
待机(根据机器内糖果库存情况,是否提示出售)
public interface State {
public void insertCoin();
public void returnCoin();
public void turnCrank();
public void dispense();
public void printstate();
}
public class CandyMachine {
State mSoldOutState;
State mOnReadyState;
State mHasCoin;
State mSoldState;
State mWinnerState;
private State state;
private int count=0;
public CandyMachine(int count){
this.count=count;
mSoldOutState=new SoldOutState(this);
mOnReadyState=new OnReadyState(this);
mHasCoin=new HasCoin(this);
mSoldState=new SoldState(this);
mWinnerState=new WinnerState(this);
if(count>0){
state=mOnReadyState;
}else{
state=mSoldOutState;
}
}
public void setState(State state){
this.state=state;
}
public void insertCoin(){
state.insertCoin();
}
public void returnCoin(){
state.returnCoin();
}
public void turnCrank(){//转动摇柄
state.turnCrank();
state.dispense();
}
void releaseCandy(){
if(count>0){
count=count-1;
System.out.println("a candy rolling out");
}
}
public int getCount(){
return count;
}
public void printstate(){
state.printstate();
}
}
public class HasCoin implements State{
private CandyMachine mCandyMachine;
public HasCoin(CandyMachine mCandyMachine){
this.mCandyMachine=mCandyMachine;
}
@Override
public void insertCoin() {
System.out.println("you cant't insert another coin");
}
@Override
public void returnCoin() {
System.out.println("coin return");
mCandyMachine.setState(mCandyMachine.mOnReadyState);
}
@Override
public void turnCrank() {
System.out.println("crank turn....");
Random ranwinner=new Random();
int winner=ranwinner.nextInt(10);
if(winner==0){
mCandyMachine.setState(mCandyMachine.mWinnerState);
}else{
mCandyMachine.setState(mCandyMachine.mSoldState);
}
}
@Override
public void dispense() {
}
@Override
public void printstate() {
System.out.println("****HasCoin****");
}
}
public class OnReadyState implements State{
private CandyMachine mCandyMachine;
public OnReadyState(CandyMachine mCandyMachine){
this.mCandyMachine=mCandyMachine;
}
@Override
public void insertCoin() {
System.out.println("you have inserted a coin,next please turn crank");
mCandyMachine.setState(mCandyMachine.mHasCoin);
}
@Override
public void returnCoin() {
System.out.println("you haven't inserted a coin yet");
}
@Override
public void turnCrank() {
System.out.println("you turned,but you haven't inserted coin");
}
@Override
public void dispense() {
}
@Override
public void printstate() {
System.out.println("*****OnReadyState****");
}
}
public class SoldOutState implements State{
private CandyMachine mCandyMachine;
public SoldOutState(CandyMachine mCandyMachine){
this.mCandyMachine=mCandyMachine;
}
@Override
public void insertCoin() {
System.out.println("you can't insert coin,the machine sold out");
}
@Override
public void returnCoin() {
System.out.println("you can't return,you haven't inserted a coin");
}
@Override
public void turnCrank() {
System.out.println("you turned,but there are no candies");
}
@Override
public void dispense() {
}
@Override
public void printstate() {
System.out.println("****SoldOutState****");
}
}
public class SoldState implements State{
private CandyMachine mCandyMachine;
public SoldState(CandyMachine mCandyMachine){
this.mCandyMachine=mCandyMachine;
}
@Override
public void insertCoin() {
System.out.println("please wait,we are giving you a candy");
}
@Override
public void returnCoin() {
System.out.println("you haven't inserted a coin yet");
}
@Override
public void turnCrank() {
System.out.println("we are giving you a candy,turning another get nothing");
}
@Override
public void dispense() {
mCandyMachine.releaseCandy();
if(mCandyMachine.getCount()>0){
mCandyMachine.setState(mCandyMachine.mOnReadyState);
}else{
System.out.println("Oo,out of candies");
mCandyMachine.setState(mCandyMachine.mSoldOutState);
}
}
@Override
public void printstate() {
System.out.println("****SoldState****");
}
}
public class WinnerState implements State{
private CandyMachine mCandyMachine;
public WinnerState(CandyMachine mCandyMachine){
this.mCandyMachine=mCandyMachine;
}
@Override
public void insertCoin() {
System.out.println("please wait,we are giving you a candy");
}
@Override
public void returnCoin() {
System.out.println("you haven't inseted a coin");
}
@Override
public void turnCrank() {
System.out.println("we are giving you a candy");
}
@Override
public void dispense() {
mCandyMachine.releaseCandy();
if(mCandyMachine.getCount()==0){
mCandyMachine.setState(mCandyMachine.mSoldOutState);
}else{
System.out.println("you are a winner,you get another candy");
mCandyMachine.releaseCandy();
if(mCandyMachine.getCount()>0){
mCandyMachine.setState(mCandyMachine.mOnReadyState);
}else{
System.out.println("Oo,Out of candies");
mCandyMachine.setState(mCandyMachine.mSoldOutState);
}
}
}
@Override
public void printstate() {
System.out
.println("****WinnerSteate****");
}
}
public class CandyTest {
public static void main(String[] args){
CandyMachine mCandyMachine=new CandyMachine(6);
mCandyMachine.printstate();
mCandyMachine.insertCoin();;
mCandyMachine.printstate();
mCandyMachine.turnCrank();
mCandyMachine.printstate();
mCandyMachine.insertCoin();
mCandyMachine.printstate();
mCandyMachine.turnCrank();
mCandyMachine.printstate();
}
}