Decorator Pattern is a design pattern used for adding a feature to an object implementing an interface in an non intrusive way either statically or dynamically. In other words the decorator pattern can be used to extend (decorate) the functionality of a certain object statically, or in some cases at run-time, independently of other instances of the same class, provided the object creation is done using a decorator object.
The class diagram for a decorator pattern is shown below.
The class diagram for a decorator pattern is shown below.
More details on decorator pattern can be found at the following wiki link: Decorator Pattern.
The objective of this post is to map decorator pattern to a day to day scenario and illustrate the same with an example. Tracing or logging an object activity is one such example.
Lets say we define an interface robot_interface defining APIs like sit, run, walk etc. Then we define a concrete class robot implementing the robot_interface interface. Now let say we create two instances of robot class, for the first one we want a record/log all the activity he does but we don’t care about the second one, so what is the best possible way to implement this tracing/logging without altering the interface or concrete class? The answer is the Decorator Pattern.
So we will create a new class called robot_activity_tracer implementing the same(robot_interface) interface. We can also optionally define an robot_activity_tracer interface and implement it in a separate concrete class but that’s not important. In this example we will directly implement the robot_interface in tracer class. The tracer class will also accept a handle of robot_interface in its constructor. In the implementation of all the APIs, the decorator class will first trace the activity to a log file and then forward the call on the interface handle locally held. Thus all the activity will be traced without altering the actual concrete class or its interface. Simplified class diagram for this tracer is shown below.
At the time of usage create instance of concrete class, then create an instance of tracer class passing interface handle of the first object. Then assign the handle of decorator class to the pointer to the robot interface with which robots are going to be used. This way when we access robot1 then all its activity will be logged to a file.
The concept shown in the example can be generalized and applied to trace any object implementing an interface at its interface boundary.
Here is the source code for the example: decorator_tracing.cpp
No comments:
Post a Comment