- Design Principles for Checking Business Rules
- Designing Business Rules Checking
- Property Write Accessors with Business Rule Checking
- Collaboration Accessors with Business Rule Checking
- Conclusion
Property Write Accessors with Business Rule Checking
Property business rules specify the legal values or ranges for properties. For purposes of rule checking there are two kind of properties: enumerated and continuous. An enumerated property can only take on a value that is within a set of fixed values. A typical enumerated property is a status property that can take on one of the following values: pending, completed, or cancelled. A continuous property is defined by a range of values or is open-ended. Examples of continuous properties are a date property and a name property.
Continuous Property Write Accessors
A continuous property has a single write accessor that accepts a value, a single business rule test method to validate the value, and a single assignment method to store the value. (See Table 1.)
Table 1. Methods for Changing the State of Continuous Property X
setX(aValue) |
Public write accessor to change the value of property X to aValue. |
testSetX(aValue) |
Business rule method to validate aValue as a value for property X. |
doSetX(aValue) |
Assignment method to assign aValue as the value for property X. |
Internal methods and data management methods that can set the continuous property without rule checking call the doSet method directly. All othersobject editors, methods of other objects, and internal methods needing business rule checkingchange the property through the setX method.
Enumerated Property Write Accessors
An enumerated property has a multiple write accessors, one for each of the enumerated values. Having multiple accessors encapsulated the true representations of the enumerated values. We recommend multiple test methods, too, in place of one test method with a large switch statement. On the other hand, one doSet method is usually adequate. (See Table 2.)
Table 2. Methods for Changing the State of Enumerated Property X
setXY |
Public write accessor to set the value of property X to Y. |
testSetXY |
Business rule method to validate aValue as a value for property X. |
doSetX(aValue) |
Assignment method to assign aValue as the value for property X. |
Property Write Accessors Example
An online commodity brokerage assigns brokers to handle every sale order through the order workflow process. Each sale order has a date indicating when it was entered into the system, a unique identifier, and a status that is either pending, completed, or cancelled. (See Figure 1.)
Figure 1. A sale order assigned to a broker.
A partial listing for the sale order's property write accessors is shown in Listing 1. The date property does not have a write accessor because it is set only once when the sale order is created, but it does have a public doSet method to allow object reconstruction from persistent storage.
For the status property, only the status-completed methods are shown. There are similar methods for setting the status to accepted and canceled. Business rules dictate how the status property changes:
If the status is pending, it can transition to completed or cancelled.
If the status is completed, it cannot transition to cancelled or pending.
If the status is cancelled, it cannot transition to pending or completed.
The identifier write accessor has a logical test to check that the string value is not null or empty. The test for uniqueness of the identifier is part of the business rule test method.
Listing 1. Property Accessors for Sale Order
/* PUBLIC ACCESS METHODS */ public void setStatusCompleted() throws BusinessRuleException { this.testSetStatusCompleted(); this.doSetStatus(STATUS_COMPLETED); } public void setIdentifier(String aString) throws BusinessRuleException { if ((aString == null) || (aString.length() == 0)) { throw new BusinessRuleException("Identifier cannot be null or empty."); } this.testSetIdentifier(aString); this.doSetIdentifier(aString); } /* BUSINESS RULE CHECKING METHODS */ public void testSetStatusCompleted() throws BusinessRuleException { if (this.isStatusPending()) return; else { throw new BusinessRuleException("Non-pending sale Order cannot become completed."); } } public void testSetIdentifier (String aString) throws BusinessRuleException { // <snip> code for checking uniqueness of identifier. } /* ASSIGNMENT METHODS */ public void doSetStatus(NominationStatus aStatus) { this.status = aStatus; } public void doSetIdentifier(String aString) { this.identifier = aString; } public void doSetDate(Date aDate) { this.date = aDate; }