Sto lavorando all'internazionalizzazione dei dati immessi dall'utente in un client/server piuttosto grande (l'HTTP (Hessian) è usato per la comunicazione) un'applicazione che è memorizzata in un database. Gli utenti possono scegliere la lingua che vogliono vedere e c'è una lingua predefinita che viene utilizzata quando non è presente una traduzione nella lingua richiesta.È OK utilizzare ThreadLocal per memorizzare le impostazioni internazionali richieste?
Attualmente una classe di dati può apparire come segue:
class MyDataClass {
private Long id;
private String someText;
/* getters and setters */
}
Dopo internazionalizzazione che potrebbe assomigliare a questo:
class MyDataClass {
private Long id;
private Set<LocalizedStrings> localizedStrings;
/* getters and setters */
}
class LocalizedStrings {
private Locale locale;
private String someText;
/* getters and setters */
}
Naturalmente può essere interessante per creare un getter delegato in MyDataClass che prende cura di ottenere il testo nella locale corretta:
public String getSomeText(Locale locale) {
for(LocalizedString localized : localizedStrings) {
if (localized.getLocale().equals(locale)) {
return localized.getSomeText();
}
}
}
Nella mia squadra c'erano alcuni dubbi riguardo alla necessità di passare le impostazioni locali per tutto il tempo fino a quando non raggiungono la classe dati. Dal momento che tutta questa roba avviene sul server e ogni richiesta al server viene gestita in un thread dedicato, alcune persone hanno suggerito di memorizzare le impostazioni internazionali richieste in un oggetto ThreadLocal e creare un retrocompatibile senza argomenti getter:
public String getSomeText() {
return getSomeText(myThreadLocalLocale.get());
}
Il ThreadLocal deve quindi essere una variabile globale (statica da qualche parte) o deve essere iniettata in MyDataClass su ogni singola creazione di istanza (stiamo usando molla, quindi potremmo iniettarla se rendiamo gestite le nostre classi di dati (cosa che non va me)).
L'utilizzo di un ThreadLocal per le impostazioni internazionali mi sembra in qualche modo sbagliato. Posso vagamente affermare che non mi piace la magia invisibile nel getter e la dipendenza da una variabile globale (in una classe di dati!). Tuttavia, avere un "brutto presentimento" a riguardo non è un buon modo per discutere con i miei colleghi a riguardo. Per aiutare ho bisogno di una risposta con uno dei seguenti:
- Dimmi che la mia sensazione fa schifo e la soluzione è grande per ragioni X, Y e Z.
- darmi alcune buone argomentazioni citabili che posso utilizzare per discutere con i miei colleghi e dirmi come farlo meglio (passare sempre locale o altra idea?)
Perché usi un Set per 'localizedStrings' e non una Mappa? –
Avete considerato l'utilizzo di Spring [LocaleContextHolder] (http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/i18n/LocaleContextHolder.html). Le molle possiedono il modo di memorizzare le impostazioni locali correnti (memorizzate da DispatcherServlet) per un thread. – sbk
Se l'ambito della variabile di localizzazione è un singolo thread, questa sembra una soluzione intelligente (e semplice). Se ti stai avventurando in più thread, ovviamente, questo richiede qualcosa in più. Se la tua API ha informazioni di localizzazione in ogni richiesta, allora è una soluzione completamente valida. BACIO, questo è il miglior argomento che puoi fare. –