首页 > 代码库 > 设计模式(10)--状态模式

设计模式(10)--状态模式

组合 、委托

基本常识:策略模式和状态模式是双胞胎,在出生时才分开。

一般来说,我们把策略模式想成是除了继承之外的一种弹性替代方案。     

什么时候用接口? or 抽象类?

当实现接口的类中,重复代码太多时,可考虑继承 。

OO模式状态模式--允许对象在内部状态改变时改变它的作为,对象看起来好像修改了它的类

如:  因为一个状态对应一个类, 每个类中的方法名相同,但实现不同。 所以看起来好像修改了类。

例:

饮料机(DrinkMachine)的状态

如果对对象的状态建模 -- 通过创建一个实例变量来持有状态值,并在方法内书写条件代码来处理不同状态。

状态:投币、出饮料、退币、售完饮料等

public class DrinkMachine{

   final static int SOLD_OUT=0;  //卖出

   final static int NO_QUARTER =1;   //没有25分钱

   final static int HAS_QUARTER = 2;  //  有 25分钱

   final staic int SOLD =3;  

   

   int state = SOLD_OUT ; // 初始状态饮料售罄

   int count = 0;   //机器内 饮料数量

   public  DrinkMachine(int count ){  //初始化饮料数量

        this.count = count;

        if(count <0){

           state = NO_QUARTER;     

         }

   }

   public void insertQuarter(){  // 投币动作

          if(state == HAS_QUARTER){}

          else if( state ==NO_QUARTER){}                     //跟据当前不同的状态 , 做相应的事。

          else if( state ==SOLD_OUT){}

   }

   // 退币动作

   // 转动手柄 取饮料动作

  // 出饮料动作  

}       //   

如果变更需求时 (如新加一个随机出两瓶饮料的动作),将 不容易 扩展。  需要修改类的方法 , 违返 设计原则 对修改关闭。

使用思虑周密的方法学构造的牢不可破的设计

新的设计:  组合  委托

将状态对象封装在各自的类中,然后在动作发生时委托给当前状态

(1)首先,我们定义一个State接口。在这个接口内,糖果机的每个动作都有一个对应的方法

(2) 然后为机器中的每个状态实现状状类。这些类将负责在对应的状态下进行机器的行为。

(3)最后,我们要摆脱旧的条件代码,取而代之的方式是,将动作委托到状态类。


之前的 饮料机中每一个状态   对应 现在的一个状态类。


下面就是完成各种状态类。  implements State 如: 投币之后,应该做哪些事,机器到什么状态

一个类一个责任,莫要用一个类表示两个状态。

状态: 封装基于状态的行为,并将行为委托到当前状态。

策略:将可以互换的行为封装起来,然后使用委托的方法,决定使用哪一个行为。

模板方法:由子类决定如何实现算法中的某些步聚。

要点:

(1)状态模式允许一个对象基于内部状态而拥有不同的行为。

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

(3)Context 会将行为委托给当前状态对象。

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

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

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

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

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

(9)状态类可以被多个Context实例共享。