`

《Head First设计模式》阅读笔记.第十章

    博客分类:
  • Java
阅读更多
1.状态(State)模式部分

*设计谜题
---------------------------------------------
状态转换图不变,在售出糖果时,如果剩余糖果数大于1,有10%的几率掉下2个。
---------------------------------------------

Sharpen your pencil
---------------------------------------------
A、B、C、D、E、F
---------------------------------------------

Sharpen your pencil
引用
---------------------------------------------
NoQuarterState:
turnCrank--告诉顾客投入硬币
dispense--什么都不做

HasQuarterState:
insertQuarter--告诉顾客已经有硬币
ejectQuarter--退回硬币,进入NoQuarterState
dispense--掉下1颗糖果,检查剩余糖果数量,大于0,进入NoQuarterState,等于0,进入SoldOutState(更好的方式:转入SoldState处理)

SoldState:
ejectQuarter--告诉顾客正在售出糖果
turnCrank--告诉顾客您没有投入硬币

SoldOutState:
insertQuarter--告诉顾客已售罄
ejectQuarter--告诉顾客您没有投入硬币
dispense--什么都不做

WinnerState:
insertQuarter--告诉顾客正在售出糖果
ejectQuarter--告诉顾客您没有投入硬币
turnCrank--告诉顾客您没有投入硬币
dispense--掉下2颗糖果,检查剩余糖果数量,大于0,进入NoQuarterState,等于0,进入SoldOutState
---------------------------------------------


Brain Power
---------------------------------------------
将调用dispense()方法的代码放到State子类中去实现。
---------------------------------------------

Sharpen your pencil
---------------------------------------------
public class SoldOutState implements State {
  GumballMachine gumballMachine;
  
  public SoldOutState(GumballMachine gumballMachine) {
    this.gumballMachine = gumballMachine;
  }
  
  public void insertQuarter(){
    System.out.println("Sorry,the gumballs are sold out.");
  }
  
  public void ejectQuarter(){
    System.out.println("Sorry,you haven't insert a quarter.");
  }
  
  public void turnCrank(){
    System.out.println("Sorry,you haven't insert a quarter");
  }
  
  public void dispense(){
    //do nothing
  }
}
---------------------------------------------


*运用状态模式给糖果机设计带来的益处是:
让每一个状态“对修改关闭”,让糖果机“对扩展开放”,这样可以方便地加入新的状态类。

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

Sharpen your pencil
---------------------------------------------
public void refill(int count){
  this.count = count;
  if(count>0){
    this.state = noQuarterState;
  }
}
---------------------------------------------


连连看
引用
---------------------------------------------
状态--封装基于状态的行为,并将行为委托到当前状态
策略--将可以互换的行为封装起来,然后使用委托的方法,决定使用哪一个行为
模板方法--由子类决定如何实现算法中的某些步骤
---------------------------------------------


2.状态(State)模式小结

*状态允许一个对象基于内部状态而拥有不同的行为。

*和程序状态机(PSM)不同,状态模式用类代表状态。

*Context会将行为委托给当前状态对象。

*通过把每个状态封装进一个类,我们把以后要做的任何改变局部化了。

*状态(State)模式和策略(Strategy)模式类图相同,但是它们有不同的意图。

*策略(Strategy)模式通常会用行为或算法来配置Context类。

*状态(State)模式允许Context随着状态的改变而改变行为。

*状态转换可以由State类或Context类来控制。

*使用状态模式通常会导致设计中类的数目大量增加。

*状态可以被多个Context实例共享。

3.状态(State)模式实例

/**
 * 钢笔
 * 
 * @author zangweiren
 * 
 */
public class FountainPen implements FountainPenState {
	FountainPenState fullState;
	FountainPenState halfFullState;
	FountainPenState emptyState;

	FountainPenState state;
	int inkLevel = 0;

	public FountainPen() {
		fullState = new FullState(this);
		halfFullState = new HalfFullState(this);
		emptyState = new EmptyState(this);
		state = emptyState;
	}

	@Override
	public void empty() {
		state.empty();
	}

	@Override
	public void fill() {
		state.fill();
	}

	@Override
	public void write() {
		state.write();
	}

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

	FountainPenState getFullState() {
		return fullState;
	}

	FountainPenState getHalfFullState() {
		return halfFullState;
	}

	FountainPenState getEmptyState() {
		return emptyState;
	}

}

/**
 * 钢笔状态接口
 * 
 * @author zangweiren
 * 
 */
public interface FountainPenState {
	void fill();

	void write();

	void empty();
}

/**
 * 满
 * 
 * @author zangweiren
 * 
 */
public class FullState implements FountainPenState {
	FountainPen pen;

	public FullState(FountainPen pen) {
		this.pen = pen;
	}

	@Override
	public void empty() {
		pen.inkLevel = 0;
		pen.setState(pen.getEmptyState());
		System.out.println("The fountain pen is empty now.");
	}

	@Override
	public void fill() {
		System.out.println("Sorry,the fountain pen is already full.");
	}

	@Override
	public void write() {
		pen.inkLevel = pen.inkLevel - 1;
		if (pen.inkLevel == 0) {
			pen.setState(pen.getEmptyState());
			System.out.println("The fountain pen is empty.");
		} else {
			pen.setState(pen.getHalfFullState());
			System.out.println("The fountain pen is half full.");
		}
	}

}

/**
 * 半满
 * 
 * @author zangweiren
 * 
 */
public class HalfFullState implements FountainPenState {
	FountainPen pen;

	public HalfFullState(FountainPen pen) {
		this.pen = pen;
	}

	@Override
	public void empty() {
		pen.inkLevel = 0;
		pen.setState(pen.getEmptyState());
		System.out.println("The fountain pen is empty now.");
	}

	@Override
	public void fill() {
		pen.inkLevel = 100;
		pen.setState(pen.getFullState());
		System.out.println("Congratulations,the fountain pen is full now.");
	}

	@Override
	public void write() {
		pen.inkLevel = pen.inkLevel - 1;
		if (pen.inkLevel == 0) {
			pen.setState(pen.getEmptyState());
			System.out.println("The fountain pen is empty.");
		} else {
			System.out.println("The fountain pen is half full.");
		}
	}

}

/**
 * 空
 * 
 * @author zangweiren
 * 
 */
public class EmptyState implements FountainPenState {
	FountainPen pen;

	public EmptyState(FountainPen pen) {
		this.pen = pen;
	}

	@Override
	public void empty() {
		System.out.println("Sorry,the fountain pen is already empty.");
	}

	@Override
	public void fill() {
		pen.inkLevel = 100;
		pen.setState(pen.getFullState());
		System.out.println("Congratulations,the fountain pen is full now.");
	}

	@Override
	public void write() {
		System.out.println("Sorry,the fountain pen is empty.");
	}

}


测试程序:
---------------------------------------------
public class TestFountainPen {
	public static void main(String[] args) {
		FountainPen pen = new FountainPen();
		pen.fill();
		int count = 5;
		while (count > 0) {
			pen.write();
			count--;
		}
		pen.empty();
		pen.write();
		pen.fill();
		pen.write();
		pen.empty();
	}

}

---------------------------------------------

测试结果:
---------------------------------------------
引用
Congratulations,the fountain pen is full now.
The fountain pen is half full.
The fountain pen is half full.
The fountain pen is half full.
The fountain pen is half full.
The fountain pen is half full.
The fountain pen is empty now.
Sorry,the fountain pen is empty.
Congratulations,the fountain pen is full now.
The fountain pen is half full.
The fountain pen is empty now.

3
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics