您的位置:首页 > 其它

设计模式之状态模式浅析

2014-12-18 22:03 183 查看
/**
*
* 状态模式:
*   允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类
*
* 封装基于状态的行为,并将行为委托到当前状态
* 通过把状态封装进一个类,把以后要做的事情局部化了
*
* 策略模式和状态模式有相同的类图,但是彼此的意图不同
*
* State接口定义了一个所有具体状态的共同接口
* Context是一个类,他可以拥有一些内部状态   糖果机就是Context
*
* 示例
*   糖果机模型
*    5个状态:没有5块钱状态、有5块钱状态、赢家模式状态、出售糖果状态  、糖果售罄状态
*    4个动作:投5块钱、退5块钱、按钮售出按钮、售出糖果
*
*
* @author Administrator
*
*/


状态接口 封装行为

package com.undergrowth.state;

/** * * 状态模式: * 允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类 * * 封装基于状态的行为,并将行为委托到当前状态 * 通过把状态封装进一个类,把以后要做的事情局部化了 * * 策略模式和状态模式有相同的类图,但是彼此的意图不同 * * State接口定义了一个所有具体状态的共同接口 * Context是一个类,他可以拥有一些内部状态 糖果机就是Context * * 示例 * 糖果机模型 * 5个状态:没有5块钱状态、有5块钱状态、赢家模式状态、出售糖果状态 、糖果售罄状态 * 4个动作:投5块钱、退5块钱、按钮售出按钮、售出糖果 * * * @author Administrator * */
public interface State {

public void insertCoins();
public void coinsHopper();
public void pressSold();
public void soldCandy();

}


没有5块钱状态

package com.undergrowth.state;

/**
* 没有5块钱的状态
* @author Administrator
*
*/
public class NoMoneyState implements State {

GumballMachine gumballMachine;

public NoMoneyState(GumballMachine gumballMachine) {
super();
this.gumballMachine = gumballMachine;
}

@Override
public void insertCoins() {
// TODO Auto-generated method stub
System.out.println("你投了5块钱");
gumballMachine.setState(gumballMachine.getHasMoneyState());
}

@Override
public void coinsHopper() {
// TODO Auto-generated method stub
System.out.println("你没有投钱,甭想退钱");
}

@Override
public void pressSold() {
// TODO Auto-generated method stub
System.out.println("你没有投钱,甭想买糖果");
}

@Override
public void soldCandy() {
// TODO Auto-generated method stub
System.out.println("你没有投钱,甭想买糖果");
}

}


有5块钱状态
package com.undergrowth.state;

import java.util.Random;

public class HasMoneyState implements State {

GumballMachine gumballMachine;
// 记录是够进入玩家模式
Random randomWinner = new Random(System.currentTimeMillis());

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

@Override
public void insertCoins() {
// TODO Auto-generated method stub
System.out.println("已经投过币了,不要在投币了");
}

@Override
public void coinsHopper() {
// TODO Auto-generated method stub
System.out.println("退币成功");
gumballMachine.setState(gumballMachine.getNoMoneyState());
}

@Override
public void pressSold() {
// TODO Auto-generated method stub
System.out.println("你按下售出糖果按钮,即将售出糖果");
int winner = randomWinner.nextInt(10);
//十分之一机会 进入赢家模式
if (winner == 0 && gumballMachine.getCount() > 1) {
gumballMachine.setState(gumballMachine.getWinnerState());
} else {
gumballMachine.setState(gumballMachine.getSoldState());
}

}

@Override
public void soldCandy() {
// TODO Auto-generated method stub
System.out.println("你没有操作,甭想售出糖果");
}

}


售出糖果状态

package com.undergrowth.state;

public class SoldState implements State {

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

@Override
public void insertCoins() {
// TODO Auto-generated method stub
System.out.println("正在售出糖果,不要投币");
}

@Override
public void coinsHopper() {
// TODO Auto-generated method stub
System.out.println("正在售出糖果,不要退币");
}

@Override
public void pressSold() {
// TODO Auto-generated method stub
System.out.println("正在售出糖果,不要再按下售出按钮了");
}

@Override
public void soldCandy() {
// TODO Auto-generated method stub
gumballMachine.releaseCandy();
if(gumballMachine.getCount()>0){
gumballMachine.setState(gumballMachine.getNoMoneyState());
}else {
System.out.println("没有糖果了,进入糖果售罄状态");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}

}


赢家模式状态

package com.undergrowth.state;

public class WinnerState implements State {

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

@Override
public void insertCoins() {
// TODO Auto-generated method stub
System.out.println("正在售出糖果,不要投币");
}

@Override
public void coinsHopper() {
// TODO Auto-generated method stub
System.out.println("正在售出糖果,不要退币");
}

@Override
public void pressSold() {
// TODO Auto-generated method stub
System.out.println("正在售出糖果,不要再按下售出按钮了");
}

@Override
public void soldCandy() {
// TODO Auto-generated method stub
System.out.println("你进入了赢家模式,会获得两个糖果");
gumballMachine.releaseCandy();
if(gumballMachine.getCount()==0){
System.out.println("没有糖果了,进入糖果售罄状态");
gumballMachine.setState(gumballMachine.getSoldOutState());
}else {
gumballMachine.releaseCandy();
if(gumballMachine.getCount()>0){
gumballMachine.setState(gumballMachine.getNoMoneyState());
}else {
System.out.println("没有糖果了,进入糖果售罄状态");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
}

}


糖果售完状态

package com.undergrowth.state;

public class SoldOutState implements State {

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

@Override
public void insertCoins() {
// TODO Auto-generated method stub
System.out.println("没有糖果了,不要投币");
}

@Override
public void coinsHopper() {
// TODO Auto-generated method stub
System.out.println("没有糖果了,不要退币");
}

@Override
public void pressSold() {
// TODO Auto-generated method stub
System.out.println("没有糖果了,不要按下售出按钮");
}

@Override
public void soldCandy() {
// TODO Auto-generated method stub
System.out.println("没有糖果了");
}

}


糖果机 拥有一系列的状态 同时拥有当前状态

package com.undergrowth.state;

/**
* 糖果机器
*
* @author Administrator
*
*/
public class GumballMachine {

//状态切换在这5个状态之间
State noMoneyState;
State hasMoneyState;
State soldState;
State soldOutState;
State winnerState;
// 当前状态
State state;
//糖果剩余数
int count;

public GumballMachine(int numCandy) {
noMoneyState = new NoMoneyState(this);
hasMoneyState = new HasMoneyState(this);
winnerState = new WinnerState(this);
soldState = new SoldState(this);
soldOutState = new SoldOutState(this);
this.count = numCandy;
if (numCandy > 0) {
state = noMoneyState;
}
}

public void insertCoins(){
state.insertCoins();
}
public void coinsHopper(){
state.coinsHopper();
}
public void pressSold(){
state.pressSold();
state.soldCandy();
}

void releaseCandy(){
if(count!=0){
System.out.println("你获得一个糖果");
count=count-1;
}
}

public State getNoMoneyState() {
return noMoneyState;
}

public State getHasMoneyState() {
return hasMoneyState;
}

public State getSoldState() {
return soldState;
}

public State getSoldOutState() {
return soldOutState;
}

public State getWinnerState() {
return winnerState;
}

public State getState() {
return state;
}

public int getCount() {
return count;
}

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

@Override
public String toString() {
return "GumballMachine [state=" + state + ", count=" + count + "]";
}

}


测试

package com.undergrowth.state.test;

import static org.junit.Assert.*;

import org.junit.Test;

import com.undergrowth.state.GumballMachine;

public class GumballMachineTest {

@Test
public void test() {
GumballMachine gumball=new GumballMachine(10);
System.out.println(gumball);
gumball.insertCoins();
gumball.pressSold();
System.out.println(gumball);
gumball.insertCoins();
gumball.pressSold();
System.out.println(gumball);
gumball.coinsHopper();
gumball.insertCoins();
System.out.println(gumball);
gumball.coinsHopper();
System.out.println(gumball);
gumball.insertCoins();
gumball.pressSold();
System.out.println(gumball);
gumball.insertCoins();
gumball.pressSold();
gumball.insertCoins();
gumball.pressSold();
gumball.insertCoins();
gumball.pressSold();
System.out.println(gumball);
}

}


输出结果

GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=10]
你投了5块钱
你按下售出糖果按钮,即将售出糖果
你获得一个糖果
GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=9]
你投了5块钱
你按下售出糖果按钮,即将售出糖果
你进入了赢家模式,会获得两个糖果
你获得一个糖果
你获得一个糖果
GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=7]
你没有投钱,甭想退钱
你投了5块钱
GumballMachine [state=com.undergrowth.state.HasMoneyState@95ef17, count=7]
退币成功
GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=7]
你投了5块钱
你按下售出糖果按钮,即将售出糖果
你获得一个糖果
GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=6]
你投了5块钱
你按下售出糖果按钮,即将售出糖果
你获得一个糖果
你投了5块钱
你按下售出糖果按钮,即将售出糖果
你获得一个糖果
你投了5块钱
你按下售出糖果按钮,即将售出糖果
你获得一个糖果
GumballMachine [state=com.undergrowth.state.NoMoneyState@328c40, count=3]


状态模式:封装基于状态的行为,并将行为委托给当前状态
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: