根据状态决定行为 与visitor相似 面向对象的灵活应用

UML类图

image.png

例子:女孩子不同的状态做不同动作时会有不同反应===>State模式

1、女孩子根据不同的心理状态决定同一动作的不同表现

  1. package com.mashibing.dp.state.v1;
  2. /**
  3. * 当增加新的状态时非常不方便
  4. */
  5. public class MM {
  6. String name;
  7. private enum MMState {HAPPY, SAD}
  8. MMState state;
  9. public void smile() {
  10. //switch case
  11. }
  12. public void cry() {
  13. //switch case
  14. }
  15. public void say() {
  16. //switch case
  17. }
  18. }

2、使用State模式,女孩子的动作根据成员属性中的State属性调用的方法决定

MMState抽象类

  1. package com.mashibing.dp.state.v2;
  2. public abstract class MMState {
  3. abstract void smile();
  4. abstract void cry();
  5. abstract void say();
  6. }

MMHappyState类(快乐状态类)

  1. package com.mashibing.dp.state.v2;
  2. public class MMHappyState extends MMState {
  3. @Override
  4. void smile() {
  5. System.out.println("happy smile");
  6. }
  7. @Override
  8. void cry() {
  9. }
  10. @Override
  11. void say() {
  12. }
  13. }

MMNervousState类

  1. package com.mashibing.dp.state.v2;
  2. public class MMNervousState extends MMState {
  3. @Override
  4. void smile() {
  5. }
  6. @Override
  7. void cry() {
  8. }
  9. @Override
  10. void say() {
  11. }
  12. }

MMSadState类

  1. package com.mashibing.dp.state.v2;
  2. public class MMSadState extends MMState {
  3. @Override
  4. void smile() {
  5. }
  6. @Override
  7. void cry() {
  8. }
  9. @Override
  10. void say() {
  11. }
  12. }

MM类(升级版)

  1. package com.mashibing.dp.state.v2;
  2. /**
  3. * 当增加新的状态时非常不方便
  4. */
  5. public class MM {
  6. String name;
  7. MMState state = new MMHappyState();
  8. public void smile() {
  9. state.smile();
  10. }
  11. public void cry() {
  12. state.cry();
  13. }
  14. public void say() {
  15. state.say();
  16. }
  17. }

GOF中的例子是TCPConnection(TCP有不同状态)

  • operation不会再拓展的时候用State模式,否则State就不适合用(拓展操作需要给每一个状态修改代码添加方法)
  • 当State不会拓展的时候,干脆就用switch,没必要拓展出这么多子类

有限状态机(FSM)

  • 状态之间的迁移变化
  • 多用途、跨学科
  • 线程的状态迁移
  • 线程挂起进入就绪状态,不会释放锁 线程挂起suspend与恢复resume
  • block不消耗cpu,timewaiting消耗cpu因为要计时
  • State模式和有限状态机是两个东西(一般会提到FSM举例?)

image.png

线程状态根据不同动作转移到相应状态

根据状态决定动作 LockSupport

ThreadState_抽象类(实体或名词用抽象类,动作或形容词用接口)

  1. package com.mashibing.dp.state.thread;
  2. public abstract class ThreadState_ {
  3. abstract void move(Action input);
  4. abstract void run();
  5. }

NewState类

  1. package com.mashibing.dp.state.thread;
  2. public class NewState extends ThreadState_ {
  3. private Thread_ t;
  4. public NewState(Thread_ t) {
  5. this.t = t;
  6. }
  7. @Override
  8. void move(Action input) {
  9. if(input.msg == "start")
  10. t.state = new RunningState(t);
  11. }
  12. @Override
  13. void run() {
  14. }
  15. }

RunningState类

  1. package com.mashibing.dp.state.thread;
  2. public class RunningState extends ThreadState_ {
  3. private Thread_ t;
  4. public RunningState(Thread_ t) {
  5. this.t = t;
  6. }
  7. @Override
  8. void move(Action input) {
  9. // TODO
  10. }
  11. @Override
  12. void run() {
  13. }
  14. }

TerminatedState类

  1. package com.mashibing.dp.state.thread;
  2. public class TerminatedState extends ThreadState_ {
  3. private Thread_ t;
  4. public TerminatedState(Thread_ t) {
  5. this.t = t;
  6. }
  7. @Override
  8. void move(Action input) {
  9. // TODO
  10. }
  11. @Override
  12. void run() {
  13. }
  14. }

Action类(动作)

  1. package com.mashibing.dp.state.thread;
  2. public class Action {
  3. String msg;
  4. }

Thread_类

  1. package com.mashibing.dp.state.thread;
  2. public class Thread_ {
  3. ThreadState_ state;
  4. void move(Action input) {
  5. // 根据现态和动作转移到下一状态
  6. state.move(input);
  7. }
  8. void run() {
  9. state.run();
  10. }
  11. }

思想:将对象作为构造方法的参数传进另一对象,让另一对象对当前对象进行操作!!!

练习拓展

image.png