Programming an Object s Memory with State Attributes


Programming an Object’s Memory with State Attributes

Some of your objects have complex lifecycles. We use state diagrams like the one in Figure 16-1 to help us understand an object’s life and what an object has to remember from one moment in its life to the next. The customer-account objects that make up our running example in this chapter are not simple data structures holding information about current customer balances. There are also rules they must obey to live life to the fullest:

  • When a customer first opens an account, the customer’s credit must be validated.

  • After the account is validated, it is put on trial to see whether the customer always maintains a positive balance and always pays their invoices within thirty days.

  • After the trial period is over, the account is established and can be renewed every three years.

  • At some point, the customer account is archived—for example, when there is no activity in the account for a period of five years.

  • Money can’t be withdrawn from the customer account while it’s being validated. Money can only be withdrawn when the account is in the trial period or when it’s fully established.

 Tip   Since the customer account is an object it can remember its current state and that is enough to help you program for all these rules. For example, you can program the withdraw method of the object to work only if the object has already been opened. This is easily done if you use an attribute to capture the current state of the object and then your withdraw method check that state attribute to see whether it’s set properly. We use the following steps to give the CustomerAccount class memory of what it has done (using the Java programming language):

  1. Create several fixed attributes that represent each state of the class.

    In this example, we need attributes representing the Validating, OnTrial, Established, Renewing, and Archived states. Each attribute representing a state gets initialized with a separate integer value.

  2. Next we provide an attribute to capture the current state and another attribute to capture the current balance of the account.

    We use the following code to make this happen:

     Public class CustomerAccount {    private int accInitialized = 0;    private int accValidating = 1;    private int accOnTrial = 2;    private int accEstablished = 3;    private int accRenewing = 4;    private int accArchived = 5;    private int currentState = 0;    private int beginningBalance = 0;    private float currentBalance = accInitialized; 
  3. Set the current state.

    Some of the operations change the currentState. For instance, the open operation that opens a customer account checks beforehand to make sure the currentState is set to its initial value. (It makes sense to not let you open an account that is already open.) Then the operation sets the currentState to the value of the attribute representing the validating state. Now the operation can ask the customer’s credit card whether it’s valid. If everything checks out, we set the currentState by setting the current state to the value of the accOnTrial attribute and the currentBalance of the account is set to the beginningBalance.

    Each operation that causes a change in state must set the currentState attribute to the correct value. Why? So the object can remember what it’s been doing. For example, the following code for the open operation first checks the currentState.

       public Boolean open(Currency beginningBalance) {    if (currentState == accInitialized) then {        currentState = accValidating;      // validating        if (myCreditCard.valid = True) then {           currentState = accOnTrial;      // now on trial           currentBalance = beginningBalance;        }}} 

    If currentState is set to the value of accInitialized then the code changes the currentState to the value of accValidating. Next the valid operation is invoked on an instance of the CreditCard class—myCreditCard. If the valid operation returns True, then the currentState is changed to the value of the attribute representing the OnTrial state and the currentBalance is set to the value of the beginningBalance attribute.

  4. Check current state.

    Some of the operations can only execute if the object is in the correct state. You can also check to be sure state-based business rules are followed. When (for example) the withdraw operation is invoked on an instance of the CustomerAccount class, the operation must check to see whether the object is in the OnTrial or the Established state. If so, then the operation can reduce the currentBalance by the withdrawal amount. Given the rules for CustomerAccount, this operation needs to check to see if the withdrawal amount exceeds the current balance, which would yield a negative balance. If a negative balance is achieved while the CustomerAccount is in the OnTrial state, the operation fails and another object is notified of the failure.

    The withdraw operation for CustomerAccount looks like the following code in the Java programming language:

       public Currency withdraw (Currency amount) {    if ((currentState == accOnTrial) or         (currentState == accEstablished)) then       currentBalance = currentBalance - amount;    if ((currentState == accOnTrial) and         (currentBalance < 0)) then { onTrialManager.failure(this);       currentBalance = amount + currentBalance;       return currentBalance;}     else       return currentBalance;   }} 

    This code first checks to see if the currentState is set to the attribute value representing either the OnTrial or the Established state. If so, the code then deducts the withdrawal amount from the currentBalance to come up with a new currentBalance. Next the code checks to see if the state of the account is equal to the attribute value representing the OnTrial state. If the currentBalance is less than zero, the failure operation of another object—an instance of the TrialManager class called onTrialManager—is invoked. Next the currentBalance is reset to the original amount. In other words, the customer account balance remains unchanged and no currency is withdrawn from the account. The old value for the balance of the account is returned. On the other hand if everything worked out correctly, the account balance is changed and the new current balance is returned.

Now you know that your objects not only have a life, they also remember what they’ve done during their lives. Your objects can get very complex.




UML 2 for Dummies
UML 2 For Dummies
ISBN: 0764526146
EAN: 2147483647
Year: 2006
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net