状态模式
- 1.什么是状态模式
- 2.核心思想
- 3.角色
- 4.例子
- 4.1 项目结构
- 4.2抽象的状态
- 4.3具体的状态
- 4.4 抽象的事物
- 4.5 具体的事物
- 4.6使用者
- 4.7 结果
- 5.扩展
- 5.1项目结构
- 5.2 抽象的中介者
- 5.3 具体的中介者
- 5.4 使用者
- 5.5 结果
- 6.总结
23种设计模式
1.什么是状态模式
对于一个事物,不同的状态下有不同的操作,那么需要知道事物的操作时,需要先判断事物的状态,然后调用事物的操作。
举一个通俗的例子:人在1天里有不同事情需要做,如果把每一个小时作为1个状态,那么人在1天里有24个状态,每个状态的操作都不同。
通常的做法是,首先判断现在是什么时间,从而获取到这个人现在的状态是什么,然后执行相应的方法。那么24个状态需要25个if分支判断(包含一个其他)。
当状态更多时,需要更多的分支。
为了解决因为状态多而判断分支多的问题,状态模式可以避免这种情况。
2.核心思想
首先,对于不同的状态,我们抽象一个状态的接口,这里定义了每一个状态都必须执行的方法。
然后每一种状态都是一个类,实现抽象的状态,并且自定义自己的操作。
然后改变不同的子类去执行抽象类中定义的方法,这样就实现了不同的状态之间的切换但不需要使用判断分支。
依赖于状态的操作
我们定义了状态的接口,然后定义了许多的实际的状态。切换的状态不同,执行的操作也不同。
委托
实际上我们并需要调用状态的方法,我们的目的是调用事物的方法,只是因为状态的不同,事物执行的操作不同。
所以,在事物的操作里面对于抽象的状态做一个委托,根据当前事物持有的实际的状态,调用实际的状态的方法。
3.角色
抽象的状态:定义事物在所有的状态下都有的方法
实际的状态:不同状态下不同的操作
抽象的事物:定义事物的状态的切换以及执行抽象状态方法的方法
实际的事物:实现方法,委托。
4.例子
4.1 项目结构
4.2抽象的状态
package state.intf;
public interface AbsState {
public void sayState();
}
4.3具体的状态
package state.impl;
import state.intf.AbsState;
public class State0 implements AbsState{
@Override
public void sayState() {
System.out.println(this.getClass().getName());
}
}
package state.impl;
import state.intf.AbsState;
public class State1 implements AbsState{
@Override
public void sayState() {
System.out.println(this.getClass().getName());
}
}
package state.impl;
import state.intf.AbsState;
public class State2 implements AbsState{
@Override
public void sayState() {
System.out.println(this.getClass().getName());
}
}
package state.impl;
import state.intf.AbsState;
public class State3 implements AbsState{
@Override
public void sayState() {
System.out.println(this.getClass().getName());
}
}
package state.impl;
import state.intf.AbsState;
public class State4 implements AbsState{
@Override
public void sayState() {
System.out.println(this.getClass().getName());
}
}
package state.impl;
import state.intf.AbsState;
public class State5 implements AbsState{
@Override
public void sayState() {
System.out.println(this.getClass().getName());
}
}
4.4 抽象的事物
package people.abs;
import state.intf.AbsState;
public abstract class People {
protected String name;
protected String message;
protected AbsState absState;
public void changeState(AbsState absState){
this.absState = absState;
}
protected void sayState(){
this.absState.sayState();
}
protected String getName() {
return name;
}
protected void setName(String name) {
this.name = name;
}
protected String getMessage() {
return message;
}
protected void setMessage(String message) {
this.message = message;
}
}
4.5 具体的事物
package people.impl;
import people.abs.People;
public class People1 extends People{
public void sayState(){
System.out.println(getName());
this.absState.sayState();
System.out.println(getMessage());
}
public String getName() {
return super.name;
}
public void setName(String name) {
super.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
4.6使用者
package client;
import java.util.ArrayList;
import java.util.List;
import people.impl.People1;
import state.impl.State0;
import state.impl.State1;
import state.impl.State2;
import state.impl.State3;
import state.impl.State4;
import state.impl.State5;
import state.intf.AbsState;
public class Main {
public static void main(String[] args) {
System.out.println("create a people");
People1 people1 = new People1();
people1.setName("lili");
people1.setMessage("hello");
System.out.println("people init over");
System.out.println(people1.getName());
System.out.println(people1.getMessage());
System.out.println("init states");
List<AbsState> states = new ArrayList<AbsState>();
states.add(new State0());
states.add(new State1());
states.add(new State2());
states.add(new State3());
states.add(new State4());
states.add(new State5());
for(AbsState state : states){
state.sayState();
}
System.out.println("states over");
System.out.println("now let us 60 times");
for(int i = 0;i < 60;i++){
System.out.println("******"+i+"******");
people1.changeState(states.get(i%6));
people1.sayState();
System.out.println("************");
}
}
}
4.7 结果
↓
create a people
people init over
lili
hello
init states
state.impl.State0
state.impl.State1
state.impl.State2
state.impl.State3
state.impl.State4
state.impl.State5
states over
now let us 60 times
******0******
lili
state.impl.State0
hello
************
******1******
lili
state.impl.State1
hello
************
******2******
lili
state.impl.State2
hello
************
******3******
lili
state.impl.State3
hello
************
******4******
lili
state.impl.State4
hello
************
******5******
lili
state.impl.State5
hello
************
******6******
lili
state.impl.State0
hello
************
******7******
lili
state.impl.State1
hello
************
******8******
lili
state.impl.State2
hello
************
******9******
lili
state.impl.State3
hello
************
******10******
lili
state.impl.State4
hello
************
******11******
lili
state.impl.State5
hello
************
******12******
lili
state.impl.State0
hello
************
******13******
lili
state.impl.State1
hello
************
******14******
lili
state.impl.State2
hello
************
******15******
lili
state.impl.State3
hello
************
******16******
lili
state.impl.State4
hello
************
******17******
lili
state.impl.State5
hello
************
******18******
lili
state.impl.State0
hello
************
******19******
lili
state.impl.State1
hello
************
******20******
lili
state.impl.State2
hello
************
******21******
lili
state.impl.State3
hello
************
******22******
lili
state.impl.State4
hello
************
******23******
lili
state.impl.State5
hello
************
******24******
lili
state.impl.State0
hello
************
******25******
lili
state.impl.State1
hello
************
******26******
lili
state.impl.State2
hello
************
******27******
lili
state.impl.State3
hello
************
******28******
lili
state.impl.State4
hello
************
******29******
lili
state.impl.State5
hello
************
******30******
lili
state.impl.State0
hello
************
******31******
lili
state.impl.State1
hello
************
******32******
lili
state.impl.State2
hello
************
******33******
lili
state.impl.State3
hello
************
******34******
lili
state.impl.State4
hello
************
******35******
lili
state.impl.State5
hello
************
******36******
lili
state.impl.State0
hello
************
******37******
lili
state.impl.State1
hello
************
******38******
lili
state.impl.State2
hello
************
******39******
lili
state.impl.State3
hello
************
******40******
lili
state.impl.State4
hello
************
******41******
lili
state.impl.State5
hello
************
******42******
lili
state.impl.State0
hello
************
******43******
lili
state.impl.State1
hello
************
******44******
lili
state.impl.State2
hello
************
******45******
lili
state.impl.State3
hello
************
******46******
lili
state.impl.State4
hello
************
******47******
lili
state.impl.State5
hello
************
******48******
lili
state.impl.State0
hello
************
******49******
lili
state.impl.State1
hello
************
******50******
lili
state.impl.State2
hello
************
******51******
lili
state.impl.State3
hello
************
******52******
lili
state.impl.State4
hello
************
******53******
lili
state.impl.State5
hello
************
******54******
lili
state.impl.State0
hello
************
******55******
lili
state.impl.State1
hello
************
******56******
lili
state.impl.State2
hello
************
******57******
lili
state.impl.State3
hello
************
******58******
lili
state.impl.State4
hello
************
******59******
lili
state.impl.State5
hello
************
↑
5.扩展
在上面的例子中,使用者持有所有的状态,并且完成切换。
现在使用中介者(仲裁者)模式来解决。
5.1项目结构
5.2 抽象的中介者
package mediator.abs;
import people.abs.People;
public abstract class Mediator {
protected People people;
protected abstract void changeState(int num);
public Mediator(People people){
this.people = people;
}
public void sayState(int num){
changeState(num);
people.sayState();
}
}
5.3 具体的中介者
使用反射
package mediator.impl;
import people.abs.People;
import mediator.abs.Mediator;
import state.intf.AbsState;
public class MediatorImpl extends Mediator{
public MediatorImpl(People people) {
super(people);
}
@Override
protected void changeState(int num) {
try {
super.people.changeState((AbsState) Class.forName(
"state.impl.State"+ (num % 6)).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
5.4 使用者
package client;
import mediator.abs.Mediator;
import mediator.impl.MediatorImpl;
import people.impl.People1;
public class Main {
public static void main(String[] args) {
System.out.println("create a people");
People1 people1 = new People1();
people1.setName("lili");
people1.setMessage("hello");
System.out.println("people init over");
System.out.println(people1.getName());
System.out.println(people1.getMessage());
System.out.println("create Mediator");
Mediator mediator = new MediatorImpl(people1);
System.out.println("Mediator over");
System.out.println("now let us 60 times");
for(int i = 0;i < 60;i++){
System.out.println("******"+i+"******");
mediator.sayState(i);
System.out.println("************");
}
}
}
5.5 结果
↓
create a people
people init over
lili
hello
create Mediator
Mediator over
now let us 60 times
******0******
lili
state.impl.State0
hello
************
******1******
lili
state.impl.State1
hello
************
******2******
lili
state.impl.State2
hello
************
******3******
lili
state.impl.State3
hello
************
******4******
lili
state.impl.State4
hello
************
******5******
lili
state.impl.State5
hello
************
******6******
lili
state.impl.State0
hello
************
******7******
lili
state.impl.State1
hello
************
******8******
lili
state.impl.State2
hello
************
******9******
lili
state.impl.State3
hello
************
******10******
lili
state.impl.State4
hello
************
******11******
lili
state.impl.State5
hello
************
******12******
lili
state.impl.State0
hello
************
******13******
lili
state.impl.State1
hello
************
******14******
lili
state.impl.State2
hello
************
******15******
lili
state.impl.State3
hello
************
******16******
lili
state.impl.State4
hello
************
******17******
lili
state.impl.State5
hello
************
******18******
lili
state.impl.State0
hello
************
******19******
lili
state.impl.State1
hello
************
******20******
lili
state.impl.State2
hello
************
******21******
lili
state.impl.State3
hello
************
******22******
lili
state.impl.State4
hello
************
******23******
lili
state.impl.State5
hello
************
******24******
lili
state.impl.State0
hello
************
******25******
lili
state.impl.State1
hello
************
******26******
lili
state.impl.State2
hello
************
******27******
lili
state.impl.State3
hello
************
******28******
lili
state.impl.State4
hello
************
******29******
lili
state.impl.State5
hello
************
******30******
lili
state.impl.State0
hello
************
******31******
lili
state.impl.State1
hello
************
******32******
lili
state.impl.State2
hello
************
******33******
lili
state.impl.State3
hello
************
******34******
lili
state.impl.State4
hello
************
******35******
lili
state.impl.State5
hello
************
******36******
lili
state.impl.State0
hello
************
******37******
lili
state.impl.State1
hello
************
******38******
lili
state.impl.State2
hello
************
******39******
lili
state.impl.State3
hello
************
******40******
lili
state.impl.State4
hello
************
******41******
lili
state.impl.State5
hello
************
******42******
lili
state.impl.State0
hello
************
******43******
lili
state.impl.State1
hello
************
******44******
lili
state.impl.State2
hello
************
******45******
lili
state.impl.State3
hello
************
******46******
lili
state.impl.State4
hello
************
******47******
lili
state.impl.State5
hello
************
******48******
lili
state.impl.State0
hello
************
******49******
lili
state.impl.State1
hello
************
******50******
lili
state.impl.State2
hello
************
******51******
lili
state.impl.State3
hello
************
******52******
lili
state.impl.State4
hello
************
******53******
lili
state.impl.State5
hello
************
******54******
lili
state.impl.State0
hello
************
******55******
lili
state.impl.State1
hello
************
******56******
lili
state.impl.State2
hello
************
******57******
lili
state.impl.State3
hello
************
******58******
lili
state.impl.State4
hello
************
******59******
lili
state.impl.State5
hello
************
↑
6.总结
主要还是理解一个思想:
类来表示状态
不同的类对应不同状态的操作
需要哪个状态就设置状态变量的值为相应的类的对象
就会执行正确的操作。
23种设计模式