您的位置:首页 > 其它

Head First 设计模式 --10 状态模式

2016-12-26 20:28 337 查看
状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类。

用到的设计原则
1、封装变化
2、多用组合,少用继承
3、针对接口编程,不针对实现编程
4、松耦合
5、对扩展开放,对修改关闭
6、依赖抽象,而不依赖具体
7、只和朋友交谈
8、别找我,我会找你
9、类应该只有一个修改的理由

例子来自《Head First设计模式》,糖果机的例子

interface State {

public void insertQuarter();

public void ejectQuarter();

public void turnCrank();

public void dispense();
}

class NoQuarterState implements State {
GumballMachine gumballMachine;

public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}

public void insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.setState(gumballMachine.hasQuarterState);
}

public void ejectQuarter() {
System.out.println("You haven't inserted a quarter");
}

public void turnCrank() {
System.out.println("You turned, but there's no quarter");
}

public void dispense() {
System.out.println("You need to pay first");
}

public String toString() {
return "waiting for quarter";
}
}

class HasQuarterState implements State {
Random randomWinner = new Random(System.currentTimeMillis());
GumballMachine gumballMachine;

public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}

public void insertQuarter() {
System.out.println("You can't insert another quarter");
}

public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.noQuarterState);
}

public void turnCrank() {
System.out.println("You turned...");

int winner = randomWinner.nextInt(10);
if ((winner == 0) && (gumballMachine.count > 1)) {
gumballMachine.setState(gumballMachine.winnerState);
} else {
gumballMachine.setState(gumballMachine.soldOutState);
}
}

public void dispense() {
System.out.println("No gumball dispensed");
}

public String toString() {
return "waiting for turn of crank";
}
}

class GumballMachine {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;

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);
// winnerState = new WinnerState(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 class StateTest {
public static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(10);

gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
}
}


类图:



上面的代码运行不了。缺少三种State,这里只是看一下要表达的意思。

装填模式将状态封装成独立的类,并将每个动作委托给当前状态的对象。如果对象能够完全改变它的行为,那么你会觉得,这个对象实际是从别的类实例化出来的,而实际上,我们是用组合通过简单引用不同的状态对象来造成类的改变的假象。

当我们看到上面的类图时,会发现这个类图和策略模式的类图是一样的。
策略模式:我们将一群行为封装在状态对象中,context的行为随时可委托到哪个状态对象中。随着状态的改变,以反应context的内部的状态。但是context的客户对于状态对象了解不多。状态模式代替多条件判断的设计方案,通过包装状态对象,在context内简单地改变状态对象。
装填模式:通常是主动指定context所要组合的对象是哪一个。这个对象一般情况不会改变,因为对于程序而言,他就是这个类型的,具有特定的行为。一般来说,策略模式是除了继承外一种弹性的设计方案。

状态模式:封装基于装填的行为,并将行为委托到当前状态
策略模式:将可以减缓的行为封装起来,然后使用委托的方法决定使用那一个行为
模板方法模式:由子类决定如何实现算法中的某个步骤
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: