我经常需要在演示器和视图中使用客户端包和一些i18n-ed消息。
我想知道哪一个是最好的方式来获得它们:注射或单例?
解决方案1:到目前为止,我使用Singleton来获取消息:
public interface MyMessages extends Messages{
String key1();
String key2();
...
class Instance {
private static MyMessages instance = null;
public static MyMessages getInstance() {
if (instance == null) {
instance = GWT.create(MyMessages.class);
}
return instance;
}
}
}
FooView.java:
MyMessages.Instance.getInstance().key1();
解决方案2:像这样注射会更好吗?
private MyMessages i18n;
@Inject
public FooView(MyMessages i18n){
this.i18n=i18n;
}
第二个解决方案对我来说似乎更干净,但当我需要使用一些i18n字符串的非空构造函数时,我有时会陷入困境:
@Inject
private MyMessages i18n;
public Bar(Foo foo){
/*
* do something which absolutely requires i18n here.
* The problem is that injectable attributes are called
* after the constructor so i18n is null here.
*/
foobar();
}
首先,客户端包和I18N消息虽然本身不是单例,但它们与所有实例共享它们的状态,因此一旦编译成JavaScript并由编译器优化,它们就好像是单例一样。有一些特殊情况(IIRC,当使用I18N接口的WithLookup
变体时),但一般来说,它不会给你任何东西,显式地将它们视为单例。
所以问题基本上变成是显式使用GWT.create()
还是注入实例。我想说这是一个品味问题,但从技术上讲,GWT.create()
与非GWTTestCase
单元测试不能很好地发挥作用。
最后,至于你最近的问题,我想通过"非空构造函数"你的意思是它需要的值不是依赖关系(即值对象);在这种情况下,您可能应该使用辅助注入,而不是自己构造对象然后注入其成员(顺便说一句:那么您如何注入成员呢?)