Using the decorator pattern to add logic to an interface without altering its existing behaviour
Suppose you have an interface that is used across different classes. You want to add some behaviour to that interface when it is used in a class and keep the behaviour unchanged for the other classes. The decorator pattern could come in handy.
In this particular scenario I want to add functionality to the Question#ask() method so that an event is emitted. The event should only be emitted when the last question is asked, however I want to keep the behaviour unchanged in other instances. This means I cannot directly edit the Question implementation. The decorator pattern is one possible solution, so where to start?
First I am creating an abstract class named QuestionDecorator that implements the Question interface. The constructor takes in a question and the class implements the ask method from the Question interface. The implementation consists in invoking the original behaviour from the question object, then invoking the abstract method named decorate. The idea from now on is that I can extend the QuestionDecorator and add the personalised decoration logic in the child class. Additionally I am keeping the question field has protected to allow accessibility by child classes.
My next step is implementing the FinalQuestionDecorator class:
The FinalQuestionDecorator class responsibility is simply to add the decorated behaviour. In this particular case it will emit an event with that question. So when a question is an instance of a FinalQuestionDecorator class, by invoking the ask method I will be triggering the decorated behaviour.
All is left do to is to use the decorated class when required:
Suppose the last question is identified as the last Question object in the questions list, then the QuestionPool#getQuestion(int index) method is updated so that the last question in the list is decorated with the FinalQuestionDecorator class.