• 状态模式——HeadFirst设计模式学习笔记


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

    ——将状态封装成独立的类,将动作委托给当前状态对象,所以行为会随着内部状态的变化而变化

     

    状态转换图:为每一个状态创建一个实现一组相同操作接口的对象,实体对象包含所有状态并有一个当前状态接口的引用

    特点:

    • 允许一个对象基于不用的状态有不同的行为
    • 把变化的东西取出来,局部化每个状态的行为,每个状态的行为局部化到自己的类中,遵守“封装变化”原则,减少了繁琐的if语句,满足“对修改关闭,对扩展开放”原则,便于阅读与理解
    • 所有的状态实现共同的state接口,state接口可以作为抽象类,减少代码冗余,默认实现可以作为不支持操作
    • 实体对象包含它的每一个状态,当前状态总是这些状态之一,当动作被调用时,它会把动作委派给当前的状态完成

    注意:

    • 状态的转换可以在Context中实现(状态转换是固定的),亦可在具体的状态类中实现(状态转化是动态的,状态类之间产生了依赖)
    • 客户不可以直接改变Context中的状态
    • 状态可以被共享
    • 明确主机的行为与主机的状态的之间的关系,主机的某种状态的操作可以操作主机的行为。例: 

    状态模式vs策略模式: 

    • 均允许对象通过组合和委托拥有不同的行为或算法
    • 状态模式的的当前状态游走于对象的状态集合之间,状态的改变是有方案的,客户不了解状态变化的方式;策略模式客户主动指定状态中的哪一个

    举例:

    实现糖果自动贩卖机过程,状态转换图如上 

    状态接口及SoldState实现:

     1 public interface State {  
     2    public void insertQuarter();   // 投入25分钱  
     3    public void ejectQuarter();    // 拒绝25分钱  
     4    public void turnCrank();       // 转动曲柄  
     5    public void dispense();        // 发放糖果  
     6 } 
     7 
     8 
     9 public class SoldState implements State{  
    10       
    11     GumballMachine gumballMachine;  
    12     public SoldState(GumballMachine gumballMachine) {  
    13         this.gumballMachine = gumballMachine;  
    14     }  
    15     // 投入25分钱  
    16     public void insertQuarter() {  
    17         System.out.println("Please wait, we're already giving you a gumball");  
    18     }  
    19     // 拒绝25分钱  
    20     public void ejectQuarter() {  
    21         System.out.println("Sorry,you have already turn crank");  
    22     }  
    23     // 转动曲柄  
    24     public void turnCrank() {  
    25         System.out.println("trun twice ,doesn't give you anthor gamball!");  
    26     }  
    27     // 发放糖果  
    28     public void dispense() {  
    29         gumballMachine.releaseBall();  
    30         if(gumballMachine.getCount()>0){  
    31             gumballMachine.setState(gumballMachine.getNoQuarterState());  
    32         } else {  
    33             System.out.println("Opps,out of gamball!");   
    34             gumballMachine.setState(gumballMachine.getSoldOutState());  
    35         }  
    36     }  
    37 } 

    自动贩卖机实现:

     1 public class GumballMachine {  
     2     //状态实例  
     3     State soldOutState;  
     4     State noQuarterState;  
     5     State hasQuarterState;  
     6     State soldState;  
     7     State winnerState;  
     8       
     9     // 实例变量state,初始化为糖果售罄状态  
    10     State state = soldOutState;   
    11     // 记录机器内装有糖果的数目,开始机器是没有装糖果的  
    12     int count=0;  
    13     // 构造器取得糖果的初始数目并把它放在一个实例变量count中  
    14     public GumballMachine(int numberGumballs) {  
    15         // 每种状态都创建一个状态实例  
    16         soldOutState=new SoldOutState(this);  
    17         noQuarterState=new NoQuarterState(this);  
    18         hasQuarterState=new HasQuarterState(this);  
    19         soldState=new SoldState(this);  
    20         winnerState = new WinnerState(this);  
    21           
    22         this.count = numberGumballs;  
    23         // 若超过0颗糖果,就将状态设置为NoQuarterState  
    24         if(numberGumballs > 0) {  
    25             state = noQuarterState;  
    26         }  
    27     }  
    28     // 取得机器内的糖果数目  
    29     public int getCount() {  
    30         return count;  
    31     }  
    32     // 取得糖果售罄状态  
    33    // ……
    34 
    35     // 投入25分钱  
    36     public void insertQuarter(){  
    37         state.insertQuarter();  
    38     }  
    39     // 拒绝25分钱  
    40     public void ejectQuarter(){  
    41         state.ejectQuarter();  
    42     }  
    43     // 转动曲柄  
    44     public void turnCrank(){  
    45         state.turnCrank();  
    46         state.dispense();  
    47     }  
    48     // 设置状态  
    49     public void setState(State state){  
    50         this.state=state;  
    51     }  
    52     // 糖果滚出来一个  
    53     public void releaseBall(){  
    54         System.out.println("A gumball comes rolling out of the solt...");  
    55         if(count!=0){  
    56             count--;  
    57         }  
    58     }  
    59 }  
  • 相关阅读:
    alpha版本发布前的进度
    1.26~1.27
    1.23~1.25
    1月21日~1月22日工作情况
    1月17日工作情况
    1月16日小组开会
    1月15日工作进度
    1月12日~1月14日工作进度
    linux下的动态链接库管理
    小组第一次小组讨论
  • 原文地址:https://www.cnblogs.com/HectorHou/p/6012179.html
Copyright © 2020-2023  润新知