针对问题:有时候一个方法可能有很多if..else来判断状态后再执行相关操作,当很多方法都重复的出现这样的if..else判断时,就可以考虑用状态模式了。
状态模式的结构图和策略模式一样,事实上状态模式和策略很相似,不同的是状态模式除了委托状态外,状态实体自身持有主实体对象的引用,在状态实体内部可以动态的改变主实体的状态。
状态模式结构图:
状态模式实现代码:
/**
* 状态接口
* @author bruce
*
*/
public interface State {
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
}
/**
* 有钱状态
* @author bruce
*
*/
public class HasQuarterState implements State{
GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
public void dispense() {
// TODO Auto-generated method stub
System.out.println("No gumball dispensed");
}
public void ejectQuarter() {
// TODO Auto-generated method stub
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("You can't insert another quarter");
}
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("You returned...");
gumballMachine.setState(gumballMachine.getSoldState());
}
}
/**
* 没钱状态
* @author bruce
*
*/
public class NoQuarterState implements State{
private GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
public void dispense() {
// TODO Auto-generated method stub
System.out.println("You need to pay first");
}
public void ejectQuarter() {
// TODO Auto-generated method stub
System.out.println("You haven't inserted a quarter");
}
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("You inserted a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("You turned,but there's no quarter");
}
}
/**
* 售出状态
* @author bruce
*
*/
public class SoldState implements State{
private GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
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 void ejectQuarter() {
// TODO Auto-generated method stub
System.out.println("Sorry, you already turned the crank");
}
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("Please wait, we're already giving you a gumball");
}
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("Turning twice doesn't get you another gumball!");
}
}
/**
* 卖完状态
* @author bruce
*
*/
public class SoldOutState implements State{
@SuppressWarnings("unused")
private GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine){
this.gumballMachine=gumballMachine;
}
public void dispense() {
// TODO Auto-generated method stub
System.out.println("No gumball dispensed");
}
public void ejectQuarter() {
// TODO Auto-generated method stub
System.out.println("You can't eject, you haven't inserted a quarter yet");
}
public void insertQuarter() {
// TODO Auto-generated method stub
System.out.println("You can't insert a quarter,the machine is sold out");
}
public void turnCrank() {
// TODO Auto-generated method stub
System.out.println("You turned, but there are no gumballs");
}
}
/**
* 糖果机
* @author bruce
*
*/
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 SoldState(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();
}
void setState(State state){
this.state=state;
}
void releaseBall(){
System.out.println("A gumball comes rolling out the slot...");
if(count !=0){
count=count-1;
}
}
public State getSoldOutState() {
return soldOutState;
}
public State getNoQuarterState() {
return noQuarterState;
}
public State getHasQuarterState() {
return hasQuarterState;
}
public State getSoldState() {
return soldState;
}
public State getState() {
return state;
}
public int getCount() {
return count;
}
}
/**
* 测试
* @author bruce
*
*/
public class Client {
public static void main(String[] args) {
GumballMachine gumballMachine=new GumballMachine(5);
System.out.println("-------------");
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.out.println("-------------");
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
System.out.println("-------------");
/**
* output:
* -------------
You inserted a quarter
You returned...
A gumball comes rolling out the slot...
-------------
You inserted a quarter
You returned...
A gumball comes rolling out the slot...
You inserted a quarter
You returned...
A gumball comes rolling out the slot...
-------------
*/
}
}