Software is filled with cross-cutting concerns, aspects that need to be implemented consistently, even if they're in separate class hierarchies. It's often a mistake to try and impose a class hierarchy around a cross-cutting concern. We've looked at a few examples, such as logging and auditing.
We can't reasonably demand that every class that might need to write to the log also be a subclass of some single Loggable superclass. It's much easier to design a Loggable mixin or a @loggable decorator. These don't interfere with the proper inheritance hierarchy that we need to design to make polymorphism work correctly.
Some important cross-cutting concerns revolve around security. Within a web application, there are two aspects to the security question as follows:
- Authentication: Do we know who's making the request?
- Authorization...