4

我的目的不是就 DDD 中的验证、代码所属的位置等进行辩论,而是专注于一种可能的方法以及如何解决本地化问题。我在我的一个域对象(实体)上具有以下行为(方法),它举例说明了这种情况:

public void ClockIn()
{
    if (WasTerminated)
    {
        throw new InvalidOperationException("Cannot clock-in a terminated employee.");
    }

    ClockedInAt = DateTime.Now;
    :
}

可以看到,当调用 ClockIn 方法时,该方法会检查对象的状态以确保 Employee 没有被终止。如果 Employee 被终止,我们会抛出一个与“不要让你的实体进入无效状态”方法一致的异常。

我的问题是我需要本地化异常消息。这通常使用应用程序服务 (ILocalizationService) 完成(在此应用程序中),该应用程序服务是使用 MEF 在需要访问其方法的类中导入的。但是,与任何 DI 框架一样,只有在容器实例化对象时才会注入/导入依赖项。DDD 通常不是这种情况。

此外,我所了解的有关 DDD 的所有内容都表明我们的域对象不应该有依赖关系,并且这些问题应该在域对象的外部处理。如果是这种情况,我该如何本地化如上图所示的消息?

这不是一个新要求,因为许多业务应用程序都需要全球化/本地化。我会很感激一些建议如何使这项工作仍然与 DDD 的目标保持一致。

更新

我最初没有指出我们的本地化都是数据库驱动的,所以我们确实有一个本地化服务(通过可注入的 ILocalizationService 接口)。因此,使用 Visual Studio 作为项目一部分提供的静态资源类不是一个可行的选择。

另一个更新

也许它会推动讨论,说明该应用程序是一个 RESTful 服务应用程序。因此,客户端可以是一个简单的网络浏览器。因此,我不能期望调用者可以执行任何类型的本地化、代码映射等进行编码。当发生异常时(在这种方法中,尝试将域对象置于无效状态是异常),抛出异常并返回相应的 HTTP 状态代码以及异常消息,该异常消息应本地化为调用者的文化(接受语言)。

4

4 回答 4

2

不确定此响应对您有多大帮助,但本地化确实是前端问题。根据您的示例本地化异常消息不是常见的做法,因为最终用户不应该看到技术细节,例如异常消息中描述的那些(并且任何将对您的异常进行故障排除的人可能具有足够的英语水平,即使它不是他们的母语)。

当然,如有必要,您始终可以处理异常并在前端向您的用户提供本地化、用户友好的消息。但是将其作为前端关注点应该会简化您的架构。

于 2012-04-13T16:26:54.617 回答
1

正如 Clafou 所说,您不应该使用异常以任何方式将消息传递给 UI。

如果您仍然坚持这样做,一种选择是抛出错误代码而不是消息

throw new InvalidOperationException("ERROR_TERMINATED_EMPLOYEE_CLOCKIN");

然后,当它发生时,对异常做任何你需要做的事情(日志、查找本地化等等)。

于 2012-04-13T18:19:09.330 回答
0

您尝试避免向域模型对象添加内部依赖项是正确的。

更好的解决方案是处理服务方法内部的操作,例如:

public class EmployeeServiceImpl implements EmployeeService {

   public void ClockEmployeeIn(Employee employee) throws InvalidOperationException {
      if (employee.isTerminated()) {
          // Localize using a resource lookup code..
          throw new InvalidOperationException("Error_Clockin_Employee_Terminated");      
      }       
      employee.setClockedInAt(DateTime.Now);
   }
}

然后,您可以使用 DI 框架在您将进行时钟调用的地方注入服务,并使用该服务将您的域对象与业务逻辑的更改隔离开来。

于 2014-08-29T03:53:04.393 回答
0

如果本地化是域/应用程序的重要组成部分,您应该将其设为一等公民并在它所属的任何地方注入。我不确定“DDD 说我们的域对象不应该有依赖项”是什么意思 - 请解释一下。

于 2012-04-13T00:38:01.527 回答