zoukankan      html  css  js  c++  java
  • state模式

    您現在正設計一個交通號誌程式,假設目前只有紅、綠、黃三個燈號,您也許會這麼設計:

    class TrafficLight {
    private enum State {RED, GREEN, YELLOW}
    private State state = State.RED;
    void change() {
    switch(state) {
    case RED:
    System.out.println("紅燈");
    sleep(5000);
    state = State.GREEN;
    break;
    case GREEN:
    System.out.println("綠燈");
    sleep(5000);
    state = State.YELLOW;
    break;
    case YELLOW:
    System.out.println("黃燈");
    sleep(1000);
    state = State.RED;
    }
    }
    private void sleep(int second) {
    try {
    Thread.sleep(second);
    }
    catch(InterruptedException e) {
    e.printStackTrace();
    }
    }
    }


    這是以結構化的方式來設計,優點是簡單直覺,缺點是若狀態增多(也許增加多個時相燈號)時,整個流程會變得冗長,如果狀態變化非線性結構(如紅--> 綠-->黃),可能有兩個或多個方向的狀態變化時,結構化的設計方式,將會增加更多層次的判斷,造成程式碼閱讀、管理的麻煩。

    可以考慮讓每個狀態各自成為一個物件,負責自己該狀態的服務,並提供切換狀態的方法

    interface State {
    void change(TrafficLight light);
    }

    abstract class Light implements State {
    public abstract void change(TrafficLight light);
    protected void sleep(int second) {
    try {
    Thread.sleep(second);
    }
    catch(InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    class Red extends Light {
    public void change(TrafficLight light) {
    System.out.println("紅燈");
    sleep(5000);
    light.set(new Green()); // 如果考慮彈性調整狀態,可以不用寫死狀態物件設定
    }
    }

    class Green extends Light {
    public void change(TrafficLight light) {
    System.out.println("綠燈");
    sleep(5000);
    light.set(new Yellow());
    }
    }

    class Yellow extends Light {
    public void change(TrafficLight light) {
    System.out.println("黃燈");
    sleep(1000);
    light.set(new Red());
    }
    }

    class TrafficLight {
    private State current = new Red();
    void set(State state) {
    this.current = state;
    }
    void change() {
    current.change(this);
    }
    }

    public class Main {
    public static void main(String[] args) {
    TrafficLight trafficLight = new TrafficLight();
    while(true) {
    trafficLight.change();
    }
    }
    }

    當狀態的轉換有方向性時,這樣的設計就很有彈性,正如範例所示的,對於單一方向性的狀態變化,可以提供一個change()方法來轉換狀態,如果狀態有前後切換,則可以提供back()、forward()方法來切換,依此類推...

    以Python來實現這個範例:

    import time

    class Red:
    def change(self, light):
    print("紅燈")
    time.sleep(5)
    light.set(Green())

    class Green:
    def change(self, light):
    print("綠燈")
    time.sleep(5)
    light.set(Yellow())

    class Yellow:
    def change(self, light):
    print("黃燈")
    time.sleep(1)
    light.set(Red())

    class TrafficLight:
    def __init__(self):
    self.current = Red()

    def set(self, state):
    self.current = state

    def change(self):
    self.current.change(self)

    trafficLight = TrafficLight()
    while True:
    trafficLight.change()

    以UML表示State模式結構:


  • 相关阅读:
    Mybatis获取插入记录的自增长ID
    mybatisGenerator 代码自动生成报错 Result Maps collection already contains value for BaseResultMap
    <c:if test="value ne, eq, lt, gt,...."> 用法
    大话设计模式之----状态模式
    php文件加锁 lock_sh ,lock_ex
    in_array 判断问题的疑惑解决。
    我是一只IT小小鸟观后感
    《世界是数字的》
    我是一只IT小小鸟
    解压缩
  • 原文地址:https://www.cnblogs.com/xiayong123/p/3717458.html
Copyright © 2011-2022 走看看