1. 定义:
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。
状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样
2.例子:
例子参考HeadFirst 通过状态模式实现糖果机,糖果机分为四个状态:投币,未投币,售完,销售中
然后通过当前状态决定当前的操作,看一下,未用状态模式实现的java代码
public class GumballMachine {
//糖果机有四种状态,分别为:投币 、未投币 、售磬、销售中
private static int has_money=0;
private static int no_money=1;
private static int no_goods=3;
private static int solding=4;
int state=solding;
int count=0;
public GumballMachine(int count) {
this.count=count;
if(count >0){
state = no_money;
}
}
//四种操作
//投币
//退钱
//转动曲柄
public void insertMoney(){
if(state == has_money){
System.out.println("已经投过币了");
}else if(state == no_money){
state=has_money;
System.out.println("投入了硬币");
}else if(state == no_goods){
System.out.println("不能投币,因为没有商口了");
}else if(state == solding){
System.out.println("稍等一下");
}
}
public void ejectMoney(){
if(state == has_money){
System.out.println("退币了");
state = no_money;
}else if(state == no_money){
System.out.println("没投币,退不了");
}else if(state == solding){
System.out.println("刚退了");
}else if(state == no_goods){
System.out.println("就不给你退");
}
}
public void turnHandler(){
if(state == solding){
System.out.println("骗子");
}else if(state == no_money){
System.out.println("先投币");
}else if(state == no_goods){
System.out.println("没有商口");
}else if(state == has_money){
System.out.println("给你");
state=solding;
dispense();
}
}
public void dispense(){
if(state == solding){
System.out.println("稍等");
count--;
if(count == 0){
System.out.println("卖完了");
state = no_goods;
}else{
state = no_money;
}
}else if(state == no_money){
System.out.println("先投币");
}else if(state == no_goods){
System.out.println("没有商口");
}else if(state == has_money){
System.out.println("给你");
state=solding;
dispense();
}
}
}
如果只是这四种状态,这个是没有问题,但是再添加一种状态的时候,会发现每一个方法都要改,会造成 代码特别不容易维护。这个时候就用到了状态模式,把状态抽象成一个接口,然后,针对每一种状态有一个实现类。
看一下类图结构:
通过类图,我们重写上面的代码。
首先是一个State接口:
/**
* 状态接口
* @author king
*
*/
public interface State {
public void insertMoney();
public void ejectMoney();
public void turnHandler();
public void dispense();
}
2. 没有投币的实现类
public class NoMoneyState implements State{
GumballMachine machine;
public NoMoneyState(GumballMachine machine) {
this.machine = machine;
}
@Override
public void insertMoney() {
System.out.println("投入了一个硬币");
machine.setDefaultState(machine.getHasMoneyState());
}
@Override
public void ejectMoney() {
System.out.println("没有投币");
}
@Override
public void turnHandler() {
System.out.println("没有钱,不能转");
}
@Override
public void dispense() {
System.out.println("投币");
}
}
3.销售状态的实现类
public class SoldingState implements State{
GumballMachine machine;
public SoldingState(GumballMachine machine) {
this.machine = machine;
}
@Override
public void insertMoney() {
System.out.println("等会再投");
}
@Override
public void ejectMoney() {
System.out.println("退不了了");
}
@Override
public void turnHandler() {
System.out.println("转动没用的");
}
@Override
public void dispense() {
machine.releaseBall();
if(machine.getCount()>0){
machine.setDefaultState(machine.getNoMoneyState());
}else{
machine.setDefaultState(machine.getNoGoodsState());
}
}
}
4. 我们看一下销售机做了哪些便化
public class GumballMachine {
private State noMoneyState;
private State hasMoneyState;
private State soldingState;
private State noGoodsState;
State defaultState = soldingState;
int count=0;
public State getNoMoneyState() {
return noMoneyState;
}
public void setNoMoneyState(State noMoneyState) {
this.noMoneyState = noMoneyState;
}
public State getHasMoneyState() {
return hasMoneyState;
}
public void setHasMoneyState(State hasMoneyState) {
this.hasMoneyState = hasMoneyState;
}
public State getSoldingState() {
return soldingState;
}
public void setSoldingState(State soldingState) {
this.soldingState = soldingState;
}
public State getNoGoodsState() {
return noGoodsState;
}
public void setNoGoodsState(State noGoodsState) {
this.noGoodsState = noGoodsState;
}
public State getDefaultState() {
return defaultState;
}
public void setDefaultState(State defaultState) {
this.defaultState = defaultState;
}
public GumballMachine(int count) {
noMoneyState = new NoMoneyState(this);
noGoodsState = new NoGoodsState(this);
hasMoneyState = new HasMoneyState(this);
soldingState = new SoldingState(this);
this.count = count;
if(this.count>0){
defaultState = noMoneyState;
}
}
void releaseBall(){
System.out.println("出糖");
if(count!=0){
count--;
}
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public void insertMoney(){
defaultState.insertMoney();
}
public void ejectMoney(){
defaultState.ejectMoney();
}
public void turnHandler(){
defaultState.turnHandler();
defaultState.dispense();
}
}
这就是状态模式