我经常需要在演示者和视图中使用客户端捆绑和一些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();
}
答案 0 :(得分:3)
首先,客户端捆绑包和I18N消息虽然不是单独的,但它们与所有实例共享它们的状态,因此一旦编译成JavaScript并由编译器优化,就好像它们是单例一样。有一些角落情况(IIRC,当使用I18N接口的WithLookup
变体时),但一般来说它不会给你买任何明确将它们视为单身的东西。
所以问题基本上就是明确地使用GWT.create()
还是注入实例。我会说这是一个品味问题,但从技术角度来说,GWT.create()
与非GWTTestCase
单元测试不相称。
最后,关于你的最新问题,我认为通过“非null构造函数”,你的意思是它需要不依赖的值(即值对象);在这种情况下,你应该使用辅助注射,而不是自己构建对象,然后注入其成员(作为一个旁边:你如何注射成员呢?)