0

我经常需要客户端包和演示者和视图中的一些 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();
}
4

1 回答 1

3

首先,客户端包和 I18N 消息虽然本身不​​是单例,但与所有实例共享它们的状态,因此一旦编译为 JavaScript 并由编译器优化,就好像它们是单例一样。有一些极端情况(IIRC,当使用WithLookupI18N 接口的变体时),但一般来说,它不会给你任何明确地将它们视为单例的东西。

所以问题基本上变成了是GWT.create()显式使用还是注入实例。我会说这是一个品味问题,但从技术上讲,非单元测试GWT.create()也不能很好地发挥作用。GWTTestCase

最后,至于您的最新问题,我认为“非空构造函数”是指它采用非依赖项的值(即值对象);在这种情况下,您可能应该使用辅助注入而不是自己构建对象然后注入其成员(顺便说一句:那么您如何注入成员?)

于 2013-04-11T12:54:18.930 回答