本文共 5587 字,大约阅读时间需要 18 分钟。
状态模式是一种设计模式,主要用于解决对象在不同状态下表现出不同的行为问题。通过将状态和行为分开管理,可以让对象在状态变化时灵活地展示不同的行为,实现更灵活的状态管理。
抽奖活动可以处于以下四个状态:
不能抽奖状态(NoRaffleState)
可以抽奖状态(CanRaffleState)
发放奖品状态(DispenseState)
奖品发放完毕状态(DispenseOutState)
从 NoRaffleState 转换到 CanRaffleState
扣除积分成功后,用户可以抽奖。从 CanRaffleState 转换到 DispenseState 或 NoRaffleState
抽奖成功则转换为 DispenseState,抽奖失败则转换为 NoRaffleState。从 DispenseState 转换到 NoRaffleState
发放完毕后,用户无法继续抽奖。从 DispenseOutState 无法转换
State 接口
提供与上下文相关的基本操作,如扣除积分、抽奖、发放奖品。ConcreteState 实现类
定义具体的状态行为,如 CanRaffleState、NoRaffleState 等。Context 类
维护当前状态实例,提供状态切换的方法。package com.lm.state;public interface State { void deduceMoney(); boolean raffle(); void dispensePrize();}
package com.lm.state;public class NoRaffleState extends State { RaffleActivity activity; public NoRaffleState(RaffleActivity activity) { this.activity = activity; } @Override public void deduceMoney() { System.out.println("扣除50积分成功,您可以抽奖了"); activity.setState(activity.getCanRaffleState()); } @Override public boolean raffle() { System.out.println("扣了积分才能抽奖喔!"); return false; } @Override public void dispensePrize() { System.out.println("不能发放奖品"); }}
package com.lm.state;public class CanRaffleState extends State { RaffleActivity activity; public CanRaffleState(RaffleActivity activity) { this.activity = activity; } @Override public void deduceMoney() { System.out.println("已经扣取过了积分"); } @Override public boolean raffle() { System.out.println("正在抽奖,请稍等!"); Random r = new Random(); int num = r.nextInt(10); if (num == 0) { activity.setState(activity.getDispenseState()); return true; } else { System.out.println("很遗憾没有抽中奖品!"); activity.setState(activity.getNoRaffleState()); return false; } } @Override public void dispensePrize() { System.out.println("没中奖,不能发放奖品"); }}
package com.lm.state;public class RaffleActivity { private State state; private int count; NoRaffleState noRaffleState = new NoRaffleState(this); CanRaffleState canRaffleState = new CanRaffleState(this); DispenseState dispenseState = new DispenseState(this); DispenseOutState dispenseOutState = new DispenseOutState(this); public RaffleActivity(int count) { state = getNoRaffleState(); this.count = count; } public void deduceMoney() { state.deduceMoney(); } public void raffle() { if (state.raffle()) { state.dispensePrize(); } } public State getState() { return state; } public void setState(State state) { this.state = state; } public int getCount() { int curCount = count; count--; return curCount; } public void setCount(int count) { this.count = count; } public NoRaffleState getNoRaffleState() { return noRaffleState; } public void setNoRaffleState(NoRaffleState noRaffleState) { this.noRaffleState = noRaffleState; } public CanRaffleState getCanRaffleState() { return canRaffleState; } public void setCanRaffleState(CanRaffleState canRaffleState) { this.canRaffleState = canRaffleState; } public DispenseState getDispenseState() { return dispenseState; } public void setDispenseState(DispenseState dispenseState) { this.dispenseState = dispenseState; } public DispenseOutState getDispenseOutState() { return dispenseOutState; } public void setDispenseOutState(DispenseOutState dispenseOutState) { this.dispenseOutState = dispenseOutState; }}
package com.lm.state;public class Client { public static void main(String[] args) { RaffleActivity activity = new RaffleActivity(1); for (int i = 0; i < 30; i++) { System.out.println("--------第 " + (i + 1) + " 次抽奖--------"); activity.deduceMoney(); activity.raffle(); } }}
借贷平台的订单管理涉及多个状态转换,如审核、发布、抢单等。状态模式可以有效地管理这些状态转换,提高代码的可读性和维护性。
+------------+ +----------------+| | | || | --> | |+------------+ +----------------+ | | v v+------------+ +----------------+| | | || | <-- |审核通过 |+------------+ +----------------+ | | v v+------------+ +----------------+| | | || | --> |发布 |+------------+ +----------------+ | | v v+------------+ +----------------+| | | || | <-- |已发布 |+------------+ +----------------+
| 事件 | 状态转换 | 备注 ||------|----------|------|| 审核 | 通过 | 修改为已审核状态 || 审核 | 未通过 | 修改为已拒绝状态 || 发布 | | 将订单状态改为已发布 || 接单 | | 将订单状态改为已接单 || 失效 | | 将订单状态改为已失效 ||付款 | | 将订单状态改为已付款 || 失败 | | 将订单状态改为已失败 || 反馈 | | 将订单状态改为已反馈 |
可读性
状态模式将每个状态的行为封装到对应的类中,代码结构清晰,便于维护和理解。可扩展性
状态模式支持轻松添加新的状态,减少了大量的 if-else 判断,提高了代码的可维护性。开闭原则
状态模式符合开闭原则,便于新增状态或修改现有状态的行为。适用性
适用于状态多且互相转换的场景,特别是在需要动态管理对象行为的系统中。潜在问题
状态模式会增加类的数量,管理大量状态时可能导致代码复杂化。转载地址:http://eugiz.baihongyu.com/