• 设计模式 - 状态模式


    目录

    一. 前言

    二. 实现


    一. 前言

        状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

    状态模式和策略模式区别
    1、策略模式封装了一组行为或者算法,它允许Client在运行时动态的切换;状态模式是帮助一个类在不同的状态下显示不同的行为,依赖于内部的状态;
    2、策略模式不持有Context的引用,而是被Context所使用;状态模式的每个状态都持有Context的引用,从而在Context中实现状态的转移;
    3、从理论上说,策略模式定义对象应该“怎么做”;状态模式定义了对象“是什么”,“什么时候做”。
    状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

    二. 实现

    Context 类为环境角色, 用于维护State 实例,这个实例定义当前状态(聚合State)。
    State 是抽象状态角色,定义一个接口封装与Context 的一个特点接口相关行为。
    ConcreteState 具体的状态角色,每个子类实现一个与Context 的一个状态相关行为。

    案例:糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。

    1. public interface State {
    2. /**
    3. * 投入 25 分钱
    4. */
    5. void insertQuarter();
    6. /**
    7. * 退回 25 分钱
    8. */
    9. void ejectQuarter();
    10. /**
    11. * 转动曲柄
    12. */
    13. void turnCrank();
    14. /**
    15. * 发放糖果
    16. */
    17. void dispense();
    18. }
    1. public class HasQuarterState implements State {
    2. private GumballMachine gumballMachine;
    3. public HasQuarterState(GumballMachine gumballMachine) {
    4. this.gumballMachine = gumballMachine;
    5. }
    6. @Override
    7. public void insertQuarter() {
    8. System.out.println("You can't insert another quarter");
    9. }
    10. @Override
    11. public void ejectQuarter() {
    12. System.out.println("Quarter returned");
    13. gumballMachine.setState(gumballMachine.getNoQuarterState());
    14. }
    15. @Override
    16. public void turnCrank() {
    17. System.out.println("You turned...");
    18. gumballMachine.setState(gumballMachine.getSoldState());
    19. }
    20. @Override
    21. public void dispense() {
    22. System.out.println("No gumball dispensed");
    23. }
    24. }
    1. public class NoQuarterState implements State {
    2. GumballMachine gumballMachine;
    3. public NoQuarterState(GumballMachine gumballMachine) {
    4. this.gumballMachine = gumballMachine;
    5. }
    6. @Override
    7. public void insertQuarter() {
    8. System.out.println("You insert a quarter");
    9. gumballMachine.setState(gumballMachine.getHasQuarterState());
    10. }
    11. @Override
    12. public void ejectQuarter() {
    13. System.out.println("You haven't insert a quarter");
    14. }
    15. @Override
    16. public void turnCrank() {
    17. System.out.println("You turned, but there's no quarter");
    18. }
    19. @Override
    20. public void dispense() {
    21. System.out.println("You need to pay first");
    22. }
    23. }
    1. public class SoldOutState implements State {
    2. GumballMachine gumballMachine;
    3. public SoldOutState(GumballMachine gumballMachine) {
    4. this.gumballMachine = gumballMachine;
    5. }
    6. @Override
    7. public void insertQuarter() {
    8. System.out.println("You can't insert a quarter, the machine is sold out");
    9. }
    10. @Override
    11. public void ejectQuarter() {
    12. System.out.println("You can't eject, you haven't inserted a quarter yet");
    13. }
    14. @Override
    15. public void turnCrank() {
    16. System.out.println("You turned, but there are no gumballs");
    17. }
    18. @Override
    19. public void dispense() {
    20. System.out.println("No gumball dispensed");
    21. }
    22. }
    1. public class SoldState implements State {
    2. GumballMachine gumballMachine;
    3. public SoldState(GumballMachine gumballMachine) {
    4. this.gumballMachine = gumballMachine;
    5. }
    6. @Override
    7. public void insertQuarter() {
    8. System.out.println("Please wait, we're already giving you a gumball");
    9. }
    10. @Override
    11. public void ejectQuarter() {
    12. System.out.println("Sorry, you already turned the crank");
    13. }
    14. @Override
    15. public void turnCrank() {
    16. System.out.println("Turning twice doesn't get you another gumball!");
    17. }
    18. @Override
    19. public void dispense() {
    20. gumballMachine.releaseBall();
    21. if (gumballMachine.getCount() > 0) {
    22. gumballMachine.setState(gumballMachine.getNoQuarterState());
    23. } else {
    24. System.out.println("Oops, out of gumballs");
    25. gumballMachine.setState(gumballMachine.getSoldOutState());
    26. }
    27. }
    28. }
    1. public class GumballMachine {
    2. private State soldOutState;
    3. private State noQuarterState;
    4. private State hasQuarterState;
    5. private State soldState;
    6. private State state;
    7. private int count = 0;
    8. public GumballMachine(int numberGumballs) {
    9. count = numberGumballs;
    10. soldOutState = new SoldOutState(this);
    11. noQuarterState = new NoQuarterState(this);
    12. hasQuarterState = new HasQuarterState(this);
    13. soldState = new SoldState(this);
    14. if (numberGumballs > 0) {
    15. state = noQuarterState;
    16. } else {
    17. state = soldOutState;
    18. }
    19. }
    20. public void insertQuarter() {
    21. state.insertQuarter();
    22. }
    23. public void ejectQuarter() {
    24. state.ejectQuarter();
    25. }
    26. public void turnCrank() {
    27. state.turnCrank();
    28. state.dispense();
    29. }
    30. public void setState(State state) {
    31. this.state = state;
    32. }
    33. public void releaseBall() {
    34. System.out.println("A gumball comes rolling out the slot...");
    35. if (count != 0) {
    36. count -= 1;
    37. }
    38. }
    39. public State getSoldOutState() {
    40. return soldOutState;
    41. }
    42. public State getNoQuarterState() {
    43. return noQuarterState;
    44. }
    45. public State getHasQuarterState() {
    46. return hasQuarterState;
    47. }
    48. public State getSoldState() {
    49. return soldState;
    50. }
    51. public int getCount() {
    52. return count;
    53. }
    54. }
    1. public class Client {
    2. public static void main(String[] args) {
    3. GumballMachine gumballMachine = new GumballMachine(5);
    4. gumballMachine.insertQuarter();
    5. gumballMachine.turnCrank();
    6. gumballMachine.insertQuarter();
    7. gumballMachine.ejectQuarter();
    8. gumballMachine.turnCrank();
    9. gumballMachine.insertQuarter();
    10. gumballMachine.turnCrank();
    11. gumballMachine.insertQuarter();
    12. gumballMachine.turnCrank();
    13. gumballMachine.ejectQuarter();
    14. gumballMachine.insertQuarter();
    15. gumballMachine.insertQuarter();
    16. gumballMachine.turnCrank();
    17. gumballMachine.insertQuarter();
    18. gumballMachine.turnCrank();
    19. gumballMachine.insertQuarter();
    20. gumballMachine.turnCrank();
    21. }
    22. }
    1. You insert a quarter
    2. You turned...
    3. A gumball comes rolling out the slot...
    4. You insert a quarter
    5. Quarter returned
    6. You turned, but there's no quarter
    7. You need to pay first
    8. You insert a quarter
    9. You turned...
    10. A gumball comes rolling out the slot...
    11. You insert a quarter
    12. You turned...
    13. A gumball comes rolling out the slot...
    14. You haven't insert a quarter
    15. You insert a quarter
    16. You can't insert another quarter
    17. You turned...
    18. A gumball comes rolling out the slot...
    19. You insert a quarter
    20. You turned...
    21. A gumball comes rolling out the slot...
    22. Oops, out of gumballs
    23. You can't insert a quarter, the machine is sold out
    24. You turned, but there are no gumballs
    25. No gumball dispensed

  • 相关阅读:
    hadoop笔记——YARN部署
    【教程5】疯壳·ARM功能手机-串口实验教程
    纯卡西欧计算器5800P坐标正反算
    PPP开源软件GMAP测试记录及原始数据比较
    java毕业设计物业管理系统mybatis+源码+调试部署+系统+数据库+lw
    库存管理“智慧官”上线!北京电信基于飞桨打造主动型库存决策分析系统
    图神经网络(1):图卷积神经网络GCN ICLR 2017
    跨境电商未来前景—成都扬帆际海教育咨询有限公司
    【C语言基础】循环
    Web开发:<p>标签作用
  • 原文地址:https://blog.csdn.net/mrluo735/article/details/133694820