Reputation: 75
Not sure if this is an ideal use of the Decorator pattern. Here's the setup.
I have a CommandBuilder class with an operation method called build(). I want to dynamically apply things to this command: write it to a file, write it to stdout, write it to a logfile.
It lays out like this:
public abstract class CommandBuilder {
public abstract String build();
}
Then I have a concrete impl with
public class StringBuilder extends CommandBuilder {
...
public String build() {
... builds command string ....
return commandString;
}
}
The abstract decorator:
public abstract class OutputDecorator extends CommandBuilder {
public abstract String build();
}
And finally, the decorators themselves:
public class FileDecorator extends OutputDecorator {
CommandBuilder builder;
public FileDecorator(CommandBuilder builder) {
this.builder = builder;
}
public String build() {
String commandOutput = builder.build(); // call it
...
someWriteClass.writeFile(commandOutput); // use it
return commandOutput; // pass it along unchanged;
}
}
And so on for StandardOutputDecorator, LoggerOutputDecorator...
Then in use:
CommandBuilder mybuilder = new LoggerOutputDecator(
new StandardOutputDecorator(
new FileDecorator(
new StringCommandBuilder()
)
)
);
mybuilder.build();
And thereby building my string command and outputing it in various ways.
QUESTION: Since I'm not modifying the operation data within these decorators, but just using the output to feed into other methods before passing it along unchanged, am I "misusing" the pattern? Is there a better way to implement this?
Upvotes: 2
Views: 653
Reputation: 234
First of all I suggest you to check out the Bridge design pattern. You should have a hierarchy for handling data (printing to File, Console, etc.), and another hierarchy for your data builders - they should be loosely coupled, as classes have to be coherent and crated because of one reason, as a best practice.
In addition, we use the Decorator pattern to extend the default behavior of classes. Your FileDecorator, LoggerOutputDecator classes have their own responsibilities, they do not extend the "decorated" object's default behavior.
I think you should have two different hierarchies as mentioned, but the hierarchy of data handlers should not be implemented in data way (do not use the Decorator pattern, because they do not decorate anything).
I think it would be cleaner to build data with a builder and iterate over handlers. Each handler should be called and the data built by the builder should be passed as a parameter.
Upvotes: 0
Reputation: 1270
It's perfectly appropriate, except that the OutputDecorator abstract class should deal with holding a reference to a CommandBuilder (as you do in FileDecorator, without sharing with other decorators)
Upvotes: 1