Web services 以webservices DTO作为值对象的DDD:如何处理它们?

Web services 以webservices DTO作为值对象的DDD:如何处理它们?,web-services,model,domain-driven-design,dto,value-objects,Web Services,Model,Domain Driven Design,Dto,Value Objects,我有一个“MyUnits”应用程序,让我们管理单位(如米、千克、磅、英里、公里/小时……)。该模型是复杂的,它支持单元兼容性、操作、转换等 我有另一个应用程序(MyApp)需要使用“单位”,所以我想让它使用我的“单位”应用程序 我想的是有一个“单位”服务(webservice)UnitService,它使用并返回一个单位DTOUnitDTO 在MyApp中,我有以下型号: Operand value: float unit: UnitDTO OperationAdd op

我有一个“MyUnits”应用程序,让我们管理单位(如米、千克、磅、英里、公里/小时……)。该模型是复杂的,它支持单元兼容性、操作、转换等

我有另一个应用程序(MyApp)需要使用“单位”,所以我想让它使用我的“单位”应用程序

我想的是有一个“单位”服务(webservice)
UnitService
,它使用并返回一个单位DTO
UnitDTO

在MyApp中,我有以下型号:

Operand
    value: float
    unit: UnitDTO
OperationAdd
    operand1: Operand
    operand2: Operand
    execute()
问题:在
操作add.execute()
中,我需要检查单元是否兼容(例如)

因此,要么:

  • UnitDTO
    有一个方法将调用
    UnitService::areCompatible
    ,但这是错误的!DTO(应该只包含数据)如何知道UnitService是一个Web服务!不应该

  • OperationAdd.execute()
    调用
    UnitService::areCompatible
    ,但这是错误的!OperationAdd(一个实体)是如何知道UnitService这是一个Web服务的!不应该

  • 或者我有一个
    OperationService
    来做这项工作(并且可以调用服务)但是我的
    操作
    实体就像数据容器,没有方法的实体,这并不是DDD的真正意义

我不想要贫血的实体,但如果我有一个实体使用服务,我该怎么办

还有:我是否错误地认为UnitDTO可以用作VO?

一个单元应该“宣传”它的兼容性。我不知道您使用的语言是否支持泛型,但我会这样做

首先,UnitDto包含某个单元的状态。使用UniDto创建混凝土单元(顺便说一句,它是VO)。每个单元都应该知道它的兼容性。UnitDTO应该只是一个DTO,创建其他VO来完成这项工作

C#

公共类单元库
{
公共虚拟对象是可兼容的(UnitBase unit)
{
返回false;
}
}
公共接口i兼容
{
布尔可比(T单位);
}
公共类单位英尺{}
公共类单位计:单位基,ICompatible
{
布尔是可计算的(单位英尺单位){返回真;}
}
公共覆盖布尔值不兼容(单位基单位)
{
返回是可计算的((单位英尺)单位);
} 
编译器应该根据比较的单元选择正确的重载。此外,ICompatFile接口可以具有从一个单元到另一个单元的转换方法。但假设你想要更抽象的东西

public class OperandValue:ICompatbile<OperandValue>
{ 
     public decimal Value {get;set;}
     public UnitBase Unit {get;set;}
     public bool IsCompatbile(OperandValue other)
     {
        return Unit.IsCompatbile(other.Unit);
     }

     public static OperandValue FromDto(Operand data)
      {
         return new OperandValue(data.Value,UnitBase.FromDto(data.Unit));
       }
}

 OperandValue first=OperandValue.FromDto(operand1);
 OperandValue second=OperandValue.FromDto(operand2);

if (first.IsCompatbile(second)){
    OperationService.Add(first,second)
  }
公共类操作数值:ICompatFile
{ 
公共十进制值{get;set;}
公共单位基单位{get;set;}
公共学校可比性(其他)
{
返回单位:iCompatbile(其他单位);
}
来自DTO的公共静态操作数值(操作数数据)
{
返回新的操作数值(data.Value,UnitBase.FromDto(data.Unit));
}
}
第一个操作数值=操作数值.FromDto(操作数1);
第二个操作数值=操作数值.FromDto(操作数2);
如果(第一个是比较级(第二个)){
OperationService.Add(第一,第二)
}

所以,您不需要UnitService::AreCompatibile方法,只需要大量多态性和仔细的对象设计。

我不太清楚,但单位是我的“单位”应用程序中的实体:它们存储在数据库中。单位之间有换算数(公里、米、英里、英尺等)。所以webservice提供了单位DTO来访问单位实体,所以我在另一个应用程序中将DTO用作VO可能是错误的……这听起来很混乱,但是是的,你不应该将DTO用作VO,它们有不同的用途
public class OperandValue:ICompatbile<OperandValue>
{ 
     public decimal Value {get;set;}
     public UnitBase Unit {get;set;}
     public bool IsCompatbile(OperandValue other)
     {
        return Unit.IsCompatbile(other.Unit);
     }

     public static OperandValue FromDto(Operand data)
      {
         return new OperandValue(data.Value,UnitBase.FromDto(data.Unit));
       }
}

 OperandValue first=OperandValue.FromDto(operand1);
 OperandValue second=OperandValue.FromDto(operand2);

if (first.IsCompatbile(second)){
    OperationService.Add(first,second)
  }