定義
- 用類來表示狀態。
- 行爲隨着狀態對象改變而改變。
使用場景
- 代碼中包含大量與對象狀態有關的條件語句。
- 對象的行爲依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行爲。
UML圖
代碼示例
公交車狀態
// 公交車的狀態
public interface State {
//開門
public void openDoor();
//加速
public void speedUp();
}
//停止狀態
public class StopState implements State {
private static StopState stopState = new StopState();
public static StopState getInstance(){
return stopState;
}
@Override
public void openDoor() {
System.out.println("公交車可以開門上下乘客");
}
@Override
public void speedUp() {
System.out.println("公交車停止狀態無法加速");
}
}
public class RunState implements State {
//使用單例模式
private static RunState runState = new RunState();
public static RunState getInstance(){
return runState;
}
@Override
public void openDoor() {
System.out.println("公交車行駛中無法開門");
}
@Override
public void speedUp() {
System.out.println("公交車行駛中可以加速");
}
}
// 上下文對象
public class Context {
private State state;
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
//測試
public class Client {
public static void main(String[] args) {
Context context = new Context();
context.setState(StopState.getInstance());
context.getState().openDoor();
context.getState().speedUp();
context.setState(RunState.getInstance());
context.getState().openDoor();
context.getState().speedUp();
}
}
- 在《圖解設計模式》中和網上朋友的示例中;都是將狀態切換放在具體狀態類中,如:
public class RunState implements State {
public void changeState(Context context){
context.setState(StopState.getInstance());
}
個人認爲不合適,比如在上面例子中再加一個等紅燈的狀態,介於RunState 和StopState之間,那你得去修改具體的狀態類,違反了開閉原則。個人覺得狀態的切換既然已經在Context維護了,那就直接使用即可。當然如果在程序設計之初,狀態的遷移就已經確認並不會出現我所說的情況則也是可以的。
總結
- 用類表示狀態,行爲隨着狀態對象改變而改變。
- 遵循單一原則,一種狀態一個子類;符合開閉原則,當新增狀態時只需添加一個狀態子類。