在软件开发过程中。应用程序可能会依据不同的情况作出不同的处理。
最直接的解决方式是将这些全部可能发生的情况全都考虑到。然后使用if... ellse语句来做状态推断来进行不同情况的处理。
可是对复杂状态的推断就显得“力不从心了”。
随着添加新的状态或者改动一个状体(if else(或switch case)语句的增多或者改动)可能会引起非常大的改动,而程序的可读性,扩展性也会变得非常弱。维护也会非常麻烦。
那么我就考虑仅仅改动自身状态的模式。————题记
设计模式
状态模式:同意对象在内部状态改变时改变他的行为,对象看起来好像改动了它的类。
这个模式将状态封装称为独立的类,并将动作托付到代表当前状态的对象。我们知道行为会随着内部状态而改变。
设计原则
封装变化
多用组合。少用继承
针对接口编程,不针对实现编程
为交互对象之间松耦合设计而努力
类应该对扩展开发。对改动关闭
依赖抽象,不依赖详细类
仅仅和朋友交谈
别找我,我会找你
类应该仅仅有一个改变的理由
要点
状态模式同意一个对象基于内部状态而拥有不同的行为。
和程序状态机不同,状态模式用类代表状态。
策略模式一般会用行为或算法来配置context类,状态模式同意context随着状态改变而改变行为。状态转变能够由state类或context类控制。
使用状态模式会导致设计模式中类的数目大量添加。
状态类能够被多个context共享。
模型匹配
状态模型 封装基于状态的行为,并将行为托付到当前状态
策略模型 将能够互换的行为封装起来,然后使用托付的方法,决定使用哪一个行为。
模板方法模型 由子类决定实现算法的某些步骤
何时使用?
State模式在实际使用中比較多,适合"状态的切换".由于我们常常会使用If elseif else 进行状态切换, 假设针对状态的这样推断切换重复出现,我们就要联想到能否够採取State模式了.
不仅仅是依据状态,也有依据属性.假设某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比較高,我们常常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这样的属性的改变(切换)又是随时可能发生的,就有可能要使用State.
状态模式:
//状态接口 public interface State { public void insertQuarter(); public void ejectQuarter(); public void turnCrank(); public void dispense(); } //实现状态接口 public 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.getHasQuarterState()); } 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"; } } public 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.getNoQuarterState()); } public void turnCrank() { System.out.println("You turned..."); //决定这名顾客是否赢了 int winner = randomWinner.nextInt(10); if ((winner == 0) && (gumballMachine.getCount() > 1)) { gumballMachine.setState(gumballMachine.getWinnerState()); } else { gumballMachine.setState(gumballMachine.getSoldState()); } } public void dispense() { System.out.println("No gumball dispensed"); } public String toString() { return "waiting for turn of crank"; } } //实现糖果机 public 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; } } int getCount() { return count; } void refill(int count) { this.count = count; state = noQuarterState; } public State getState() { return state; } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } public State getWinnerState() { return winnerState; } public String toString() { StringBuffer result = new StringBuffer(); result.append(" Mighty Gumball, Inc."); result.append(" Java-enabled Standing Gumball Model #2004"); result.append(" Inventory: " + count + " gumball"); if (count != 1) { result.append("s"); } result.append(" "); result.append("Machine is " + state + " "); return result.toString(); } } package net.dp.state.gumballstatewinner; public class GumballMachineTestDrive { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(10); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); //再在转动运行多次 } }