设计模式学习--状态模式(State Pattern)

  • 和程序状态机(PSM)不同,状态模式用类代表状态。

  • Context会将行为委托给当前状态对象。

  • 通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。

  • 状态模式和策略模式有相同的类图,但是它们的意图不同。

  • 策略模式通常会用行为或算法来配置Context类。

  • 状态模式允许Context随着状态的改变而改变行为。

  • 状态转换可以由State类或Context类控制。

  • 使用状态模式通常会导致设计中类的数目大量增加。

  • 状态类可以被多个Context实例共享。

例子 糖果机

———————————————————————————————————————————————————

先来看一下状态模式的类图

1. Context

定义客户感兴趣的接口。

维护一个ConcreteState子类的实例,这个实例定义当前状态。

GumballMachine.java

package gumballstate;

/**

  • 2013/7/12

  • @author wwj

  • 糖果机

  • 利用状态模式

*/

public class GumballMachine {

State soldOutState; //售空状态

State noQuarterState; //没有投入25分钱

State hasQuarterState; //有25分钱了

State soldState; //出售状态

State winnerState; //10%的中奖率

State state = soldOutState;

int count = 0;

public GumballMachine(int numberGumballs) {

soldOutState = new SoldOutState(this);

noQuarterState = new NoQuarterState(this);

hasQuarterState = new HasQuarterState(this);

soldState = new SoldState(this);

winnerState = new WinnerState(this);

this.count = numberGumballs;

if(numberGumballs > 0) {

state = noQuarterState;

}

}

public void insertQuarter() {

state.insertQuarter();

}

public void ejectQuarter() {

state.ejectQuarter();

}

public void turnCrank() {

state.turnCrank();

state.dispense();

}

void setState(State state) {

this.state = state;

}

public State getState() {

return state;

}

void releaseBall() {

System.out.println(“A gumball comes rolling out the slot…”);

if(count != 0) {

count = count - 1;

}

}

public State getSoldOutState() {

return soldOutState;

}

public State getNoQuarterState() {

return noQuarterState;

}

public State getHasQuarterState() {

return hasQuarterState;

}

public State getSoldState() {

return soldState;

}

public State getWinnerState() {

return winnerState;

}

public int getCount() {

return count;

}

public String toString() {

StringBuffer result = new StringBuffer();

result.append(“\nMighty Gumball, Inc.”);

result.append(“\nJava-enabled Standing Gumball Model #2004”);

result.append(“\nInventory: " + count + " gumball”);

if (count != 1) {

result.append(“s”);

}

result.append(“\n”);

result.append("Machine is " + state + “\n”);

return result.toString();

}

}

2.State

定义一个接口以封装与Context的一个特定状态相关的行为。

State.java

package gumballstate;

/**

  • 状态接口

  • @author wwj

*/

public interface State {

void insertQuarter();

void ejectQuarter();

void turnCrank();

void dispense();

}

3.ConcreteStateSubClasses

每一个子类实现与context的一个状态相关的行为

NoQuarterState.java

package gumballstate;

/**

  • 2013/7/12

  • @author wwj

  • 实现状态接口状态类:没有25分钱

*/

public class NoQuarterState implements State {

GumballMachine gumballMachine;

public NoQuarterState(GumballMachine gumballMachine2) {

this.gumballMachine = gumballMachine2;

}

@Override

public void insertQuarter() { //如果有人投入了25分钱,就将状态转换为HasQuarterState

System.out.println(“You inserted a quarter”);

}

@Override

public void ejectQuarter() { //如果没给钱,就不能要求退钱

System.out.println(“You haven’t inserted a quarter”);

}

@Override

public void turnCrank() { //如果没给钱,就不能要求糖果

System.out.println(“You turned, but there’s no quarter”);

}

@Override

public void dispense() { //如果没得到钱,我们就不能发放糖果

System.out.println(“You need to pay first”);

}

}

HasQuarterState.java

package gumballstate;

import java.util.Random;

public class HasQuarterState implements State {

Random randomWinner = new Random(System.currentTimeMillis()); //随机数产生器

GumballMachine gumballMachine;

public HasQuarterState(GumballMachine gumballMachine) {

this.gumballMachine = gumballMachine;

}

public void insertQuarter() {

System.out.println(“You can’t insert another quarter”);

}

public void ejectQuarter() {

System.out.println(“Quarter returned”);

gumballMachine.setState(gumballMachine.getNoQuarterState());

}

public void turnCrank() {

System.out.println(“You turned…”);

int winner = randomWinner.nextInt(10); //参数0~10的随机数

if((winner == 0) && (gumballMachine.getCount() > 1)) { //如果随机树为0,且足够的糖果的话,则可以得到两颗糖果

gumballMachine.setState(gumballMachine.getWinnerState());

} else {

gumballMachine.setState(gumballMachine.getSoldState());

}

}

public void dispense() {

System.out.println(“No gumball dispensed”);

}

public String toString() {

return “waiting for turn of crank”;

}

}

SoldState.java

package gumballstate;

public class SoldState implements State {

GumballMachine gumballMachine;

public SoldState(GumballMachine gumballMachine) {

this.gumballMachine = gumballMachine;

}

public void insertQuarter() {

System.out.println(“Please wait, we’re already giving you a gumball”);

}

public void ejectQuarter() {

System.out.println(“Sorry, you already turned the crank”);

}

public void turnCrank() {

System.out.println(“Turning twice doesn’t get you another gumball!”);

}

public void dispense() {

gumballMachine.releaseBall();

if (gumballMachine.getCount() > 0) {

gumballMachine.setState(gumballMachine.getNoQuarterState());

} else {

System.out.println(“Oops, out of gumballs!”);

gumballMachine.setState(gumballMachine.getSoldOutState());

}

}

public String toString() {

return “dispensing a gumball”;

}

}

SoldOutState.java

package gumballstate;

public class SoldOutState implements State {

GumballMachine gumballMachine;

public SoldOutState(GumballMachine gumballMachine) {

this.gumballMachine = gumballMachine;

}

public void insertQuarter() {

System.out.println(“You can’t insert a quarter, the machine is sold out”);

}

public void ejectQuarter() {

System.out.println(“You can’t eject, you haven’t inserted a quarter yet”);

}

public void turnCrank() {

System.out.println(“You turned, but there are no gumballs”);

}

public void dispense() {

System.out.println(“No gumball dispensed”);

}

public String toString() {

return “sold out”;

}

}

WinnerState.java

package gumballstate;

public class WinnerState implements State {

GumballMachine gumballMachine;

public WinnerState(GumballMachine gumballMachine) {

this.gumballMachine = gumballMachine;

}

public void insertQuarter() {

System.out.println(“Please wait, we’re already giving you a Gumball”);

}

public void ejectQuarter() {

System.out.println(“Please wait, we’re already giving you a Gumball”);

}

public void turnCrank() {

System.out.println(“Turning again doesn’t get you another gumball!”);

}

public void dispense() {

System.out.println(“YOU’RE A WINNER! You get two gumballs for your quarter”);

gumballMachine.releaseBall();

if (gumballMachine.getCount() == 0) {

gumballMachine.setState(gumballMachine.getSoldOutState());

} else {

gumballMachine.releaseBall();

if (gumballMachine.getCount() > 0) {

gumballMachine.setState(gumballMachine.getNoQuarterState());

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节

整理不易,望各位看官老爷点个关注转发,谢谢!祝大家都能得到自己心仪工作。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

public void dispense() {

System.out.println(“YOU’RE A WINNER! You get two gumballs for your quarter”);

gumballMachine.releaseBall();

if (gumballMachine.getCount() == 0) {

gumballMachine.setState(gumballMachine.getSoldOutState());

} else {

gumballMachine.releaseBall();

if (gumballMachine.getCount() > 0) {

gumballMachine.setState(gumballMachine.getNoQuarterState());

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节

[外链图片转存中…(img-QhVKOuHn-1715147437254)]

整理不易,望各位看官老爷点个关注转发,谢谢!祝大家都能得到自己心仪工作。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 30
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值