The decorator pattern is a nifty way of adding behaviour to existing objects. Let’s say you have a class that is responsible for sending messages over the network.
class NetworkMessage implements MessageSender {
public send(Message message) {
//things occur
}
};
Later, there comes a requirement where you want start making a copy of messages going over the network but you don’t want to change any existing behaviour. So you write a decorator to do the work.
class MessageCopier implement MessageSender
private MessageSender messageSender;
public MessageCopier(MessageSender messageSender) {
this.messageSender = messageSender;
}
public send(Message message) {
storeMessageSomewhereSafe(message);
messageSender.send(message);
}
private storeMessageSomewhereSafe(Message message) {
//other things occur
}
}
Now, because we’re in Java and the factory pattern is prolific. Your factory just needs to new up a MessageCopier
passing in the instance of the MessageSender
. Behaviour extended.
public MessageSender build() {
return new MessageCopier(new NetworkMessage());
};
One thing you may note is that the implementation of MessageCopier
is quite thin. It only has a new bit of behaviour in it. Everything that isn’t relevant is elsewhere; a separation of concerns. As the consumers of the MessageSender
interface get their implementations from a factory you can now add in new behaviour incrementally with minimal rework. As the behaviour is constrained you can test behaviour in isolation, more easily.
That was this month’s pattern fun fact. Do you have a pattern fun fact you would like to share? Send it to us at p2@thoughtworks.com and we’ll publish it.