狀态模式
- 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
************