> 文章列表 > 设计模式:状态模式

设计模式:状态模式

设计模式:状态模式

一、定义

依据状态的不同,调用同样的方法却有不同的行为

二、角色

  • Context:环境,定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义当前状态。
  • State:抽象状态,定义一个接口以封装与Context的一个特定状态相关的行为。
  • ConcreteState:每一子类实现一个与Context的一个状态相关的行为。

三、使用场景

  • 一个对象的行为取决于它的状态,并且它必须在运行时根据状态该改变它的行为;
  • 代码中包含大量与对象状态有关的条件语句,如一个操作中含有大量的多分支语句(if-else或switch-case),且这些分支依赖于该对象的状态;

四、使用案例

车辆限行

1.抽象出一个接口方法,判断是否限行

public interface Check {boolean limit(int lastNumber);
}

2.定义周一和周二两种不同状态同个limit方法下,不同的处理行为。

public class Monday implements Check {@Overridepublic boolean limit(int lastNumber) {if (lastNumber == 1 || lastNumber == 6) {return true;}return false;}
}public class Tuesday implements Check {@Overridepublic boolean limit(int lastNumber) {if (lastNumber == 2 || lastNumber == 7) {return true;}return false;}
}

3.定义一个判断限行的类,来统一管理和处理

public class LimitLine {private Check check;public void setCheck(Check check) {this.check = check;}public boolean getLimitLine (int lastNumber) {return check.limit(lastNumber);378915406@qq.com}
}

4.调用

 Monday monday = new Monday();Tuesday tuesday = new Tuesday();LimitLine limitLine = new LimitLine();limitLine.setCheck(monday);boolean mondayLimitOne = limitLine.getLimitLine(1);boolean mondayLimitTwo = limitLine.getLimitLine(2);limitLine.setCheck(tuesday);boolean tuesdayLimitOne = limitLine.getLimitLine(1);boolean tuesdayLimitTwo = limitLine.getLimitLine(2);Log.d("State","mondayLimitOne  = " + mondayLimitOne);Log.d("State","mondayLimitTwo  = " + mondayLimitTwo);Log.d("State","tuesdayLimitOne  = " + tuesdayLimitOne);Log.d("State","tuesdayLimitTwo  = " + tuesdayLimitTwo);

五、在Android中的使用

WIFI管理模块。

当WIFI开启时,自动扫描周围的接入点,然后以列表的形式展示;当wifi关闭时则清空。这里wifi管理模块就是根据不同的状态执行不同的行为

六、优缺点

优点:

  • 将所有与一个特定的状态相关的行为都放入一个状态对象中,提供了一个更好的方法来组织与特定状态相关的代码,避免代码膨胀的同时也保证了可扩展性与可维护性。

缺点:

  • 随着状态的增加必然会增加类和对象的个数

七、和策略模式的区别:

  • 状态模式是跟状态密切相关,同样的行为可能不同的状态会有不同的处理方式,状态是平行的。策略模式是根据策略分类,不同的策略,不同的算法会使用不同的策略,策略间是相互独立的。
  • 对于Client 端两种模式是两种不同的存在方式
    • 状态模式中不同的状态类在Client端并不需要出现,Client 只需要调用Context的接口就可以。
    • 策略模式中不同的策略必须是在Client 端出现的,Client会根据不同的需要选择不同的策略,这一点Context 无法去控制。
  • 两种模式Context 类控制方式不同
    • 状态模式中不同的状态类不需要在Client 中出现,Client只需要操作接口,例如上面例子中电视的频道调节,Client 只需要调用nextChannel() 即可,所以Context 的构造函数可以将State 作为参数,也可以不将其作为参数传入。
    • 策略模式中Client 必须要知道策略,所以Context的构造函数或者其他接口必须要将Stragety 作为参数传入。