1. 程式人生 > >《大話設計模式》java實現之狀態模式

《大話設計模式》java實現之狀態模式

狀態模式、策略模式、責任鏈模式三者非常像,今天花了很多時間查詢他們之間的不同,部落格https://www.cnblogs.com/xibei666/p/6858145.html總結得很好,這裡簡單總結一下。現在總結如下:
UML圖狀態模式和策略模式基本一致
狀態模式
這裡寫圖片描述
策略模式
這裡寫圖片描述
從UML圖可以看出,狀態模式和策略模式完全一樣,細微的區別主要是狀態模式各狀態子類知道下一狀態是誰,且要把邏輯判斷轉移到各個狀態子類中,客戶端不需要了解狀態遷移的順序,但是策略目的是針對單一演算法的執行時替換,客戶端需要事先了解策略,主動去選擇合適的策略,不存在狀態的自動遷移!
責任鏈的職責不彼此依賴,不知道下一個職責是誰,組裝過程可以由環境動態配置,很靈活,如struts裡的filter的順序可以由xml指定。
其實設計模式的初衷主要是優化程式碼,同一個問題著重點不同,因此可以選用不同的模式,只要起到優化程式碼的功能,其實沒必要太過注重叫什麼名字。
重寫書中的程式碼時,只重寫了其中的三個狀態,並且把State由抽象類改成了介面,往知悉。
程式碼結構這裡寫圖片描述

public class AfternoonState implements State {

    @Override
    public void writeProgram(Work w) {
        System.out.println("當前時間: " + w.getHour() + "下午狀態還不錯,繼續努力");
    }

}
public class Client {
    public static void main(String[] args) {
        Work emergencyProjects = new Work();
        emergencyProjects.setHour(9
); emergencyProjects.writeProgram(); emergencyProjects.setHour(12); emergencyProjects.writeProgram(); emergencyProjects.setHour(13); emergencyProjects.writeProgram(); } }
public class ForenoonState implements State {

    @Override
    public void writeProgram
(Work w) { if(w.getHour() < 12) { System.out.println("當前時間:" + w.getHour() + "點,上午工作,精神百倍"); } else { w.setState(new NoonState()); w.writeProgram(); } } }
public class NoonState implements State {

    @Override
    public void writeProgram(Work w) {
        if(w.getHour() < 13) {
            System.out.println("當前時間:" + w.getHour() + "點,餓了,午飯:午休");
        } else {
            w.setState(new AfternoonState());
            w.writeProgram();
        }
    }

}
public interface State {
    void writeProgram(Work w);
}
public class Work {
    private State current;
    private int hour;

    public void setState(State state) {
        this.current = state;
    }

    public int getHour() {
        return hour;
    }

    public void setHour(int hour) {
        this.hour = hour;
    }

    public Work() {
        current = new ForenoonState(); //工作狀態初始化為上午工作狀態,即9點開始上班
    }

    public void writeProgram() {
        current.writeProgram(this);
    }
}

執行結果
這裡寫圖片描述