3

在遵循 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
}
4

2 回答 2

4

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

域类应该只包含与其不变量相关的数据,因为它们负责业务规则。要检索本地化描述,请使用投影 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;
}

那是:

  • 类似于VatCodevalueobject(覆盖 equals、hashCode 和 toString)来识别Person实体
  • 一个实体,持有确保业务不变性Person所需的最少数据量并公开一组命令和查询
  • aPersonDTO带有有用的描述(有些人称之为read-model
  • aLocalizedPersonalInformationService能够提供PersonDTOs。
  • 和(显然)所有需要的 例外...... :-)
于 2013-04-05T08:17:23.483 回答
2

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

//====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();
  }

}
于 2013-04-05T01:49:29.897 回答