- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在从事一个大型项目,该项目部分是要替换现有的服务器堆栈。对于一个非常规范化的大型数据库,很明显我们需要构建许多复合对象。我的一个查询的一个例子是这样的:我的复合对象定义:
[DataContract]
public class CompositeEvent
{
Guid eventIdentity;
string accountIdentity;
string eventMessage;
DateTime eventLoggedOn;
string methodName;
string programName;
string userIdentity;
List<CompositeException> exceptions = new List<CompositeException>( );
List<CompositeParameter> methodParameters = new List<CompositeParameter>( );
List<CompositeParameter> databaseParameters = new List<CompositeParameter>( );
[DataMember]
public Guid EventIdentity
{
get { return eventIdentity; }
set { eventIdentity = value; }
}
[DataMember]
public string AccountIdentity
{
get { return accountIdentity; }
set { accountIdentity = value; }
}
[DataMember]
public string EventMessage
{
get { return eventMessage; }
set { eventMessage = value; }
}
[DataMember]
public DateTime EventLoggedOn
{
get { return eventLoggedOn; }
set { eventLoggedOn = value; }
}
[DataMember]
public string MethodName
{
get { return methodName; }
set { methodName = value; }
}
[DataMember]
public string ProgramName
{
get { return programName; }
set { programName = value; }
}
[DataMember]
public string UserIdentity
{
get { return userIdentity; }
set { userIdentity = value; }
}
public string QualifiedCreator
{
get
{
if ( String.IsNullOrEmpty( programName ) && String.IsNullOrEmpty( methodName ) )
return string.Empty;
return string.Format( "{0}:{1}", String.IsNullOrEmpty( ProgramName ) ? "{undefined}" : ProgramName, String.IsNullOrEmpty( MethodName ) ? "{undefined}" : MethodName );
}
}
[DataMember]
public int EventTypeIdentity { get; set; }
[DataMember]
public string EventTypeName { get; set; }
[DataMember]
public List<CompositeException> Exceptions
{
get { return exceptions; }
set { exceptions = value; }
}
[DataMember]
public List<CompositeParameter> MethodParameters
{
get { return methodParameters; }
set { methodParameters = value; }
}
[DataMember]
public List<CompositeParameter> DatabaseParameters
{
get { return databaseParameters; }
set { databaseParameters = value; }
}
}
我的服务中的数据库查询:
using ( Framework.Data.FrameworkDataEntities context = new Data.FrameworkDataEntities( ) )
{
var list = from item in context.EventLogs
join typeName in context.EventLogTypes on item.EventTypeId equals typeName.Id
orderby item.EventLoggedOn, item.EventLogType
select new CompositeEvent
{
AccountIdentity = item.AccountIdentity,
EventIdentity = item.Id,
EventLoggedOn = item.EventLoggedOn,
EventMessage = item.EventMessage,
EventTypeIdentity = item.EventTypeId,
EventTypeName = typeName.EventTypeName,
MethodName = item.MethodName,
ProgramName = item.ProgramName,
UserIdentity = item.UserIdentity
};
return new List<CompositeEvent>( list );
}
现在从我的复合对象的定义中可以清楚地看出它只包含数据,没有业务规则,也没有业务结构、数据结构或任何其他内容的其他持久化或暴露。
然而我的队友说这只能存在于域模型中,我必须花时间将我的数据从这个定义明确的对象移动到 DTO。不仅如此,而且 a) 所有 DTO 的名称中都必须包含 DTO,并且 b) 它们的存在必须只是为了在网络中移动。因此,当我们开发客户端代码时,它必须 a) 创建每个对象属性的属性,以及 b) 从 DTO 移动到 View 模型属性。
我感觉这是把DTO发挥到了极致。基于复合对象的定义,这些是数据传输对象。此外,我认为将此对象存储在客户端中并直接绑定(bind)到客户端中的此对象绝对没有问题。由于我所做的只是获取复合对象中定义的每个属性并将它们复制到 DTO 中,创建一个对象只是为了将其复制到另一个对象然后再次将其复制到内部似乎是对时间和周期的巨大浪费客户端的属性。
我对关于此的其他意见很感兴趣。我觉得我没有违反任何 OOP 规则,例如关注点分离或单一职责原则……至少只要您不对这些规则变得非常厌恶。意见????
最佳答案
好吧,您同事强调的所有必须
让他看起来有点强制症。但这没关系,因为他确实有道理。
DTO,尤其是 MVC 中的 DTO,应该以这样一种方式进行设计,使它们抽象出底层数据模型,以便它们成为 View 的实际模型。让它们靠近您的对象只会导致您修改两组对象,而实际上可能只有其中一个需要更改。
在 SoA 或 N 层架构中设计 DTO 时要考虑的另一件事是,它们不应在您的 View 层与底层服务和模型之间创建契约。因此,如果数据库中发生某些变化(字段、表、 View 等),您应该能够从服务层开始调整所有内容,并以不影响 DTO 的方式进行调整。
View 模型应该保持不变,至少只要您不在其中添加或删除功能。任何潜在的变化都应该适应 DTO(不是绕过的方式 - 但这并不总是可能的)。
现在我应该提一下,我现在正在将一个项目从 SoA 和 DTO 切换到普通的 2 层架构(这是因为性能问题,而不是 DTO:))。我有一个包含简单对象和复杂对象的横切域层,旨在仅供内部使用。任何通过 Web 服务公开的 API 都将使用 DTO,因为我不想杀死 WS 消费者。也许会伤害他们一点 :)。
但是您应该按照我上面提到的方式使用 DTO。它将对您的情况有所帮助(使用 MVC)。为了更容易映射到 DTO,反之亦然,我建议 AutoMapper
.会让你的生活更轻松(让你的同事开心)。
关于c# - 关于何时需要特定 DTO 类的另一个讨论,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11351207/
我看到 DTO 类型在域模型中的类型内创建并在类型之间传递。这是好习惯吗? 我一直认为 DTO 主要用于上下文边界(即对象图的边缘)以解耦上下文实现(例如域/ui 边界)。 最佳答案 你的问题有点主观
我们将使用 DTO 向表示层发送数据或从表示层发送数据。我们有这样的层: 外观 应用服务 域名 我们使用 Dozer 来帮助我们将实体转换为 dto。但我现在有两个问题: 从entity到dto我们可
我对术语有疑问。根据 Fowler 的说法,DTO 是“在进程之间传输数据以减少方法调用次数的对象”。 (http://martinfowler.com/eaaCatalog/dataTransfer
我们使用 spring-boot 开发的应用程序遵循微服务架构。为了解释这个问题,让我们考虑 3 个不同的服务 A、B、C。服务 A 和 B 也使用服务 C 的一些 API。 我在项目 C(服务 C)
所以基本上我正在编写一个使用 DTO 的 API,但我在返回 DTO 内的另一个实体时遇到了问题。 这是我的 DTO: public class DirectoryDTO { String per
我尝试从方法响应正文中获取派生类字段。请求体参数是基类的类型。请求带有派生类字段,但我无法将其转换为派生类。 这是我的 Controller 方法和 DTO 类: 方法: @PostMapping(
这更多的是一个理论问题,而不是一个实际问题。 我们有一个分层架构,类似于: UI UI_JavaHandler Backend DTO1 需要比 DTO2 多一点的数据,并且恰好是一个额外的字符串
我在 Wildfly 10.1.0-Final 上使用带有 Java 8 和 Hibernate (5.0.X) 的 Java EE 7,我需要使用投影将 JPQL 查询结果加载到 DTO 中,但我找
有一个建议是transfer objects should not contain object references to other transfer objects .相反,他们应该使用其他传输
我们正在开始一个新项目并正在设计 DTO,这些 DTO 将被注入(inject)到具有行为的相应 POCO 中。然而,我能找到的每个 DTO 示例都只包含值类型,例如: public class Cu
这可能是一个一般的java问题 DTO1 属性1 属性2 属性3 DTO2 属性1 属性2 属性3 属性4 属性5 属性6 属性7 属性8 属性9 属性10 属性11 属性12 我将在屏幕上的 gxt
我在一个项目中遇到了一个问题,并在一个裸测试项目中成功地重现了它。 我有以下 dto: public class AppUserDto { public int Id { get; set;
我正在研究 RESTful API,但在为 API 提供输入的过程中遇到了一些麻烦。 假设我有一个可以像这样获取的“人”资源:api/person/{id}并返回一个这样的对象: public cla
我正在使用 DTO 构建我的第一个应用程序 - 我目前有一个 DTO 用于获取特定对象的数据,另一个不同的 DTO 用于更新(PUTting)数据 - 因为只有少数字段可以从任何客户端更新,我决定为
private void writeData(HSSFSheet sheet) { for (int i = 0; i 并动态获取 DTO 属性值?,我们在Stack Overflo
我正在尝试使用 Jackson 和 Kotlin 将 YAML 文档映射到复杂的 DTO 结构,但似乎在某处遇到了误解。 我正在解析的 YAML 文档是 item_names: - item:
这个问题在这里已经有了答案: How to efficiently create a list of objects inside of a generic method? (2 个答案) 关闭 9
我们将使用 DTO 向表示层发送数据或从表示层发送数据。 我在名为 PostAd 的服务对象上有一个方法,它发布用户输入的广告。 Ad 与另一个名为 AdValues 的对象相关联,该对象包含 Ad
我的应用程序服务中有验证逻辑,用于确定请求的操作是否成功,如果没有,原因。我质疑这是否是代码异味,因为它在应用程序服务中而不是域服务中,它围绕检查域模型是否存在、dto 中的属性是否可以为空等展开。代
我有以下域模型: public class Playlist { public long Id { get; set; } public string Title { get; set
我是一名优秀的程序员,十分优秀!