設計模式之狀態模式
狀態模式定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。
用性:1.一個對象的行為取決于它的狀態,并且它必須在運行時刻根據狀態改變它的行為。
2.一個操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態。
這個狀態通常用一個或多個枚舉常量表示。
通常,有多個操作包含這一相同的條件結構。
State模式將每一個條件分支放入一個獨立的類中。
這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴于其他對象而獨立變化。
例子:2.一個操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態。
這個狀態通常用一個或多個枚舉常量表示。
通常,有多個操作包含這一相同的條件結構。
State模式將每一個條件分支放入一個獨立的類中。
這使得你可以根據對象自身的情況將對象的狀態作為一個對象,這一對象可以不依賴于其他對象而獨立變化。
狀態模式在工作流或游戲等各種系統中有大量使用,甚至是這些系統的核心功能設計,例如
政府OA中,一個批文的狀態有多種:未辦;正在辦理;正在批示;正在審核;已經完成等
各種狀態,使用狀態機可以封裝這個狀態的變化規則,從而達到擴充狀態時,不必涉及到狀
態的使用者。
在網絡游戲中,一個游戲活動存在開始;開玩;正在玩;輸贏等各種狀態,使用狀態模式就
可以實現游戲狀態的總控,而游戲狀態決定了游戲的各個方面,使用狀態模式可以對整個游
戲架構功能實現起到決定的主導作用。
狀態模式實質:
使用狀態模式前,客戶端外界需要介入改變狀態,而狀態改變的實現是瑣碎或復雜的。
使用狀態模式后,客戶端外界可以直接使用事件Event實現,根本不必關心該事件導致如
何狀態變化,這些是由狀態機等內部實現。
這是一種Event-condition-State,狀態模式封裝了condition-State部分。
每個狀態形成一個子類,每個狀態只關心它的下一個可能狀態,從而無形中形成了狀態轉換
的規則。如果新的狀態加入,只涉及它的前一個狀態修改和定義。
狀態轉換有幾個方法實現:一個在每個狀態實現next(),指定下一個狀態;還有一種方法,
設定一個StateOwner,在StateOwner設定stateEnter狀態進入和stateExit狀
態退出行為。
狀態從一個方面說明了流程,流程是隨時間而改變,狀態是截取流程某個時間片。
政府OA中,一個批文的狀態有多種:未辦;正在辦理;正在批示;正在審核;已經完成等
各種狀態,使用狀態機可以封裝這個狀態的變化規則,從而達到擴充狀態時,不必涉及到狀
態的使用者。
在網絡游戲中,一個游戲活動存在開始;開玩;正在玩;輸贏等各種狀態,使用狀態模式就
可以實現游戲狀態的總控,而游戲狀態決定了游戲的各個方面,使用狀態模式可以對整個游
戲架構功能實現起到決定的主導作用。
狀態模式實質:
使用狀態模式前,客戶端外界需要介入改變狀態,而狀態改變的實現是瑣碎或復雜的。
使用狀態模式后,客戶端外界可以直接使用事件Event實現,根本不必關心該事件導致如
何狀態變化,這些是由狀態機等內部實現。
這是一種Event-condition-State,狀態模式封裝了condition-State部分。
每個狀態形成一個子類,每個狀態只關心它的下一個可能狀態,從而無形中形成了狀態轉換
的規則。如果新的狀態加入,只涉及它的前一個狀態修改和定義。
狀態轉換有幾個方法實現:一個在每個狀態實現next(),指定下一個狀態;還有一種方法,
設定一個StateOwner,在StateOwner設定stateEnter狀態進入和stateExit狀
態退出行為。
狀態從一個方面說明了流程,流程是隨時間而改變,狀態是截取流程某個時間片。
操作當前狀態類:
public class Context {
private Weather weather;
public void setWeather(Weather weather) {
this.weather = weather;
}
public Weather getWeather() {
return this.weather;
}
public String weatherMessage() {
return weather.getWeather();
}
}
狀態接口:private Weather weather;
public void setWeather(Weather weather) {
this.weather = weather;
}
public Weather getWeather() {
return this.weather;
}
public String weatherMessage() {
return weather.getWeather();
}
}
public interface Weather {
String getWeather();
}
狀態實現類:String getWeather();
}
public class Sunshine implements Weather{
public String getWeather() {
return "陽光";
}
}
public String getWeather() {
return "陽光";
}
}
public class Rain implements Weather{
public String getWeather() {
return "下雨";
}
}
測試類:public String getWeather() {
return "下雨";
}
}
public class Test {
public static void main(String[] args) {
Context ctx1 = new Context();
ctx1.setWeather(new Sunshine());
System.out.println(ctx1.weatherMessage());
System.out.println("===============");
ctx1.setWeather(new Rain());
System.out.println(ctx1.weatherMessage());
}
}
例子2:
public static void main(String[] args) {
Context ctx1 = new Context();
ctx1.setWeather(new Sunshine());
System.out.println(ctx1.weatherMessage());
System.out.println("===============");
ctx1.setWeather(new Rain());
System.out.println(ctx1.weatherMessage());
}
}
例子2:
public class Work {
private State current;
public Work(double hour,boolean finish){
current = new ForenoonState();
this.hour = hour;
this.finish = finish;
}
private double hour;
public double getHour() {
return hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private boolean finish;
public boolean isFinish() {
return finish;
}
public void writeProgram(){
current.writeProgram(this);
}
}
private State current;
public Work(double hour,boolean finish){
current = new ForenoonState();
this.hour = hour;
this.finish = finish;
}
private double hour;
public double getHour() {
return hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private boolean finish;
public boolean isFinish() {
return finish;
}
public void writeProgram(){
current.writeProgram(this);
}
}
public interface State {
void writeProgram(Work work);
}
void writeProgram(Work work);
}
public class ForenoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<12){
System.out.println("工作時間");
}else {
work.setCurrent(new NoonState());
work.writeProgram();
}
}
}
@Override
public void writeProgram(Work work) {
if(work.getHour()<12){
System.out.println("工作時間");
}else {
work.setCurrent(new NoonState());
work.writeProgram();
}
}
}
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<13){
System.out.println("午睡");
}else {
work.setCurrent(new AfterNoonState());
work.writeProgram();
}
}
}
@Override
public void writeProgram(Work work) {
if(work.getHour()<13){
System.out.println("午睡");
}else {
work.setCurrent(new AfterNoonState());
work.writeProgram();
}
}
}
public class AfterNoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<17){
System.out.println("工作");
}else {
work.setCurrent(new EveningState());
work.writeProgram();
}
}
}
@Override
public void writeProgram(Work work) {
if(work.getHour()<17){
System.out.println("工作");
}else {
work.setCurrent(new EveningState());
work.writeProgram();
}
}
}
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if(work.isFinish()){
work.setCurrent(new RestState());
work.writeProgram();
}else {
if(work.getHour()<21){
System.out.println("加班");
}else {
work.setCurrent(new SleepState());
work.writeProgram();
}
}
}
}
@Override
public void writeProgram(Work work) {
if(work.isFinish()){
work.setCurrent(new RestState());
work.writeProgram();
}else {
if(work.getHour()<21){
System.out.println("加班");
}else {
work.setCurrent(new SleepState());
work.writeProgram();
}
}
}
}
public class SleepState implements State {
@Override
public void writeProgram(Work work) {
System.out.println("睡覺");
}
}
@Override
public void writeProgram(Work work) {
System.out.println("睡覺");
}
}