The Decorator pattern allows you to dynamically add new behaviors to objects at runtime without altering their original class. It achieves this by wrapping existing objects in a new “decorator” object. Decorators share the same interface as the objects they wrap, enabling seamless integration and composition of functionalities.
Too bookish ??
Lets say you have a camera class, which is doing capture, Now you want to add some new features like Bookeh Mode, Night Mode, Portrait so on.
1 way is to modify the same class, capture method, to provide new functionality. Too Risky ??
May be add some composition inside the same class, but again will be modify the existing class, violating open/close.
Let’s explore what decorator pattern says :
We create a BaseDecorator class, which keeps track of original Camera object, this BaseDecorator will implement the same interface as of camera, so in a sense BaseDecorator is type of Camera.
Now we can create the type of decorator we want may be create a NightModeDecorator, BookehModeDecorator, PortraitDecorator.
It will form a chain of the objects.
You create a baseDecorator object (it contains a camera instance)
create NightModeDecorator, its cons take baseDec obj .
create BookehMode -> pass NightModeDecorator.
You see this chain, overall you have multiple objects now,
BookehMode (having NightMode)
NightMode (having basedecoratr)
Bookeh’ capture calls -> night modes’ capture -> so on..
class Icamera {
public:
virtual ~Icamera() = default;
virtual void capture() = 0;
};
class CameraBaseDecorator : public Icamera {
protected:
shared_ptr<Icamera> camera;
public:
CameraBaseDecorator(shared_ptr<Icamera> cam) : camera(cam) {
}
CameraBaseDecorator() {
}
void capture () {
cout <<" capture from base decorator" <<endl;
// do actual capture..
}
};
class CameraNightModeDecorator : public CameraBaseDecorator {
public:
CameraNightModeDecorator(shared_ptr<Icamera> cam) : CameraBaseDecorator(cam) {
}
void capture () {
cout <<" capture from CameraNightModeDecorator" <<endl;
camera->capture();
// apply processing once capture is done...
}
};
class CameraBookehModeDecorator : public CameraBaseDecorator {
public:
CameraBookehModeDecorator(shared_ptr<Icamera> cam) : CameraBaseDecorator(cam) {
}
void capture () {
cout <<" capture from CameraBookehModeDecorator" <<endl;
camera->capture();
// apply processing once capture is done...
}
};
int main() {
auto cam = make_shared<CameraBaseDecorator>(nullptr);
cam = make_shared<CameraBookehModeDecorator>(cam);
cam = make_shared<CameraNightModeDecorator>(cam);
cam->capture();
}
Follow more posts @ https://jdecodes.wordpress.com
My all design pattern articles :
- https://jdecodes.wordpress.com/2024/07/13/builder-design-pattern/
- https://jdecodes.wordpress.com/2024/07/13/command-design-pattern/
- https://jdecodes.wordpress.com/2024/07/13/iterator-design-pattern/
- https://jdecodes.wordpress.com/2024/07/13/mediator-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/state-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/memento-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/observer-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/strategy-pattern/
- https://jdecodes.wordpress.com/2024/07/20/visitor-design-pattern/
- https://jdecodes.wordpress.com/2024/07/20/adapter-desing-pattern/
- https://jdecodes.wordpress.com/2024/07/20/bridge-design-pattern/
- https://jdecodes.wordpress.com/2024/07/22/composite-desing-pattern/
- https://jdecodes.wordpress.com/2024/07/22/facade-design-pattern/
- https://jdecodes.wordpress.com/2024/07/22/decorater-design-pattern/
Leave a comment