行为型设计模式 - 状态模式详解

状态模式(State Pattern)主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题,类的行为是基于它的状态改变的。

模式结构

行为型设计模式 - 状态模式详解

Context(环境角色):用于维护 State 实例,这个实例定义当前状态

State(抽象状态):定义一个接口以封装与 Context 的一个特定状态相关的行为

ConcreteState(具体状态):每一子类实现一个与 Context 的一个状态相关的行为

举例说明

我们以抽奖的场景作为例子,流程如下:

行为型设计模式 - 状态模式详解

定义一个抽象状态:State

public interface State { //报名 void signUp(); //抽奖 boolean raffle(); //发奖品 void sendPrize(); }

具体状态1:不能抽奖

public class NotRaffleState implements State { private RaffleActivity activity; public NotRaffleState(RaffleActivity activity) { this.activity = activity; } @Override public void signUp() { if(activity.getCount() <= 0){ System.out.println("奖品没有了,下次再来吧"); activity.setState(activity.getNoPrizeState()); return; } System.out.println("报名成功,可以抽奖了"); activity.setState(activity.getCanRaffleState()); } @Override public boolean raffle() { System.out.println("还没有报名"); return false; } @Override public void sendPrize() { System.out.println("还没有报名"); } }

具体状态2:可以抽奖

public class CanRaffleState implements State { private RaffleActivity activity; public CanRaffleState(RaffleActivity activity) { this.activity = activity; } @Override public void signUp() { System.out.println("已经报过名了"); } @Override public boolean raffle() { if(activity.getCount() <= 0){ System.out.println("奖品没有了,下次再来吧"); activity.setState(activity.getNoPrizeState()); return false; } //模拟五分之一的中奖几率 int n = new Random().nextInt(5); if (n == 0) { //抽中,进入发放奖品的状态 System.out.println("恭喜你,抽中了"); activity.setState(activity.getSendPrizeState()); return true; } else { //未抽中,回到初始状态 System.out.println("很遗憾,没有抽中"); activity.setState(activity.getNotRaffleState()); return false; } } @Override public void sendPrize() { System.out.println("还未进行抽奖"); } }

具体状态3:发放奖品

public class SendPrizeState implements State { private RaffleActivity activity; public SendPrizeState(RaffleActivity activity) { this.activity = activity; } @Override public void signUp() { System.out.println("已经报过名了"); } @Override public boolean raffle() { System.out.println("已经参与抽奖了"); return false; } @Override public void sendPrize() { int count = activity.getCount(); //没有奖品了 if (count <= 0) { activity.setState(activity.getNoPrizeState()); } else { activity.setCount(--count); System.out.println("奖品已发送"); activity.setState(activity.getNotRaffleState()); } } }

具体状态4:奖品领完

public class NoPrizeState implements State { private RaffleActivity activity; public NoPrizeState(RaffleActivity activity) { this.activity = activity; } @Override public void signUp() { System.out.println("奖品没有了,下次再来吧"); } @Override public boolean raffle() { System.out.println("奖品没有了,下次再来吧"); return false; } @Override public void sendPrize() { System.out.println("奖品没有了,下次再来吧"); } }

环境角色:抽奖活动

public class RaffleActivity { private State state; //当前状态 private int count; //奖品数量 private State notRaffleState = new NotRaffleState(this); private State canRaffleState = new CanRaffleState(this); private State sendPrizeState = new SendPrizeState(this); private State noPrizeState = new NoPrizeState(this); public RaffleActivity(int count) { this.state = getNotRaffleState(); //初始状态设为不能抽奖状态 this.count = count; } public void signUp() { state.signUp(); } public void raffle() { if (state.raffle()) { state.sendPrize(); } } //省略getter setter }

客户端

public class Client { @Test public void test(){ RaffleActivity activity = new RaffleActivity(1); for (int i = 0; i < 5; i++) { System.out.println("第" + (i + 1) + "次抽奖"); activity.signUp(); activity.raffle(); System.out.println("------------------"); } } }

运行结果

第1次抽奖 报名成功,可以抽奖了 很遗憾,没有抽中 ------------------ 第2次抽奖 报名成功,可以抽奖了 恭喜你,抽中了 奖品已发送 ------------------ 第3次抽奖 奖品没有了,下次再来吧 奖品没有了,下次再来吧 ------------------ 第4次抽奖 奖品没有了,下次再来吧 奖品没有了,下次再来吧 ------------------ 第5次抽奖 奖品没有了,下次再来吧 奖品没有了,下次再来吧 ------------------ 模式分析

优点:

代码具有较强的可读性。状态模式将每个状态的行为封装到对应的一个类中

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdxzj.html