Recently I read about the decorator design pattern but I was left with some unanswered questions that I couldn't find online. I'm not going to show code because I don't want to make this question more complicated than it really is. I'll simply give an example:
Subway Store:
Component --> SubSandwich
ConcreteComponent --> 15cmSub, 30cmSub
Decorator --> Ingredients
ConcreteDecorator --> White Cheese, Yellow Cheese, Jam, Chicken.
This is just the way a Subway store works. Pick your core sandwhich size and then add all the toppings you like. But I still have some questions:
What if there is an invalid combination of ingredients? For example, Subway policy says that there can't be two kinds of cheeses in the same sub. Now let's imagine that there are 10000 possible combinations for the toppings and ONLY one is invalid. Does this completely break the decorator pattern?
What if two ingredients are dependant. For example, if you order lettuce THEN you need some other kind of vegetable to make a "valid" Sub.
When is it better to use the decorator pattern instead of a SubSandwich class with an ArrayList of Ingredient? I know here the Ingredients don't add behaviour, which makes the Subway example not accurate, but let's assume they do.
Why extending? Why not using interfaces?
The patterns in their original structure do not solve any practical problem. You need to mix them up with general SOLID principles. For the example problem, you can implement Builder pattern on top of the Decorators. And you will have some DSL type of code e.g.
Builder.aPizza().withCheeze(someCheeze).addTopping(someTopping).and(someOtherTopping).build();
Using this pattern/style you can validate the intermediate state of object or even at the final stage when you call build() method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With