Use Cases For The Decorator Pattern
Let's explore some real-world scenarios where the Decorator pattern could be a good fit
Graphic User Interfaces (GUIs)
GUI toolkits often make use of the Decorator pattern. For instance, a window in a GUI could be decorated with borders, scrollbars, or other graphical elements. Each decorator would add its own functionality without modifying the window's core behavior. This makes the design more flexible and allows for dynamic customization of the GUI.
In this class diagram:
Window <|.. BaseWindow : implementsandWindow <|.. WindowDecorator : implementsdenote that bothBaseWindowandWindowDecoratorimplement theWindowinterface.WindowDecorator <|-- BorderDecorator : extends,WindowDecorator <|-- ScrollbarDecorator : extendsandWindowDecorator <|-- TitleBarDecorator : extendsshow thatBorderDecorator,ScrollbarDecorator, andTitleBarDecoratorextend theWindowDecorator.WindowDecorator o-- Window : - has arepresents thatWindowDecoratorhas a reference to aWindowobject (composition).- The
class Window,class BaseWindow,class WindowDecorator,class BorderDecorator,class ScrollbarDecorator, andclass TitleBarDecoratorblocks define the classes and interfaces with their methods. The<<interface>>tag indicates thatWindowis an interface. - The
+and-before the method and attribute names represent public and private access modifiers, respectively.
Middleware in Web Frameworks
The Decorator pattern is often used in web development frameworks to provide middleware services. Middleware functions are functions that have access to the request and response objects, and the next middleware function in the application's request-response cycle. They can be used to perform actions like authentication, logging, error handling, etc. For instance, in Express.js (a popular Node.js framework), middleware functions can be thought of as decorators that add functionality to the HTTP request/response process.
Below is an abstracted class diagram demonstrating the Decorator pattern
in the context of a web framework, where we have a RequestHandler that can be
decorated with different middleware
like AuthenticationMiddleware, LoggingMiddleware,
or ErrorHandlingMiddleware:
In this class diagram:
RequestHandler <|.. BaseRequestHandler : implementsandRequestHandler <|.. MiddlewareDecorator : implementsdenote that bothBaseRequestHandlerandMiddlewareDecoratorimplement theRequestHandlerinterface.MiddlewareDecorator <|-- AuthenticationMiddleware : extends,MiddlewareDecorator <|-- LoggingMiddleware : extends, andMiddlewareDecorator <|-- ErrorHandlingMiddleware : extendsshow thatAuthenticationMiddleware,LoggingMiddleware, andErrorHandlingMiddlewareextend theMiddlewareDecorator.MiddlewareDecorator o-- RequestHandler : - has arepresents thatMiddlewareDecoratorhas a reference to aRequestHandlerobject ( composition).- The
class RequestHandler,class BaseRequestHandler,class MiddlewareDecorator,class AuthenticationMiddleware,class LoggingMiddleware, andclass ErrorHandlingMiddlewareblocks define the classes and interfaces with their methods. The<<interface>>tag indicates thatRequestHandleris an interface. - The
+and-before the method and attribute names represent public and private access modifiers, respectively.
Access Control or User Permissions
You can use decorators to control
access permissions for a user. For example, you might have a User object,
and you want to add different levels of access control such
as AdminUser, ReadOnlyUser, etc. Instead of modifying the User class
directly or using inheritance which could become unwieldy with many types of
users, you can use decorators to dynamically assign and remove these
permissions.
Here is a class diagram demonstrating the Decorator pattern for a User
object that can be decorated with different permissions
like AdminPermissions, ReadPermissions, or WritePermissions:
In this class diagram:
User <|.. BasicUser : implementsandUser <|.. PermissionDecorator : implementsdenote that bothBasicUserandPermissionDecoratorimplement theUserinterface.PermissionDecorator <|-- AdminPermissionDecorator : extends,PermissionDecorator <|-- ReadPermissionDecorator : extends, andPermissionDecorator <|-- WritePermissionDecorator : extendsshow thatAdminPermissionDecorator,ReadPermissionDecorator, andWritePermissionDecoratorextend thePermissionDecorator.PermissionDecorator o-- User : - has arepresents thatPermissionDecoratorhas a reference to aUserobject (composition).- The
class User,class BasicUser,class PermissionDecorator,class AdminPermissionDecorator,class ReadPermissionDecorator, andclass WritePermissionDecoratorblocks define the classes and interfaces with their methods. The<<interface>>tag indicates thatUseris an interface. - The
+and-before the method and attribute names represent public and private access modifiers, respectively.
Each of these scenarios involves situations where you want to add functionality to objects dynamically and transparently, without affecting other objects. Decorators offer a flexible and maintainable way to do this.


Time To Transition From JavaScript To TypeScript
Level Up Your TypeScript And Object Oriented Programming Skills. The only complete TypeScript course on the marketplace you building TypeScript apps like a PRO.
SEE COURSE DETAILSWhat Can You Do Next 🙏😊
If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for software developers.