Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用和创建DTO是OOP世界? 从业务对象创建DTO的正确方法是什么 谁应该负责创建它们?BO/从BO/某个静电工厂到自身 如果我有一些核心库和我需要DTO的特定服务API库,它们应该驻留在代码中的什么地方?在BO旁边的核心库中(这似乎不正确)/在特定库中 如果我在BO中封装了字段,那么DTO如何获取它们?(显然,如果BO不负责创建DTO)_Oop_Design Patterns_Dto - Fatal编程技术网

如何使用和创建DTO是OOP世界? 从业务对象创建DTO的正确方法是什么 谁应该负责创建它们?BO/从BO/某个静电工厂到自身 如果我有一些核心库和我需要DTO的特定服务API库,它们应该驻留在代码中的什么地方?在BO旁边的核心库中(这似乎不正确)/在特定库中 如果我在BO中封装了字段,那么DTO如何获取它们?(显然,如果BO不负责创建DTO)

如何使用和创建DTO是OOP世界? 从业务对象创建DTO的正确方法是什么 谁应该负责创建它们?BO/从BO/某个静电工厂到自身 如果我有一些核心库和我需要DTO的特定服务API库,它们应该驻留在代码中的什么地方?在BO旁边的核心库中(这似乎不正确)/在特定库中 如果我在BO中封装了字段,那么DTO如何获取它们?(显然,如果BO不负责创建DTO),oop,design-patterns,dto,Oop,Design Patterns,Dto,举个例子,假设我有这样的人: class Person { private int age; public bool isBigEnough => age > 10; } 我希望age成为Person的内部状态,但我仍然需要将我的BO与一些api进行通信。或者在我的类中有我想发送到某处的私有字段意味着它应该是公共的 对于如何将DTO与封装数据的业务类一起使用,有什么一般性的考虑吗 更新: 除了@Alexey Groshev提到的方法外,我还使用了另一种方法:我们使用

举个例子,假设我有这样的人:

class Person
{
    private int age;
    public bool isBigEnough => age > 10;
}
我希望
age
成为
Person
的内部状态,但我仍然需要将我的BO与一些api进行通信。或者在我的类中有我想发送到某处的私有字段意味着它应该是公共的

  • 对于如何将DTO与封装数据的业务类一起使用,有什么一般性的考虑吗
  • 更新:


    除了@Alexey Groshev提到的方法外,我还使用了另一种方法:我们使用公共访问器将BO类的数据分离到某个数据类中。BO使用其api(可能使用组合)包装此数据,并在需要时将其状态作为数据类作为克隆返回。因此,dto转换器将能够访问域对象的状态,但无法修改它(因为它只是一个副本)。

    我认为问题5的答案也将解决其他问题

    对于如何将DTO与封装数据的业务类一起使用,有什么一般性的考虑吗


    请记住,DTO仅用于传输数据。不要在DTO中执行任何类型的规则。它只用于将数据从一个子系统移动到另一个子系统(而不是在同一个子系统的类之间)。数据在目标系统中的使用方式超出了您的控制范围——尽管作为上帝程序员,您天生就知道如何使用数据,但不要让这些知识影响您的设计——因此不应将任何假设表示为行为或知识访问器——因此,没有
    足够大

    有多种选择,但很难推荐任何东西,因为我不知道您的项目/产品的详细信息。无论如何,我会列举一些

  • 您可以使用将BO映射到DTO,反之亦然。我个人不喜欢这种方法,因为在中型/大型项目中很难(但可能)控制它。人们通常不会费心正确配置映射,而只是公开对象的内部状态。例如,您的
    足够大
    将消失,
    年龄
    将成为
    公众
    。另一个潜在的风险是,人们可以将DTO映射到EF/Hibernate对象或从EF/Hibernate对象映射DTO。你可以找到一些文章来解释为什么它被认为是

  • 正如您所建议的,BO可以自己创建DTO,但是您将如何实现这种方法?您可以向实体添加方法或工厂方法,例如,
    public PersonDto ToDto()
    。或者您可以添加一个接口,例如,
    公共接口IDtoConvertable{T ToDto();}
    ,并选择哪个实体或聚合根将实现它。您的
    Person
    类将如下所示
    类Person:IDtoConvertable{…public PersonDto ToDto(){…}
    。在这两种情况下,名称空间/程序集的数据都必须能够被实体访问,这有时可能是一个问题,但通常不是一个大问题。(确保DTO无法访问更糟糕的实体。)

  • (C#)另一个选项是返回一个创建DTO的委托。我决定将其与(2)分开,因为实体本身并没有真正创建DTO,而是公开了创建DTO的功能。因此,您可以使用类似以下内容的
    public Func ToDto(){…}
    。您可能希望有一个如(2)所示的接口,但您明白了,不是吗?我喜欢这种方法吗?不,因为它使代码不可读


  • 如你所见,问题多于答案。我建议你做一些实验,检查什么对你(你的项目)有效,什么对你无效

    我的
    Person
    类是我自己域模型的一部分。是的,DTO中绝对没有业务逻辑。假设我需要将其作为
    PersonDto
    发送到某个外部服务。如何创建一个?我的许多数据字段都封装在
    Person
    中,我需要从那里检索它们。而且,正如您建议不要让它影响我的设计,我不想公开我的字段。拥有
    Person
    类的子系统应该是唯一知道如何创建
    PersonDto
    的子系统。在该子系统中有一个工厂。注:如果工厂可以从外部进入,则可以。虽然客户端将能够创建
    PersonDto
    对象,但它们的实际创建方式将保持隐藏,从而保留封装。是的,这是我首先想到的。但这是正确的吗?它应该是域的一部分吗?我宁愿说不,也不愿说是。它只是一些基础设施,而不是域。而且,把这些东西放在真正使用它们的地方会干净得多。作为最后的骗局。在这种方法中,我遇到了一种情况,即当您需要相同BO的多个dto格式时。我想域代码可能会变得非常混乱。嗯,你可能创建的
    Person
    类的最大DTO是一个包含所有属性的结构。您还需要什么其他格式?请记住,DTO用于传输数据。没有别的了。甚至没有格式化。所以语句1和3将违反并丢弃所有oop。也许第2点是最好的,尽管它要求您的BO完全了解项目/解决方案中的所有DTO。随着api林的增长,这将成为一个很大的负担。所以基本上作为结论,据我所知,我们有dto的概念是oop不友好的