允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。
    状态模式 - 图1

    糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。
    状态模式 - 图2

    具体代码如下:

    1. /**
    2. * 糖果销售机
    3. */
    4. public class GumballMachine {
    5. private final State soldOutState = new SoldOutState(this);
    6. private final State noQuarterState = new NoQuarterState(this);
    7. private final State hasQuarterState = new HasQuarterState(this);
    8. private final State soldState = new SoldState(this);
    9. /*糖果销售机,当前处于的状态*/
    10. private State state;
    11. /*糖果销售机,有的糖果数量*/
    12. private int count = 0;
    13. public GumballMachine(int numberGumballs) {
    14. count = numberGumballs;
    15. if (numberGumballs > 0) {
    16. state = noQuarterState;
    17. } else {
    18. state = soldOutState;
    19. }
    20. }
    21. /*投币,投了25美分*/
    22. public void insertQuarter() {
    23. state.insertQuarter();
    24. }
    25. /*退币,退了25美分*/
    26. public void ejectQuarter() {
    27. state.ejectQuarter();
    28. }
    29. /*转动曲柄*/
    30. public void turnCrank() {
    31. state.turnCrank(); //转动曲柄
    32. state.dispense(); //弹出糖果
    33. }
    34. public void releaseBall() {
    35. if (count > 0) {
    36. count--;
    37. System.out.println("糖果销售机中,弹出一颗糖果……");
    38. }else {
    39. System.out.println("糖果销售机中,没有弹出糖果……");
    40. }
    41. }
    42. public void setState(State state) {
    43. this.state = state;
    44. }
    45. public State getSoldOutState() {
    46. return soldOutState;
    47. }
    48. public State getNoQuarterState() {
    49. return noQuarterState;
    50. }
    51. public State getHasQuarterState() {
    52. return hasQuarterState;
    53. }
    54. public State getSoldState() {
    55. return soldState;
    56. }
    57. public int getCount() {
    58. return count;
    59. }
    60. }
    1. /**
    2. * 糖果销售机,某一刻所处的状态
    3. */
    4. public interface State {
    5. /**
    6. * 投入 25 分钱
    7. */
    8. void insertQuarter();
    9. /**
    10. * 退回 25 分钱
    11. */
    12. void ejectQuarter();
    13. /**
    14. * 转动糖果销售机曲柄
    15. */
    16. void turnCrank();
    17. /**
    18. * 糖果销售机,发放糖果
    19. */
    20. void dispense();
    21. }
    1. /**
    2. * 为投币状态
    3. */
    4. public class NoQuarterState implements State {
    5. private GumballMachine gumballMachine;
    6. public NoQuarterState(GumballMachine gumballMachine) {
    7. this.gumballMachine = gumballMachine;
    8. }
    9. @Override
    10. public void insertQuarter() {
    11. System.out.println("你已经投币了");
    12. gumballMachine.setState(gumballMachine.getHasQuarterState());
    13. }
    14. @Override
    15. public void ejectQuarter() {
    16. System.out.println("你不能退币,因为你没投币");
    17. }
    18. @Override
    19. public void turnCrank() {
    20. System.out.println("你不能转动糖果销售机曲柄,因为你没投币");
    21. }
    22. @Override
    23. public void dispense() {
    24. System.out.println("没有弹出糖果");
    25. }
    26. }
    1. /**
    2. * 投币状态
    3. */
    4. public class HasQuarterState implements State {
    5. private GumballMachine gumballMachine;
    6. public HasQuarterState(GumballMachine gumballMachine) {
    7. this.gumballMachine = gumballMachine;
    8. }
    9. @Override
    10. public void insertQuarter() {
    11. System.out.println("你已投币,不能再投了");
    12. }
    13. @Override
    14. public void ejectQuarter() {
    15. System.out.println("退币成功");
    16. /*退币成功,切换到:未投币状态*/
    17. gumballMachine.setState(gumballMachine.getNoQuarterState());
    18. }
    19. @Override
    20. public void turnCrank() {
    21. System.out.println("你转动糖果销售机曲柄");
    22. /*你转动曲柄,状态切换为:糖果销售机弹出糖果状态*/
    23. gumballMachine.setState(gumballMachine.getSoldState());
    24. }
    25. @Override
    26. public void dispense() {
    27. System.out.println("没有弹出糖果");
    28. }
    29. }
    1. /**
    2. * 糖果销售机,弹出糖果状态
    3. */
    4. public class SoldState implements State {
    5. private GumballMachine gumballMachine;
    6. public SoldState(GumballMachine gumballMachine) {
    7. this.gumballMachine = gumballMachine;
    8. }
    9. @Override
    10. public void insertQuarter() {
    11. System.out.println("你已投币,不能再投了");
    12. }
    13. @Override
    14. public void ejectQuarter() {
    15. System.out.println("你不能退币,因为你已经使用了");
    16. }
    17. @Override
    18. public void turnCrank() {
    19. System.out.println("转动糖果销售机曲柄,你能弹出一个糖果");
    20. }
    21. @Override
    22. public void dispense() {
    23. /*糖果数量 减一*/
    24. gumballMachine.releaseBall();
    25. if (gumballMachine.getCount() > 0) {
    26. /*糖果销售机中有糖果,状态切换为:为投币状态*/
    27. gumballMachine.setState(gumballMachine.getNoQuarterState());
    28. } else {
    29. /*糖果销售机中没有糖果,状态切换为:糖果售完状态*/
    30. System.out.println("哎呀!糖果销售机的糖果售完了");
    31. gumballMachine.setState(gumballMachine.getSoldOutState());
    32. }
    33. }
    34. }
    1. /**
    2. * 糖果买完状态
    3. */
    4. public class SoldOutState implements State {
    5. private GumballMachine gumballMachine;
    6. public SoldOutState(GumballMachine gumballMachine) {
    7. this.gumballMachine = gumballMachine;
    8. }
    9. @Override
    10. public void insertQuarter() {
    11. System.out.println("你不能投币了,因为糖果已售完");
    12. }
    13. @Override
    14. public void ejectQuarter() {
    15. System.out.println("你不能退币,因为你没投币");
    16. }
    17. @Override
    18. public void turnCrank() {
    19. System.out.println("你能转动糖果销售机曲柄,但是糖果已售完");
    20. }
    21. @Override
    22. public void dispense() {
    23. System.out.println("没有糖果弹出,因为糖果已售完");
    24. }
    25. }
    1. package com.example.greamrodcode.pattern2;
    2. public class Client {
    3. public static void main(String[] args) {
    4. GumballMachine gumballMachine = new GumballMachine(5);
    5. gumballMachine.insertQuarter();
    6. gumballMachine.turnCrank();
    7. System.out.println("=============================================");
    8. gumballMachine.insertQuarter();
    9. gumballMachine.ejectQuarter();
    10. gumballMachine.turnCrank();
    11. System.out.println("=============================================");
    12. gumballMachine.insertQuarter();
    13. gumballMachine.turnCrank();
    14. gumballMachine.insertQuarter();
    15. gumballMachine.turnCrank();
    16. gumballMachine.ejectQuarter();
    17. System.out.println("=============================================");
    18. gumballMachine.insertQuarter();
    19. gumballMachine.insertQuarter();
    20. gumballMachine.turnCrank();
    21. gumballMachine.insertQuarter();
    22. gumballMachine.turnCrank();
    23. gumballMachine.insertQuarter();
    24. gumballMachine.turnCrank();
    25. }
    26. }
    1. 你已经投币了
    2. 你转动糖果销售机曲柄
    3. 糖果销售机中,弹出一颗糖果……
    4. =============================================
    5. 你已经投币了
    6. 退币成功
    7. 你不能转动糖果销售机曲柄,因为你没投币
    8. 没有弹出糖果
    9. =============================================
    10. 你已经投币了
    11. 你转动糖果销售机曲柄
    12. 糖果销售机中,弹出一颗糖果……
    13. 你已经投币了
    14. 你转动糖果销售机曲柄
    15. 糖果销售机中,弹出一颗糖果……
    16. 你不能退币,因为你没投币
    17. =============================================
    18. 你已经投币了
    19. 你已投币,不能再投了
    20. 你转动糖果销售机曲柄
    21. 糖果销售机中,弹出一颗糖果……
    22. 你已经投币了
    23. 你转动糖果销售机曲柄
    24. 糖果销售机中,弹出一颗糖果……
    25. 哎呀!糖果销售机的糖果售完了
    26. 你不能投币了,因为糖果已售完
    27. 你能转动糖果销售机曲柄,但是糖果已售完
    28. 没有糖果弹出,因为糖果已售完