Reputation: 4849
Consider the code below. Through A::doit()
, a B
object is supposed to increase total by 3. A Decorated1
object is supposed to increase total by 4,
and a Decorated2
object is supposed to increase total by 5. An A
object that is a combination of these derived types shall still carry out their "special actions" but is to increase total by the max (not sum) of the individual increases in total. But the decorator pattern is obtaining the sum instead of the max. Do I have to abandon the Decorator Pattern here?
#include <iostream>
int total = 0;
struct A {
public:
virtual void doIt() = 0;
};
struct Decorator : public A {
A* a;
Decorator (A* a_) : a(a_) {}
virtual void doIt() override {a->doIt();}
};
struct B : public A {
virtual void doIt() override {
total += 3;
std::cout << "Special actions by B carried out.\n";
}
};
struct Decorated1 : public Decorator {
using Decorator::Decorator;
virtual void doIt() override {
Decorator::doIt();
total += 4;
std::cout << "Special actions by Decorated1 carried out.\n";
}
};
struct Decorated2 : public Decorator {
using Decorator::Decorator;
virtual void doIt() override {
Decorator::doIt();
total += 5;
std::cout << "Special actions by Decorated2 carried out.\n";
}
};
int main() {
A* decorated1_2 = new Decorated2(new Decorated1(new B));
decorated1_2->doIt();
std::cout << "total = " << total << std::endl;
}
Output:
Special actions by B carried out. // Good I want this.
Special actions by Decorated1 carried out. // Good I want this.
Special actions by Decorated2 carried out. // Good I want this.
total = 12 // No, it is supposed to be 5, not the sum 3+4+5.
Upvotes: 4
Views: 170
Reputation: 9770
You'll need to split the functionality of doIt
up. You can't apply an increment in the function and do something special and not have both operations happen.
There's two ways you could accomplish this. Both require you to isolate the increment to its own method.
Upvotes: 2
Reputation: 2435
Decorator pattern is a class of structural pattern, i.e structural patterns help you to add and build functionality to the current features
That's the reason you are getting the sum of all the decorators as 12 (B feature<<3>> + Decorated1 feature<<4>> + Decorated2 feature<<5>> ).
If you want to keep working on structural pattern and if you want to yield the expected results, you have to initialize and send object of class A to all the decorator classes separately..
Else, you can work on Strategy Design Pattern and get the same results..
One more good option would be to use Creational design patterns
You can check these examples about design patterns with java code over here.. https://github.com/pavansn/java-design-patterns
Hope it helps
Upvotes: 3