应该是DDD中域的本地化部分

时间:2013-04-04 23:21:43

标签: java design-patterns localization domain-driven-design

在遵循DDD概念的同时,我正在努力做出决定,是否应该让我的域名本地化能够识别?我带来了两个解决方案,如何解决这个问题。两者都可以在不同的地方识别域本地化。我是否应该将本地化文本放入域?分享您的解决方案以解决此问题或我的两个示例的优缺点。感谢。

  

示例1

class Persion {

  String name;

  // other fields ommited

  void rename(String newName) {
    String oldName = this.name;
    this.name = newName

    // publish event with old name and new name
  }

  String name() {
    return name;
  }
}

class PersionRepository {

  void store(Persion persion) {
    Locale loc = LocaleContextHolder.get().getLocale();

    // store object to DAO - create/update fields for context locale
  }

  // other methods ommited
}
  

示例2

class Persion {

  Map<Locale, String> name;

  // other fields ommited

  void rename(String newName) {
    Locale locale = LocaleContextHolder.get().getLocale();
    String oldName = this.name.put(locale, newName);

    // publish event with old name and new name
  }

  String name() {
    Locale locale = LocaleContextHolder.get().getLocale();
    return this.name.get(locale);
  }
}

class PersionRepository {

  void store(Persion persion) {
    // store object to DAO - create/update fields for all locales
  }

  // other methods ommited
}

2 个答案:

答案 0 :(得分:3)

在大多数情况下,最好的选择是从域中删除本地化。

域类应该只包含与其不变量相关的数据,因为它们负责业务规则。要检索本地化描述,请使用投影DTO和应用服务。

您可以使用以下内容:

public final class VatCode {
    private final String _code;
    public VatCode(String code)
    {
        // VAT code validation here...
        _code = code;
    }

    @Override
    public String toString() {
        return _code;
    }

    @Override
    public boolean equals(Object obj) {
        // ...
    }

    @Override
    public int hashCode() {
        // ...
    }
}

public class Person {
    private final VatCode _identifier;

    public Person(VatCode identifier)
    {
        _identifier = identifier;
    }

    // some command and some query here...
}

public class PersonDTO {
    private final String _vatCode;
    private final String _personalDescription;

    public PersonDTO(String _vatCode, String _personalDescription) {
        this._vatCode = _vatCode;
        this._personalDescription = _personalDescription;
    }
    // other fields here...

    public String getVatCode()
    {
        return _vatCode;
    }

    public String getPersonalDescription()
    {
        return _personalDescription;
    }

    // some more getter here
}

public interface LocalizedPersonalInformationService {
    PersonDTO getInformationOf(VatCode person, Locale localization) throws ProperExceptionList;
}

那是:

  • 类似于VatCode valueobject(覆盖equals,hashCode和toString)以识别Person实体
  • Person实体,持有确保商业不变量所需的最少数据量并公开一组command and queries
  • 一个带有有用描述的PersonDTO(有些人称之为read-model
  • LocalizedPersonalInformationService能够提供PersonDTO s。
  • 和(显然)所有needed exceptions ...: - )

答案 1 :(得分:1)

如果可能的话,将所有本地化放在UI层中。有时人们发现很难做到。例如,我参与了一个项目,其中业务逻辑将抛出异常,并且该异常将在UI中显示。要本地化异常,我们必须执行以下操作(为简洁起见省略了详细信息,我们还必须有LocalizedRuntimeExceptionLocalizedException):

//====ArbitraryBusinessLogic.java====

if(badThing) {
  throw new SubclassOfLocalizedException(LocalizedStrings.ERROR_FOO,param1,param2);
}

//====LocalizedException.java====

public class LocalizedException extends Exception {

  private LocalizationKey localizationKey;
  Object [] params;

  public LocalizedException(LocalizationKey localizationKey, Object ... params) {
    super();
    localizationKey = localizationKey
    params = params;
  }

  public String getLocalizedMessage(Locale locale) {
    //message would be something like "The %s foo'd the %s"
    //or of course "le %s foo'd le %s" (FYI: I don't speak French)
    String message = getLocalizedMessageForKey(localizationKey);
    return String.format(locale,message,params);
  }

  public String getLocalizedMessage() {
    return getLocalizedMessage(getDefaultLocale());
  }

  public String getMessage() {
    return getLocalizedMessage();
  }

}