State Pattern)

Source: Internet
Author: User

State Pattern)
1. What is the status mode? Encapsulate all actions in the status object. The status holder entrusts the action to the current status object. That is, the status holder (such as a car, TV, or ATM) has multiple statuses) I don't know the details of the action. The status owner only cares about his current state (which State object is held), and then gives everything to the current State object for care, you do not even need to control the status switch. (Of course, the status holder has the right to control the status switch. You can also choose to do the shopkeeper ..) II. for example, if we want to simulate an ATM, we have the following requirements: to withdraw money, verify the password, and spit out cash. if the service ends, if the password verification fails or the balance is insufficient, the card will pop up directly, after the Service is completed, No Cash is saved on the machine, No Cash is displayed, and No Service is displayed when the machine fault is sent to the bank, the process of user withdrawal should be as follows: This is the process of user operation. For ATM machines, pay attention to the following points: after obtaining the amount entered by the user, not only must the user card balance be verified, but also the balance in the ATM machine should be checked every time the successful withdrawal service ends (if there is no bill, the balance should be processed accordingly) errors that cannot be handled at any stage are handled according to the fault ------- think about the above withdrawal process, we must also consider various illegal operations, such: if you do not need to insert a card or directly enter the password when the machine fails, and you still need to subscribe the money in the operating machine without a bill, we will find the details become very troublesome and the machine will be there, all user interfaces are open, and users are likely to use any interfaces at any time to prevent these illegal Operation, we have to add a series of judgments, such as: Check whether the card has been inserted before verifying the password, and whether the machine has a fault plug-in card before the machine should check whether the machine has a fault withdrawal operation before the machine should check whether the machine is faulty, whether there is no money, whether... In our code, we need to set a large number of member variables to identify the State of the machine. What's more terrible is that there are a large number of if-else in our logic block, in addition, the if-else block in each operation only has minor differences. It looks like redundancy, but it is not easy to handle (even if we propose every judgment as an independent method, code size can be reduced, but the processing process is still redundant ..) A better solution is to use the State mode to completely eliminate the redundancy of the State judgment part and provide a clear and tidy code structure ------- the following uses the state mode to implement the requirements in the example (1) first, find all the interface cards provided by the ATM to submit the password for withdrawal (assuming that the withdrawal button is a physical key) query (assuming the same as above) card fetch (2) find out all the statuses of the ATM and the actions corresponding to each status are Ready (Ready). Available interfaces: NoCash, available interfaces:, fault (NoService ), available interfaces: No (3) encoding implementation first defines the State base class, which encapsulates all interfaces listed in (1): package StatePattern; /*** define the ATM machine status ** @ author ayqy */public interface ATM state {/*** plug-in card */public abstract void insertCard (); /*** submit the password */public abstract void submitPwd ();/*** withdraw money */public abstract void getCash (); /*** query balance */public abstract void queryBalance ();/*** fetch card */public abstract void ejectCard ();} implement three states one by one: ReadyState: package StatePattern;/*** implement ATM ready state * @ author ayqy */public class ReadyState implements ATM state {private atm ATM; // reference of the holder of the reserved state, in order to operate on it public ReadyState (ATM atm) {this. atm = atm;} @ Override public void insertCard () {System. out. println ("plug-in completed") ;}@ Override public void submitPwd () {System. out. println ("password submitted"); // verify the password and handle it accordingly if ("123 ". equals (atm. getPwd () {System. out. println ("Password verified");} else {System. out. println ("password verification failed"); // The ejectCard () ;}@override public void getCash () {if (atm. getTotalAmount ()> = atm. getAmount () & atm. getBalance ()> = atm. getAmount () {// update the account balance atm. setBalance (atm. getBalance ()-atm. getAmount (); // update the total number of cash in the machine atm. setTotalAmount (atm. getTotalAmount ()-atm. getAmount (); System. out. println ("Spit $" + atm. getAmount (); System. out. println ("withdrawal completed"); // The ejectCard () is displayed; // check if (atm. getTotalAmount () = 0) {// if there is no bill, switch to the NoService status atm. setCurrState (atm. getNoCashState (); System. out. println ("No banknote information has been sent to the Bank");} else {System. out. println ("withdrawal failed, insufficient balance"); // The ejectCard () ;}@override public void queryBalance () {System. out. println ("balance $" + atm. getBalance (); System. out. println ("balance query completed") ;}@ Override public void ejectCard () {System. out. println ("card acquisition completed") ;}note the status switch section in the status class: if (atm. getTotalAmount () = 0) {// if there is no bill, switch to the NoService status atm. setCurrState (atm. getNoCashState ();} instead of directly creating a specific State object, we use the set interface provided by the ATM. This is done to decouple as much as possible (brothers do not know each other ), get more flexible implementation NoCashState: package StatePattern;/*** implement the ATM cashless state * @ author ayqy */public class NoCashState implements ATM state {private atm ATM; // retain the reference of the Status holder to operate on it. public NoCashState (ATM atm) {this. atm = atm;} @ Override public void insertCard () {System. out. println ("plug-in completed") ;}@ Override public void submitPwd () {System. out. println ("password submitted"); // verify the password and handle it accordingly if ("123 ". equals (atm. getPwd () {System. out. println ("Password verified");} else {System. out. println ("password verification failed"); // The ejectCard () ;}@override public void getCash () {System. out. println ("withdrawal failed, no bill in the Machine");} @ Override public void queryBalance () {System. out. println ("balance $" + atm. getBalance (); System. out. println ("balance query completed") ;}@ Override public void ejectCard () {System. out. println ("card acquisition completed") ;}} implement NoServiceState: package StatePattern; /*** implement the ATM fault status * @ author ayqy */public class NoServiceState implements ATM state {private atm ATM; // reference of the holder of the retention status, in order to operate on it public NoServiceState (ATM atm) {this. atm = atm;} @ Override public void insertCard () {System. out. println ("plug-in failed, Machine Fault") ;}@ Override public void submitPwd () {System. out. println ("password submission failed, Machine Fault") ;}@ Override public void getCash () {System. out. println ("withdrawal failed, machine failed") ;}@ Override public void queryBalance () {System. out. println ("balance query failed, machine failed") ;}@ Override public void ejectCard () {System. out. println ("failed to pick up the card, the machine fails") ;}} the specific status is implemented to construct the ATM class, just like this: package StatePattern; /*** implement ATM machine * @ author ayqy */public class ATM {/* All statuses */private ATM state readyState; private ATM state noCashState; private ATM state noServiceState; private ATM state currState; // The current status is private int totalAmount; // The total number of cash in the instance/* The temporary variable for testing */private String pwd; // The password is private int balance; // The balance is private int amount; // withdrawal amount public ATM (int totalAmount, int balance, int amount, String pwd) throws Exception {// Initialize all States readyState = new ReadyState (this ); noCashState = new NoCashState (this); noServiceState = new NoServiceState (this); if (totalAmount> 0) {currState = readyState;} else if (totalAmount = 0) {currState = noCashState;} else {throw new Exception () ;}// initialize the test data this. totalAmount = totalAmount; this. balance = balance; this. amount = amount; this. pwd = pwd;}/* delegate specific behavior to the status object * // **** card plug-in */public void insertCard () {currState. insertCard ();}/*** submit password */public void submitPwd () {currState. submitPwd ();}/*** withdrawal */public void getCash () {currState. getCash ();}/*** query balance */public void queryBalance () {currState. queryBalance ();}/*** card acquisition */public void ejectCard () {currState. ejectCard ();} public String toString () {return "Total number of banknotes ¥" + totalAmount;}/* a large number of getter and setter are skipped here */}. Everything is done, I can't wait to test it. the running example first implements a Test class: package StatePattern; import java. util. implementation;/*** implementation Test class * @ author ayqy */public class Test {public static void main (String [] args) {/* test data * // * Total number of on-site accounts balance withdrawal amount password * 1000 500 200 123 1000*300 500 123*0 500 200 123 **/try {test (1000,500,200, "123"); System. out. println ("-------"); test (1000,300,500, "123"); System. out. println ("-------"); test (0,500,200, "123");} catch (Exception e) {System. out. println ("Machine Fault, repair request sent to repair party") ;}} private static void test (int totalAmount, int balance, int amount, String pwd) throws Exception {// create an ATM atm; atm = new ATM (totalAmount, balance, amount, pwd); // output the initial state System. out. println (atm. toString (); atm. insertCard (); atm. submitPwd (); atm. getCash (); // output end state System. out. println (atm. toString ());}}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.