Phi*_*ipp 11 java internationalization
在Java中进行国际化时,为每条消息分配一个字符串键.什么是最佳实践,在哪里放置这些字符串键.目标是允许简单的重构(例如,密钥名称更改),清晰可读的代码,关注点的分离,但即使从代码的不同部分调用,仍然没有重复的密钥/消息.
//bad way, strings directly in code
messages.getString("hello_key");
Run Code Online (Sandbox Code Playgroud)
-
// better way, use String constants
public static final String HELLO_KEY = "hello_key";
...
messages.getString(HELLO_KEY);
Run Code Online (Sandbox Code Playgroud)
-
// other (better?) way, put all keys in one huge central class
public class AllMessageKeys {
public static final String HELLO_KEY = "hello_key";
...
}
public class Foo {
...
messages.getString(AllMessageKeys.HELLO_KEY);
}
Run Code Online (Sandbox Code Playgroud)
-
// other (better?) way, put all keys in neighbor class
public class FooMessageKeys {
public static final String HELLO_KEY = "hello_key";
}
public class Foo {
...
messages.getString(FooMessageKeys.HELLO_KEY);
}
Run Code Online (Sandbox Code Playgroud)
还有其他建议吗?哪个最好?我在Eclipse IDE上,如果这使得重构部分更清晰.
澄清:在上面的示例中,"messages"的类型为ResourceBundle.
基本上,似乎我们都同意需要某种常数.说到常量,我更喜欢Enums.Java Enum功能非常强大,并且未得到充分利用:
String title = Messages.getString(RunDialogMessages.TITLE);
Run Code Online (Sandbox Code Playgroud)
好的,但我必须做些什么才能让它看起来像这样?简单的界面,枚举和对标准消息访问例程的轻微修改.让我们从界面开始:
public interface MessageKeyProvider {
String getKey();
}
Run Code Online (Sandbox Code Playgroud)
枚举:
public enum RunDialogMessages implements MessageKeyProvider {
TITLE("RunDialog.Title"),
PROMPT("RunDialog.Prompt.Label"),
RUN("RunDialog.Run.Button"),
CANCEL("RunDialog.Cancel.Button");
private RunDialogMessages(String key) {
this.key = key;
}
private String key;
@Override
public String getKey() {
return key;
}
}
Run Code Online (Sandbox Code Playgroud)
并修改getString()方法:
public static String getString(MessageKeyProvider provider) {
String key = provider.getKey();
try {
return RESOURCE_BUNDLE.getString(key);
} catch (MissingResourceException e) {
return '!' + key + '!';
}
}
Run Code Online (Sandbox Code Playgroud)
只是为了完成图片,让我们看一下RunDialog.properties(我会尽快说明一下):
RunDialog.Title=Run
RunDialog.Prompt.Label=Enter the name of the program to run:
RunDialog.Run.Button=Run
RunDialog.Cancel.Button=Cancel
Run Code Online (Sandbox Code Playgroud)
显然,您可以使用Enum从属性文件中读取(通过嵌入ResourceBundle),但它可能违反单一责任原则(以及不要重复自己,因为访问代码需要重复).
回到属性文件,我有一种感觉(我可能在这里错了),你的目标之一是避免重复翻译.这就是为什么我在上面的例子中放两个运行.你看,这个词会根据上下文以不同的方式翻译(实际上很常见).在这个例子中,如果我要将其翻译为波兰语,它将如下所示:
RunDialog.Title=Uruchamianie
RunDialog.Prompt.Label=Wpisz nazw? programu do uruchomienia:
RunDialog.Run.Button=Uruchom
RunDialog.Cancel.Button=Anuluj
Run Code Online (Sandbox Code Playgroud)
这是一个有着共轭概念的奇怪语言的不幸问题......
我总是使用列出我的密钥的界面来处理此类内容。Interace 的名称主要是 DESC=Issue/short description/topic 和键值。通过这种方式,您可以制作一些漂亮的界面和一些通用界面,例如用于确定或中止键的界面。
// other (better?) way, put all keys in neighbor class
public interface DESCMessage {
public static final String HELLO_KEY = "hello_key";
}
public class Foo {
...
messages.getString(DESCMessage.HELLO_KEY);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4637 次 |
| 最近记录: |