This notion is illustrated in the change scenario 2, which focuses on modifying
the HW layers to add new use cases. The activity to add constrained modules
(contracted classes and methods) is performed by one layer (concern) at a time. For
instance, there are situations where the view layer is under modification to adhere the
new constrained modules, but the DbC features (such as preconditions) are propagated
to other layers such as the business layer. More specifically, in the view layer
there is an interface called IFacade, but as a limitation of the OO decomposition,
we cannot add any precondition to this component, so we should propagate this
change to the modules a®ected (the classes which implement such interface) by such
interface. As a result, we have two classes implementing this interface: the RMIServletAdapter
in the same view layer and the HealthWatcherFacade class in the
business layer. This way, the attempt to add a precondition to a method of the
IFacade interface, results in changes in two components, one of them localized in
another unrelated layer (the business layer where the HealthWatcherFacade class is declared). In the same sense, while reasoning about the correctness of a method at
the RMIServletAdapter class, if we change a precondition in this class, we might
change the related precondition in the HealthWatcherFacade class as well. Thus,
these result in negative changes caused by OO ripple-e®ects. These negative changes
can be avoided in AO implementation since AspectJ-like languages can instrument
an interface and its hierarchy.