35.8. Handling Payments with Polymorphism and Do It Myself
One of the common ways to apply polymorphism (and Information Expert) is in the context of what Peter Coad calls the "Do It Myself" strategy or pattern [Coad95]. That is:
Do It Myself "I (a software object) do those things that are normally done to the actual object that I'm an abstraction of." [Coad95] |
- Credit and debit payments are authorized with an external authorization service. Both require recording a receivable entry in accounts receivablemoney owing from the financial institution that does the authorization.
- Cash payments are authorized in some stores (it is a trend in some countries) using a special paper bill analyzer attached to the POS terminal that checks for counterfeit money. Other stores do not do this.
- Check payments are authorized in some stores using a computerized authorization service. Other stores do not do authorize checks.
CreditPayments are authorized in one way; CheckPayments are authorized in another. This is a classic case for Polymorphism.Thus, as shown in Figure 35.17, each Payment subclass has its own authorize method.
Figure 35.17. Classic polymorphism with multiple
authorize methods.Figure 35.18. Creating a CreditPayment.
Figure 35.19. Creating a CheckPayment.
Fine-Grained Classes?
Consider the creation of the CreditCard, DriversLicense, and Check software objects. Our first impulse might be to record the data they hold simply in their related payment classes, and eliminate such fine-grained classes. However, it is usually a more profitable strategy to use them; they often end up providing useful behavior and being reusable. For example, the CreditCard is a natural Expert on telling you its credit company type (Visa, MasterCard, and so on). This behavior will turn out to be necessary for our application.
Credit Payment Authorization
The system must communicate with an external credit authorization service, and we have already created the basis of the design based on adapters to support this.
Relevant Credit Payment Domain Information
Some context for the upcoming design:
- POS systems are physically connected with external authorization services in several ways, including phone lines (which must be dialed) and always-on broadband Internet connections.
- Different application-level protocols and associated data formats are used, such as Secure Electronic Transaction (SET). New ones may become popular, such as XMLPay.
- Payment authorization can be viewed as a regular synchronous operation: a POS thread blocks, waiting for a reply from the remote service (within the limits of a time-out period).
- All payment authorization protocols involve sending identifiers uniquely identifying the store (with a "merchant ID"), and the POS terminal (with a "terminal ID"). A reply includes an approval or denial code, and a unique transaction ID.
- A store may use different external authorization services for different credit card types (one for Visa, one for MasterCard). For each service, the store has a different merchant ID.
- The credit company type can be deduced from the card number. For example, numbers starting with 5 are MasterCard; numbers starting with 4 are Visa.
- The adapter implementations will protect the upper layers of the system against all these variations in payment authorization. Each adapter is responsible for ensuring the authorization request transaction is in the appropriate format, and for collaborating with the external service. As discussed in a prior iteration, the ServicesFactory is responsible for delivering the appropriate ICreditAuthorizationServiceAdapter implementation.
A Design Scenario
Figure 35.20 starts the presentation of an annotated design that satisfies these details and requirements. Messages are annotated to illustrate the reasoning.
Figure 35.20. Handling a credit payment.
[View full size image]
Figure 35.21. Completing the authorization.
[View full size image]
Figure 35.22. Completion of an approved credit payment.
[View full size image]
Observe in this sequence diagram that some objects were stacked. This is legal, although few CASE tools support it. It is helpful in publishing, where width is constrained.