Я работаю над интернационализацией введенных пользователем данных в довольно большом клиенте/сервере (приложение HTTP (Hessian) используется для связи), которое хранится в базе данных. Пользователи могут выбирать язык, который они хотят видеть, и есть язык по умолчанию, который используется, когда перевода на запрошенный язык нет.Можно ли использовать ThreadLocal для хранения запрошенной локали?
В настоящее время класс данных может выглядеть следующим образом:
class MyDataClass {
private Long id;
private String someText;
/* getters and setters */
}
После интернационализации она может выглядеть следующим образом:
class MyDataClass {
private Long id;
private Set<LocalizedStrings> localizedStrings;
/* getters and setters */
}
class LocalizedStrings {
private Locale locale;
private String someText;
/* getters and setters */
}
Конечно, это может быть интересно для создания делегата геттер в MyDataClass, который принимает уход за текстом в правильном регионе:
public String getSomeText(Locale locale) {
for(LocalizedString localized : localizedStrings) {
if (localized.getLocale().equals(locale)) {
return localized.getSomeText();
}
}
}
В моей команде были некоторые проблемы, но о необходимости проходить локаль все время, пока они не достигнут класса данных. Так как все эти вещи происходят на сервере, и каждый запрос к серверу обрабатывается в специальной резьбе, некоторые люди предложили хранить запрашиваемую локаль в ThreadLocal объекта и создать обратный совместимый без аргументов поглотитель:
public String getSomeText() {
return getSomeText(myThreadLocalLocale.get());
}
Затем ThreadLocal должен быть глобальной переменной (статической где-то), или ее нужно вводить в MyDataClass при каждом создании экземпляра (мы используем Spring, поэтому мы можем вставлять его, если мы сделаем наши классы данных весной управляемыми (что неправильно меня)).
Использование ThreadLocal для локали меня как-то не так. Я могу смутно утверждать, что мне не нравится невидимая магия в getter и зависимость от глобальной переменной (в классе данных!). Тем не менее, наличие «плохого чувства» об этом на самом деле не является хорошим способом спорить с моими коллегами об этом. Для того, чтобы помочь мне нужен ответ с одним из следующих способов:
- Скажите мне, что мое чувство отстоя и решение отлично подходит для причин X, Y и Z.
- Дайте мне несколько хороших Quotable аргументов я могу использовать для спорить с моими коллегами и рассказывать мне, как это сделать лучше всего (просто всегда обходите локаль вокруг или любую другую идею?)
Почему вы используете набор для 'localizedStrings', а не карту? –
Считаете ли вы использование Spring [LocaleContextHolder] (http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/i18n/LocaleContextHolder.html). Его пружины имеют собственный способ хранения текущей локали (хранимой DispatcherServlet) для потока. – sbk
Если объем вашей переменной локализации - это один поток, это кажется интеллектуальным (и простым) решением. Если вы решитесь на несколько потоков, то, очевидно, это требует чего-то большего. Если ваш API имеет информацию о локализации в каждом запросе, то это полностью действующее решение. KISS, это лучший аргумент, который вы можете сделать. –