|
The Legacy Class
For starters, let me introduce the reuse candidate: a legacy class called Visa, which implements no interfaces or abstract classes, and exposes the following methods: setOwnerName (the owner of the Visa card), setCCNumber (the card number), setExpirationDate (the expiration date), charge (charges the credit card), and credit (credits money back to the credit card). The Visa class is shown in Figure 1.
Though a simplified example, a similar class should exist in most e-commerce architectures. Perhaps for the original business model, charging only a Visa card was a sufficient set of functionality, so the developers coded directly to the exact use case in all handler code (all other application code that references Visa), without much thought given to future extensibility. By addressing the specific use case, rather than an abstracted generalization of it, the chance that code can be reused without additional structural changes in the future is greatly reduced.
An Extensibility Request
Suppose a request is received to extend the application to allow charging to Master Card and American Express cards. In surveying the landscape, it is apparent that a little foresight in the original design could have made this task much easier. The most extensible applications are built on the foundation of interfaces (and/or abstract classes), and handler code utilizes the technique of polymorphism in manipulating the interface or abstract class, rather than offering code that handles each potential implementation.
Polymorphism is the ability of a class or subclass to be used in the same manner as the interface it implements or the same manner as its superclass, respectively. In this way, the handler code never has to be changed to add new implementations of the interface or abstract classand this is what the original developers in this example failed to take into account. Quite often, it is assumed that the high price of changing a class lies in the class itself. The changes to the class in question will always be finite, and though in reality the changes to the handler code will be some countable number, in theory, the potential changes to this handler code are infinite.
If the changes needed to extend code are contained within the class in question, rather than propagated to the handling code around it, then the design is properly abstracted to easily allow changes. The current design, coded directly against the Visa class, is not. Let's alter the original design to provide a greater level of abstraction while enhancing the ability to reuse code.
|