Украшение строки в Java - PullRequest
       5

Украшение строки в Java

0 голосов
/ 15 октября 2010

Предположим, я хочу использовать шаблон Decorator для добавления функциональности в класс java.lang.String. (Например, чтобы добавить метод toRussian ().) Строка - это последний класс. Является ли следующий способ сделать это единственно возможным?

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 ...
}

Использование:

String greeting = new DecoratedString("Hello, world!").toRussian().toString();

Постскриптум: Это так легко сделать в Objective-C с "категориями". У Python теперь есть @Decorators. И, конечно, это тривиально в JavaScript, где вы обычно добавляете trim () в прототип String. Это абсолютно невозможно в Java?

Postpostscript: ОК, toRussian () - плохой пример. Как бы вы добавили trim (), если бы в String еще не было trim ()? trim () является примером того, что должна иметь каждая строка.

Ответы [ 3 ]

4 голосов
/ 15 октября 2010

Шаблон декоратора обычно работает путем расширения исходного класса с добавленной функциональностью.

Поскольку класс String является окончательным, его нельзя расширять.

Недостатком использования композиции, а не наследования, как вы это делаете, является то, что обычно декоратор реализован таким образом, что везде, где вы можете использовать X, вы можете использовать DecoratedX.(Шаблон на самом деле должен позволять вам украшать X любым количеством декораторов и по-прежнему использовать его в качестве X.) Вы не сможете сделать это с вашим текущим дизайном, и в итоге вы будете повторно реализовывать любой из расширенныхНеобходимая вам функциональность строки.

Возможно, используется другой шаблон проектирования.

3 голосов
/ 15 октября 2010

Я бы имел интерфейс Translator и передавал (неизменяемый) String в него.Разные реализации для разных языков.

Зачем вам встраивать всю эту специфическую русскую логику в украшенную строку?

1 голос
/ 16 октября 2010

Разве этот вид перевода не весь смысл Java ResourceBundle ?

...