A software design often has aspects that apply across several classes, functions, or methods. We might have a concern, such as logging, auditing, or security, that must be implemented consistently. One general method for reuse of functionality in object-oriented programming is inheritance through a class hierarchy. However, inheritance doesn't always work out well. For example, one aspect of a software design could be orthogonal to the class hierarchy. These are sometimes called cross-cutting concerns. They cut across the classes, making design more complex.
A decorator provides a way to define functionality that's not bound to the inheritance hierarchy. We can use decorators to design an aspect of our application and then apply the decorators across classes, methods, or functions.
Additionally, we can use multiple inheritances...