状态模式
核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:
1、可以通过改变状态来获得不同的行为。
2、你的好友能同时看到你的变化。看图:
State类是个状态类,Context类可以实现切换,我们来看看代码:
实例代码一:
public class State {
private String value;
public State() {
}
public State(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void method1(){
System.out.println("execute the first opt!");
}
public void method2(){
System.out.println("execute the second opt!");
}
}
****************************************************
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void method() {
if(state.getValue().equals("state1")) {
state.method1();
}else if(state.getValue().equals("state2")) {
state.method2();
}
}
}
********************************************************
/**
* 状态模式state
* 根据这个特性,状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。
*/
public class MainClass {
public static void main(String[] args) {
State state = new State();
Context context = new Context(state);
state.setValue("state1");
context.method();
System.out.println("*********************************");
state.setValue("state2");
context.method();
}
}
***********************
测试结果:
execute the first opt!
*********************************
execute the second opt!
实例代码二:
public abstract class State {
public abstract void doSomething(Person person);
}
*************************************************************
public class MState extends State{
@Override
public void doSomething(Person person) {
if(person.getHour() == 7) {
System.out.println("吃早餐");
}else {
person.setState(new LState());
person.doSomething();
}
}
}
*************************************************************
public class LState extends State {
@Override
public void doSomething(Person person) {
if(person.getHour() == 12) {
System.out.println("吃午餐");
}else {
person.setState(new SState());
person.doSomething();
}
}
}
*************************************************************
public class SState extends State {
@Override
public void doSomething(Person person) {
if(person.getHour() == 18) {
System.out.println("吃晚餐");
}else {
person.setState(new NoState());
person.doSomething();
}
}
}
*************************************************************
public class NoState extends State {
@Override
public void doSomething(Person person) {
System.out.println(person.getHour()+"未定义");
}
}
*************************************************************
public class Person {
private int hour;
private State state;
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public Person(int hour) {
this.hour = hour;
}
public Person() {
state = new MState();
}
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public void doSomething() {
// if(hour==7) {
// State state = new MState();
// state.doSomething();
// }else if(hour==12) {
// State state = new LState();
// state.doSomething();
// }else if(hour==18) {
// State state = new SState();
// state.doSomething();
// }else {
// State state = new NoState();
// state.doSomething();
// }
state.doSomething(this);
state = new MState();
}
}
*************************************************************
public class MainClass {
public static void main(String[] args) {
Person person = new Person();
person.setHour(7);
person.doSomething();
person.setHour(12);
person.doSomething();
person.setHour(18);
person.doSomething();
person.setHour(8);
person.doSomething();
person.setHour(7);
person.doSomething();
}
}
*****************************************
测试结果:
吃早餐
吃午餐
吃晚餐
8未定义
吃早餐
# 事例
GumballMachine
@Data
public class GumballMachine {
private State state;
private int count;
public State soldOutState;
public State noQuarterState;
public State hasQuarterState;
public State soldState;
public GumballMachine(int count) {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
this.count = count;
if (count > 0) {
state = noQuarterState;
}
}
// 投入硬币
public void insertQuarter() {
state.insertQuarter();
}
// 吐出硬币
public void ejectQuarter() {
state.ejectQuarter();
}
// 转动曲轴,发放奖品
public void turnCrank() {
state.turnCrank();
state.dispense();
}
void releaseBall(){
System.out.println("A gumball comes rolling out the slot...");
if(count != 0){
count--;
}
}
}
State接口
public interface State {
/**投币*/
void insertQuarter();
/**退币*/
void ejectQuarter();
/**转动曲轴*/
void turnCrank();
/**发放奖品*/
void dispense();
}
四个状态
public class HasQuarterState implements State {
private GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
throw new UnsupportedOperationException("HasQuarterState--->已经有硬币,不需要投硬币You had inserted quarter into gumballMachine");
}
@Override
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
@Override
public void turnCrank() {
System.out.println("You turned...");
gumballMachine.setState(gumballMachine.getSoldState());
}
@Override
public void dispense() {
throw new UnsupportedOperationException("HasQuarterState--->No gumball dispensed 没有奖品");
}
}
/**
* @auhtor
* @create 2023-07-25-9:56
* 无硬币状态
*/
public class NoQuarterState implements State{
private GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("Quarter insert");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
@Override
public void ejectQuarter() {
throw new UnsupportedOperationException("NoQuarterState--->没硬币,不可退硬币You haven't inserted a quarter");
}
@Override
public void turnCrank() {
throw new UnsupportedOperationException("NoQuarterState-->没硬币,不可转动曲轴You turned, but there's no quarter");
}
@Override
public void dispense() {
throw new UnsupportedOperationException("NoQuarterState-->No gumball dispensed 没有奖品You need to pay firs");
}
}
/**
* @auhtor
* @create 2023-07-25-9:56
* 售罄状态
*/
public class SoldOutState implements State{
private GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
throw new UnsupportedOperationException("SoldOutState--->售罄,不可投入硬币The gumball is sold out");
}
@Override
public void ejectQuarter() {
throw new UnsupportedOperationException("SoldOutState--->售罄,不可退硬币You haven't insert a quarter");
}
@Override
public void turnCrank() {
throw new UnsupportedOperationException("SoldOutState--->售罄,不可转动曲轴Gumball is sold out");
}
@Override
public void dispense() {
throw new UnsupportedOperationException("SoldOutState--->售罄,没有奖品No gumball to dispense");
}
}
/**
* @auhtor
* @create 2023-07-25-9:57
* 可售状态
*/
public class SoldState implements State{
private GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
throw new UnsupportedOperationException("SoldState--->已经有硬币,不需要投硬币Please wait a moment,we will dispense a gumball");
}
@Override
public void ejectQuarter() {
throw new UnsupportedOperationException("SoldState--->不可退硬币 Sorry,you already turned a quarter");
}
@Override
public void turnCrank() {
throw new UnsupportedOperationException("SoldState--->Turning twice doesn't get you another gumball");
}
@Override
public void dispense() {
gumballMachine.releaseBall();
if(gumballMachine.getCount() == 0) {
System.out.println("Oops, out of gumballs!");
System.out.println("-----------------------------------------------------");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
else {
System.out.println("恭喜中奖");
System.out.println("-----------------------------------------------------");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
}
}
测试
public class MainClient {
public static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(5);
for (int i = 0; i < 10; i++) {
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
}
}
}
Quarter insert
You turned...
A gumball comes rolling out the slot...
恭喜中奖
-----------------------------------------------------
Quarter insert
You turned...
A gumball comes rolling out the slot...
恭喜中奖
-----------------------------------------------------
Quarter insert
You turned...
A gumball comes rolling out the slot...
恭喜中奖
-----------------------------------------------------
Quarter insert
You turned...
A gumball comes rolling out the slot...
恭喜中奖
-----------------------------------------------------
Quarter insert
You turned...
A gumball comes rolling out the slot...
Oops, out of gumballs!
-----------------------------------------------------
Exception in thread "main" java.lang.UnsupportedOperationException: SoldOutState--->售罄,不可投入硬币The gumball is sold out
at StateAppro.SoldOutState.insertQuarter(SoldOutState.java:18)