[关闭]
@Tyhj 2019-01-31T08:56:02.000000Z 字数 2190 阅读 404

状态模式

设计模式


原文:https://www.jianshu.com/p/176eb110a081

定义

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类

使用场景

  • 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为
  • 代码中包含大量与对象状态有关的语句条件

理解

其实很好理解,就是对象可以改变自身的状态,状态改变后,行为也会跟着改变

实现方法

一般是根据对象行为提取出接口,不同的状态有不同的实现类,然后对象中有改变状态的方法,对象的行为依赖实现类去实现,状态改变后把相应的实现类替换掉,从而改变对象的行为;感觉上和策略模式有些相像,但是解决的问题不同

举个栗子

很多软件都有用户系统,都需要实名认证绑定手机号,比如有一篇文章,我点击收藏、点赞、分享的时候可能就有三种情况:未登录、登录未绑定手机、已登录;

第一个版本

  1. package state;
  2. public class Essay {
  3. //未登录
  4. private static final int NEED_REGISTER = 1;
  5. //没有绑定手机号
  6. private static final int NEED_PHONE = 2;
  7. //正常登录
  8. private static final int REGISTERED = 3;
  9. /**
  10. * 当前状态
  11. */
  12. private int mState = 1;
  13. /**
  14. * 点赞,登录就可以了
  15. */
  16. public void like() {
  17. if (mState == NEED_REGISTER) {
  18. System.out.println("请先登录");
  19. } else if (mState == NEED_PHONE || mState == REGISTERED) {
  20. System.out.println("点赞成功");
  21. }
  22. }
  23. /**
  24. * 分享,可以随意分享
  25. */
  26. public void share() {
  27. System.out.println("分享到朋友圈成功");
  28. }
  29. /**
  30. * 收藏,必须绑定手机号
  31. */
  32. public void collect() {
  33. if (mState == NEED_REGISTER) {
  34. System.out.println("请先登录");
  35. } else if (mState == NEED_PHONE) {
  36. System.out.println("请先绑定手机号");
  37. } else if (mState == REGISTERED) {
  38. System.out.println("收藏成功");
  39. }
  40. }
  41. }

无论在哪里判断状态,这些条件语句是少不了的,看起来比较麻烦,不利于维护,要是在多添加几个状态可能就更糟糕了,使用状态模式试试

先抽象出行为

  1. public interface OperateState {
  2. /**
  3. * 分享
  4. */
  5. void share();
  6. /**
  7. * 点赞
  8. */
  9. void like();
  10. /**
  11. * 收藏
  12. */
  13. void collect();
  14. }

实现未登录状态的行为

  1. public class NeedRegisterState implements OperateState {
  2. @Override
  3. public void share() {
  4. System.out.println("分享到朋友圈成功");
  5. }
  6. @Override
  7. public void like() {
  8. System.out.println("请先登录");
  9. }
  10. @Override
  11. public void collect() {
  12. System.out.println("请先登录");
  13. }
  14. }

实现未绑定手机的行为

  1. package state;
  2. public class NeedPhoneState implements OperateState {
  3. @Override
  4. public void share() {
  5. System.out.println("分享到朋友圈成功");
  6. }
  7. @Override
  8. public void like() {
  9. System.out.println("点赞成功");
  10. }
  11. @Override
  12. public void collect() {
  13. System.out.println("请先绑定手机号");
  14. }
  15. }

实现正常登录的行为

  1. public class Registed implements OperateState {
  2. @Override
  3. public void share() {
  4. System.out.println("分享到朋友圈成功");
  5. }
  6. @Override
  7. public void like() {
  8. System.out.println("点赞成功");
  9. }
  10. @Override
  11. public void collect() {
  12. System.out.println("收藏成功");
  13. }
  14. }

最后对象的实现

  1. public class Essay {
  2. private OperateState operateState;
  3. /**
  4. * 改变状态
  5. *
  6. * @param operateState
  7. */
  8. public void changeState(OperateState operateState) {
  9. this.operateState = operateState;
  10. }
  11. public void like() {
  12. operateState.like();
  13. }
  14. public void share() {
  15. operateState.share();
  16. }
  17. public void collect() {
  18. operateState.collect();
  19. }
  20. }

总结

类虽然变多了,但是思路清晰了,也更易于维护了;既然使用设计模式就是要降低耦合,抽象接口,分离代码,类变多也是正常的吧

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注