Suppose I want to use the Decorator pattern to add functionality to the java.lang.String class. (Just for example, to add a toRussian() method.) String is a final class. Is the following the only way to do it?
class DecoratedString implements Serializable, CharSequence,
Comparable<DecoratedString>
{
private final String str;
public DecoratedString (String str) {
this.str = str;
}
public DecoratedString toRussian() {
...
}
public String toString() { return str; }
public int hashCode() { return str.hashCode(); }
public boolean equals(Object obj) { /* don't forget this one */ }
public char charAt(int index) { return str.charAt(index);}
public int codePointAt(int index) { return str.codePointAt(index);}
... and so on for 30 or so more methods of String ...
}
Usage:
String greeting = new DecoratedString("Hello, world!").toRussian().toString();
Postscript:开发者_StackOverflow社区 This is so EASY to do in Objective-C with "Categories". Python now has @Decorators. And of course it's trivial in JavaScript, where you routinely add trim() to the String prototype. Is it totally impossible in Java?
Postpostscript: OK, toRussian() is a bad example. How would you add trim(), if String didn't already have trim()? trim() is an example of something every String should have.
The decorator pattern usually works by extending the original class with added functionality.
Since the String
class is final, it cannot be extended.
The downside to using composition rather than inheritance as you are doing, is that typically a decorator is implemented in such a way that anywhere you can use an X, you can use a DecoratedX. (The pattern should in fact allow you to decorate an X with any number of decorators and still use it as an X.) You would not be able to do that with your current design, and would end up re-implementing any of the extended String functionality you need.
A different design pattern is probably in order.
I'd have a Translator interface and pass an (immutable) String into it. Different implementations for different languages.
Why would you embed all that Russian specific logic into a decorated String?
Isn't this sort of translation the entire point behind Java's ResourceBundle?
精彩评论