事务的状态(状态模式)
生活随笔
收集整理的這篇文章主要介紹了
事务的状态(状态模式)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【0】README
0.1)本文部分文字描述轉自 “head first設計模式”,旨在學習 ?事務的狀態(狀態模式) 的基礎知識;
【1】應用場景一 1.1)還記得成都市各大高校內的米源自動售賣機嗎?售賣機的主要制造商發現,只要把CPU 放入機器,可以提高銷量。于是乎,它們提供了一幅自動售賣機的狀態圖給我們,希望我們用java 幫他實現,且代碼富有彈性易于擴展(下面以米源糖果售賣機為例給出狀態圖);
1.2)具體實現(for downloading, please visit ?https://github.com/pacosonTang/HeadFirstDesignPattern/tree/master/state_pattern_10/chapter10)
【4】狀態模式和策略模式的區別 4.1)狀態模式:我們將一群行為封裝在狀態對象中,context的行為隨時可委托到那些狀態對象中的一個。隨著時間的流失,當前狀態在狀態對象集合中游走改變,以反映出 context內部的狀態,因此,context的行為也會跟著改變; 4.2)策略模式:客戶通常主動指定Context 所要組合的策略對象是哪一個?,F在,固然策略模式讓我們具有彈性,能夠在運行時改變策略。但對于某個context對象來說,通常都只有一個 最適當的策略對象。 4.3)Conclusion:
【1】應用場景一 1.1)還記得成都市各大高校內的米源自動售賣機嗎?售賣機的主要制造商發現,只要把CPU 放入機器,可以提高銷量。于是乎,它們提供了一幅自動售賣機的狀態圖給我們,希望我們用java 幫他實現,且代碼富有彈性易于擴展(下面以米源糖果售賣機為例給出狀態圖);
1.2)具體實現(for downloading, please visit ?https://github.com/pacosonTang/HeadFirstDesignPattern/tree/master/state_pattern_10/chapter10)
- step1)米源售賣機實現
- public class CandyMachine {private final static int SOLD_OUT = 0; // 售罄狀態private final static int NO_QUARTER = 1; // 無幣狀態,QUARTER==25美分==幣private final static int HAS_QUARTER = 2; // 有幣狀態private final static int SOLD = 3; // 售賣狀態private int state = SOLD_OUT;private int count = 0;public CandyMachine(int count) {this.count = count;if(count > 0) {this.state = NO_QUARTER;}}public void insertQuarter() { // client投幣請求if(state == HAS_QUARTER) {System.out.println("you can't insert another quarter.");} else if(state == NO_QUARTER) {System.out.println("you insert a quarter.");state = HAS_QUARTER;} else if(state == SOLD_OUT) {System.out.println("you can't insert a quarter for the machine is sold out.");} else if(state == SOLD) {System.out.println("please wait, we're already gibing you a candy.");}}public void ejectQuarter() { // client請求退錢if(state == HAS_QUARTER) {System.out.println("quarter returned.");state = NO_QUARTER;} else if(state == NO_QUARTER) {System.out.println("you haven't inserted a quarter.");} else if(state == SOLD_OUT) {System.out.println("you can't eject for you haven't inserted a quarter yet.");} else if(state == SOLD) {System.out.println("sorry, you already trune the crank.");}}public void turnCrank() { // client轉動曲柄動作if(state == HAS_QUARTER) {System.out.println("you turned, please wait....");state = SOLD;dispense();} else if(state == NO_QUARTER) {System.out.println("you turned but there is no quarter.");} else if(state == SOLD_OUT) {System.out.println("you truned but there's no candy.");} else if(state == SOLD) {System.out.println("turning twice doesn't get you another candy.");}}private void dispense() { // 分發糖果if(state == HAS_QUARTER) {System.out.println("no candy dispensed.");} else if(state == NO_QUARTER) {System.out.println("you need to insert a quarter first.");} else if(state == SOLD_OUT) {System.out.println("no candy dispensed.");} else if(state == SOLD) {System.out.println("a candy comes rolling out the slot.");count--;if(count == 0) {System.out.println("Oops, there's no candy.");state = SOLD_OUT;} else {state = NO_QUARTER;}}}@Overridepublic String toString() {String state_str = null;switch (state) {case SOLD_OUT: state_str = "SOLD_OUT"; break;case SOLD: state_str = "SOLD"; break;case NO_QUARTER: state_str = "NO_QUARTER"; break;case HAS_QUARTER: state_str = "HAS_QUARTER"; break;}return "=== I own " + count + " candies, and stay in " + state_str + " state. ===";} }
- step2)測試用例
- public class CandyMachineTest {public static void main(String[] args) {CandyMachine cm = new CandyMachine(5);System.out.println(cm);System.out.println("====== 1st test: ======");cm.insertQuarter();cm.turnCrank();System.out.println(cm);System.out.println("====== 2nd test: ======");cm.insertQuarter();cm.ejectQuarter();//要求售賣機退錢cm.ejectQuarter();//要求售賣機第二次退錢System.out.println("====== 3rd test: ======");cm.insertQuarter();cm.ejectQuarter();cm.turnCrank();// 請求退錢后,不應該得到糖果System.out.println(cm);} }
- step3)打印結果
- === I own 5 candies, and stay in NO_QUARTER state. === ====== 1st test: ====== you insert a quarter. you turned, please wait.... a candy comes rolling out the slot. === I own 4 candies, and stay in NO_QUARTER state. === ====== 2nd test: ====== you insert a quarter. quarter returned. you haven't inserted a quarter. ====== 3rd test: ====== you insert a quarter. quarter returned. you turned but there is no quarter. === I own 4 candies, and stay in NO_QUARTER state. ===
- step1)定義一個狀態接口(State),在這個接口內,售賣機的每個動作有一個對應方法;
- public abstract class State {protected String name;public abstract void insertQuarter();public abstract void ejectQuarter();public abstract void trunCrank();public abstract void dispense();public String getName() {return name;} }
- step2)創建該狀態接口的子類,實現售賣機的相應方法;
- // 售罄狀態 public class SoldOutState extends State {CandyMachine machine;public SoldOutState(CandyMachine machine) {super.name = "SoldOutState";this.machine = machine;}@Overridepublic void insertQuarter() {System.out.println("you can't insert a quarter for there's no candies."); }@Overridepublic void ejectQuarter() {System.out.println("you have not inserted a quarter.");}@Overridepublic void trunCrank() {System.out.println("you turned but there is no quarter.");}@Overridepublic void dispense() {System.out.println("you need to insert a quarter first."); }}public class NoQuarterState extends State {CandyMachine machine;public NoQuarterState(CandyMachine machine) {super.name = "NoQuarterState";this.machine = machine;}@Overridepublic void insertQuarter() {System.out.println("you insert a quatter.");machine.setState(machine.getHasQuarterState());}@Overridepublic void ejectQuarter() {if(machine.getState() == machine.getHasQuarterState()) {System.out.println("returned a quarter.");machine.setState(machine.getNoQuarterState());} else {System.out.println("you have not inserted a quarter.");}}@Overridepublic void trunCrank() {System.out.println("you turned but there is no quarter.");}@Overridepublic void dispense() {System.out.println("you need to insert a quarter first."); } }// 有幣狀態 public class HasQuarterState extends State {Random random = new Random();CandyMachine machine;public HasQuarterState(CandyMachine machine) {super.name = "HasQuarterState"; this.machine = machine;}@Overridepublic void insertQuarter() {System.out.println("you can't insert another quarter.");}@Overridepublic void ejectQuarter() { // client退錢請求System.out.println("quarter returned.");machine.setState(machine.getNoQuarterState());}@Overridepublic void trunCrank() { // 有幣狀態下,進行幾率性中獎測試System.out.println("you turned , please waiting......");int winner = random.nextInt(5);System.out.println("\nrandom winner == " + winner);if(winner == 2 && machine.getCount() > 1) {machine.setState(machine.getWinnerState());} else {machine.setState(machine.getSoldState());}}@Overridepublic void dispense() {System.out.println("no candies dispensed."); } } // 售賣狀態 public class SoldState extends State {CandyMachine machine;public SoldState(CandyMachine machine) {super.name = "SoldState";this.machine = machine;}@Overridepublic void insertQuarter() { System.out.println("please wait, we're already giving you a candy."); }@Overridepublic void ejectQuarter() {System.out.println("sorry, you've already turned the crank.");}@Overridepublic void trunCrank() {System.out.println("turning twice doesn't get you another candy.");}@Overridepublic void dispense() {machine.releaseBall();if(machine.getCount() > 0) {machine.setState(machine.getNoQuarterState());} else {machine.setState(machine.getSoldOutState());}} }
- // 中獎狀態 public class WinnerState extends State {CandyMachine machine;public WinnerState(CandyMachine machine) {this.machine = machine;}@Overridepublic void insertQuarter() {System.out.println("error.");}@Overridepublic void ejectQuarter() { // client退錢請求System.out.println("error.");}@Overridepublic void trunCrank() {System.out.println("error.");}@Overridepublic void dispense() {System.out.println("you're a winner. you get 2 candies for your quarter.");machine.releaseBall();if(machine.getCount() == 0) {machine.setState(machine.getSoldOutState());} else {machine.releaseBall();if(machine.getCount() > 0) {machine.setState(machine.getNoQuarterState());} else {System.out.println("Oops, out of candies.");machine.setState(machine.getSoldOutState());}}} }
- step3)將動作委托到狀態類(構造米源糖果售賣機);
- public class CandyMachine {private State winnerState; //中獎狀態private State soldOutState; // 售罄狀態private State noQuarterState; // 無幣狀態,QUARTER==25美分==幣private State hasQuarterState; // 有幣狀態private State soldState; // 售賣狀態private State state;private int count = 0;public CandyMachine(int count) {soldOutState = new SoldOutState(this);soldState = new SoldState(this);hasQuarterState = new HasQuarterState(this);noQuarterState = new NoQuarterState(this);winnerState = new WinnerState(this);state = soldOutState;this.count = count;if(count > 0) {state = noQuarterState;}}public void insertQuarter() { // client投幣請求state.insertQuarter();}public void ejectQuarter() { // client請求退錢state.ejectQuarter();}public void turnCrank() { // client轉動曲柄動作state.trunCrank();state.dispense();}public void releaseBall() { // 釋放糖果System.out.println("a candy comes rolling out the slot....");if(count != 0) {count--;}}public State getState() {return state;}public void setState(State state) {this.state = state;}public State getSoldOutState() {return soldOutState;}public void setSoldOutState(State soldOutState) {this.soldOutState = soldOutState;}public State getSoldState() {return soldState;}public void setSoldState(State soldState) {this.soldState = soldState;}public State getHasQuarterState() {return hasQuarterState;}public void setHasQuarterState(State hasQuarterState) {this.hasQuarterState = hasQuarterState;}public State getNoQuarterState() {return noQuarterState;}public void setNoQuarterState(State noQuarterState) {this.noQuarterState = noQuarterState;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public State getWinnerState() {return winnerState;}public void setWinnerState(State winner) {this.winnerState = winner;} @Override public String toString() { String state_str = null; switch (state.getName()) { case "SoldOutState": state_str = "SOLD_OUT"; break; case "SoldState": state_str = "SOLD"; break; case "NoQuarterState": state_str = "NO_QUARTER"; break; case "HasQuarterState": state_str = "HAS_QUARTER"; break; } return "=== I own " + count + " candies, and stay in " + state_str + " state. ==="; } }step4)測試用例
- public class CandyMachineTest {public static void main(String[] args) {CandyMachine cm = new CandyMachine(50);System.out.println(cm);System.out.println("====== init state ======");System.out.println(cm);// 第一次測試cm.insertQuarter();cm.turnCrank();System.out.println(cm);// 第二次測試cm.turnCrank();System.out.println(cm);// 第3次測試: 在為投幣的情況下退幣請求cm.ejectQuarter();System.out.println(cm);System.out.println("\n\n ====== 下面進入循環測試(中獎)隨機數==2表示中獎 ======");for (int i = 0; i < 5; i++) {cm.insertQuarter();cm.turnCrank();System.out.println(cm);}} }
- step5)打印結果
- === I own 50 candies, and stay in NO_QUARTER state. === ====== init state ====== === I own 50 candies, and stay in NO_QUARTER state. === you insert a quatter. you turned , please waiting......random winner == 0 a candy comes rolling out the slot.... === I own 49 candies, and stay in NO_QUARTER state. === you turned but there is no quarter. you need to insert a quarter first. === I own 49 candies, and stay in NO_QUARTER state. === you have not inserted a quarter. === I own 49 candies, and stay in NO_QUARTER state. ========= 下面進入循環測試(中獎,為了演示方便,我這里的中獎率為20%,且 <span style="font-family: Arial, Helvetica, sans-serif;">隨機數==2表示中獎</span><span style="font-family: Arial, Helvetica, sans-serif;">) ======</span> you insert a quatter. you turned , please waiting......random winner == 2 you're a winner. you get 2 candies for your quarter. a candy comes rolling out the slot.... a candy comes rolling out the slot.... === I own 47 candies, and stay in NO_QUARTER state. === you insert a quatter. you turned , please waiting......random winner == 4 a candy comes rolling out the slot.... === I own 46 candies, and stay in NO_QUARTER state. === you insert a quatter. you turned , please waiting......random winner == 4 a candy comes rolling out the slot.... === I own 45 candies, and stay in NO_QUARTER state. === you insert a quatter. you turned , please waiting......random winner == 2 you're a winner. you get 2 candies for your quarter. a candy comes rolling out the slot.... a candy comes rolling out the slot.... === I own 43 candies, and stay in NO_QUARTER state. === you insert a quatter. you turned , please waiting......random winner == 0 a candy comes rolling out the slot.... === I own 42 candies, and stay in NO_QUARTER state. ===
【4】狀態模式和策略模式的區別 4.1)狀態模式:我們將一群行為封裝在狀態對象中,context的行為隨時可委托到那些狀態對象中的一個。隨著時間的流失,當前狀態在狀態對象集合中游走改變,以反映出 context內部的狀態,因此,context的行為也會跟著改變; 4.2)策略模式:客戶通常主動指定Context 所要組合的策略對象是哪一個?,F在,固然策略模式讓我們具有彈性,能夠在運行時改變策略。但對于某個context對象來說,通常都只有一個 最適當的策略對象。 4.3)Conclusion:
- C1)一般而言,我們把策略模式想成是除了繼承外的一種彈性替代方案。如果你使用繼承定義了一個類的行為,你將被這個行為所困住,甚至要修改他都很難。有了策略模式,你可以通過組合不同對象來改變行為;
- C2)我們把狀態模式想成是不用在 context 中放置許多條件判斷的替代方案。通過將行為包裝進狀態對象中,你可以通過 context 內簡單地修改狀態對象來改變context 的行為;
總結
以上是生活随笔為你收集整理的事务的状态(状态模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么区分原创和伪原创(怎么区分原创和伪原
- 下一篇: jvm(6)-java类文件结构(字节码