2.9 Finishing Touches
Now that our refactoring is complete, we can make one more finishing touch. In the PolicyChangeNotification aspect, we can turn the declare warning statement into a declare error.
declare error : notifyingListeners() && !within(PolicyChangeNotification) : "Only the PolicyChangeNotification aspect should be notifying listeners";
Now if anyone inadvertently breaks the modularity we just put in place, he or she will receive a compilation error.
Finally we are now ready to go ahead and add the PetPolicyImpl class we need for the new pet insurance business linethe change that started us off down this road in the first place. Pet policies have attributes such as petName, petType, vetName, and vetAddress. Figure 2.45 shows the PetPolicyImpl class in the editor.
Figure 2.45 Adding in the PetPolicyImpl class.
Notice that all the methods that update the state of the PetPolicyImpl class are being advised by the PolicyChangeNotification aspect. The aspect continues to correctly notify changes even in code added to the system after the aspect was written. This is the power of capturing the design for change notification in the code (whenever the state of a policy changes), rather than coding by hand the implications of the design (putting calls to notifyListeners throughout the policy hierarchy).
If the PetPolicyImpl programmer somehow manages to miss the advice markers in the editor gutter and the "advised by" relationships in the Outline view, and starts to implement change notification the old way, the PolicyChangeNotification aspect soon tells him or her (see Figure 2.46).
Figure 2.46 Catching a violation of the change notification design.