.net – 跟踪复杂对象图中的变化

我开始考虑在断开的应用程序中跟踪复杂对象图中的变化.我已经找到了几个解决方案,但是我想知道是否有最佳实践或者使用什么解决方案,为什么?我把同样的问题交给了 MSDN forum,但是我只收到了一个答案.我想有更多的答案从其他开发人员的经验中学习.

这个问题与.NET有关,所以对于实现细节的答案我更喜欢与.NET世界相关的答案,但我认为在其他平台上是一样的.

我的案例中的理论问题是在多层架构中定义的(目前不一定是n层),如下所示:

>使用ORM来处理持久性的存储库层(ORM工具在当前并不重要,但最有可能是Entity Framework 4.0或NHibernate).
>表示域对象的纯类(持久无知=等价于Java世界中的POJO的POCO)的集合.存储库会持续存在这些类并将其作为查询结果返回.
>使用域实体的域服务集.
>定义门户到业务逻辑的门面层.在内部,它使用存储库,域服务和域对象.域对象不被暴露 – 每个外观方法使用一组专门的数据传输对象进行参数和返回值.每个门面方法的责任是将域实体转换为DTO,反之亦然.
>使用立面图层和DTO的现代Web应用程序 – 我称之为断开连接的应用程序.一般来说,设计可以在将来改变,因此Facade层将被Web服务层包裹,Web应用程序将消耗该服务=>过渡到3层(网络,业务逻辑,数据库).

现在假设域对象之一是具有订单详细信息(行)和相关订单的订单.当客户端请求订购订单时,可以修改订单,添加,删除或修改任何订单明细,并添加或删除相关订单.所有这些修改都是通过Web浏览器中的数据完成的 – javascript和AJAX.所以当客户端按下保存按钮时,所有的更改都会被单独提交.问题是如何处理这些变化?存储库和ORM工具需要知道哪些实体和关系被修改,插入或删除.我结束了两个“最好的”解决方案:

>将隐藏字段中DTO的初始状态存储(更糟的情况是会话).当接收到保存更改的请求时,基于接收的数据创建新的DTO,并且基于持久数据创建第二个DTO.合并这两个并跟踪更改.将DTO合并到外观图层,并使用收到的关于更改的信息来正确设置实体图.这需要在域对象中进行一些手动更改跟踪,以便可以从头开始设置变更信息,稍后传递到存储库 – 这是我不太高兴的一点.
>不要跟踪DTO的变化.当在门面层中接收到修改后的数据时,创建修改后的实体并从存储库中加载实际状态(通常是数据库的附加查询 – 这是我不太满意的一点) – 合并这两个实体并自动跟踪由ORM工具提供的实体代理的更改(实体框架4.0和NHibernate允许这一点).并发处理需要特别注意,因为实际状态不一定是初始状态.

你觉得怎么样?你有什么建议?

我知道通过在某些应用程序层使用缓存可以避免其中的一些挑战,但这是我现在不想使用的.

我对这个话题的兴趣甚至更远.例如,假设该应用程序进入3层体系结构,并且客户端(Web应用程序)将不会在.NET = DTO类中编写,不能重复使用.跟踪DTO的变化将会更加困难,因为这将需要其他开发团队在其开发工具中正确实施跟踪机制.

我相信这些问题必须在很多应用中得到解决,请分享你的经验.

解决方法

这一切都是关于责任的.

(我不知道这是否是你以后的答案 – 让我知道,如果不是这样我可以更新).

因此,我们在系统中有多个层次 – 每个层面负责不同的任务:数据访问,UI,业务逻辑等.当我们以这种方式构建系统时,我们(其中包括)尝试通过制作未来的变化每个组件负责一个任务 – 所以它可以专注于一个任务,并做好.随着时间的推移,系统的修改也变得更加容易,而且改变了.

在考虑DTO时,需要考虑类似的想法 – “如何跟踪变化?例如.以下是我如何处理:BL负责管理规则和逻辑;鉴于网络的无状态(这是我做大部分工作的地方),我只是不追踪一个对象的状态并明确地查看更改.如果用户正在传回数据(要保存/更新),我将把所有的内容传递给他们,而不必关心改变的内容.

一方面这似乎效率不高,但数据量并不大,这不是问题;在另一方面,较少的“移动部件”不太可能出错,因为该过程更简单.

我如何传回资料? –

>我使用DTO(或者也许POCO会更准确);当我在BL和DAL(通过interfaces / DI)之间交换数据时,数据被交换为DTO(或它们的集合).具体来说,我使用一个单一实例的结构体和这些结构体的集合为多个.
> DTO被定义在一个很少依赖的普通类中.
>我故意尝试限制DTO为特定对象创建的数量(如“Order”) – 但同时如果有一个很好的理由,我会创建一个新的对象.通常我会有一个“胖”的DTO,其中包含大部分/所有的数据可用于该对象,我也可能有一个更精简的设计用于集合(列表等).在这两种情况下,这些DTO都是纯粹的返回“阅读”信息.你必须保持责任 – 当BL要求数据时,通常不会同时写回数据;所以DTO是“只读”的事实更多的是符合干净的界面和架构而不是业务规则.
>我总是为插入和更新定义单独的DTO,即使它们共享完全相同的字段.这样可能发生的最糟糕的情况是重复一些trival代码 – 而不是具有依赖关系和多个重用案例来解开.

最后 – 不要混淆DAL如何与UI的工作原理;让ORM做他们的事情,只因为他们以特定的方式存储数据并不意味着它是唯一的办法.

最重要的是在层之间指定有意义的界面.

管理改变的是BL的工作;让UI以最适合您的用户的方式工作,让BL知道如何处理这个问题,DAL(通过您的DI的干净的界面)只是告诉你的.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 连接 连接池产生原因 连接池实现原理 小结 TEMPERANCE:Eat not to dullness;drink not to elevation.节制
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。-- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelC
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。一、接口和抽象类类,即一个对象。先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类)。官方定义让人费解,但是记忆方法是也不错的 —包含抽象方法的类叫做抽象类。接口
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket一、引子文件,作为常见的数据源。关于操作文件的字节流就是 —FileInputStream&FileOutputStream。
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_Aonqz
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程与多线程 线程是什么? 线程(Thread)是一个对象(Object)。用来干什么?Java 线程(也称 JVM 线程)是 Java 进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。 Ja
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket在面向对象编程中,编程人员应该在意“资源”。比如?1String hello = "hello"; 在代码中,我们
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 《程序兵法:Java String 源码的排序算法(一)》 文章工程:* JDK 1.8* 工程名:algorithm-core-le
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 一、父子类变量名相同会咋样? 有个小故事,今天群里面有个人问下面如图输出什么? 我回答:60。但这是错的,答案结果是 40 。我知错能改,然后说了下父子类变
作者:泥瓦匠 出处:https://www.bysocket.com/2021-10-26/mac-create-files-from-the-root-directory.html Mac 操作系统挺适合开发者进行写代码,最近碰到了一个问题,问题是如何在 macOS 根目录创建文件夹。不同的 ma
作者:李强强上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。一、引子在Java世界里,99%的工作都是处理这高层。那么二进制,字节码这些会在哪里用到呢?自问自答:在跨平台的时候,就凸显神功了。比如说文件读写,数据通信,还
1 线程中断 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want需求 项目在设计表的时候,要处理并发多的一些数据,类似订单号不能重复,要保持唯一。原本以为来个时间戳,精确到毫秒应该不错了。后来觉得是错了,测试环境下很多一
纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 加微信:bysocket01
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want.文章Points:1、介绍RESTful架构风格2、Spring配置CXF3、三层初设计,实现WebService接口层4、撰写HTTPClient 客户
Writer :BYSocket(泥沙砖瓦浆木匠)什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道“就一个回调…”。此时千万个草泥马飞奔而过(逃哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉。不妨总结总结。一、什么是回调回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百
Writer :BYSocket(泥沙砖瓦浆木匠)一、什么大小端?大小端在计算机业界,Endian表示数据在存储器中的存放顺序。百度百科如下叙述之:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加
What is a programming language? Before introducing compilation and decompilation, let's briefly introduce the Programming Language. Programming la
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket泥瓦匠喜欢Java,文章总是扯扯Java。 I/O 基础,就是二进制,也就是Bit。一、Bit与二进制什么是Bit(位)呢?位是CPU
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocket一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标:专注很重要。专注Java 基础 + H5(学习) 其他操作系统,算法,数据结构当成课外书博览。有时候,就是那样你越是专注方面越