加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 16:47:06 所属栏目:Java 来源:网络整理
导读:我开始考虑在断开的应用程序中跟踪复杂对象图中的变化.我已经找到了几个解决方案,但是我想知道是否有最佳实践或者使用什么解决方案,为什么?我把同样的问题交给了 MSDN forum,但是我只收到了一个答案.我想有更多的答案从其他开发人员的经验中学习. 这个问题
我开始考虑在断开的应用程序中跟踪复杂对象图中的变化.我已经找到了几个解决方案,但是我想知道是否有最佳实践或者使用什么解决方案,为什么?我把同样的问题交给了 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的干净的界面)只是告诉你的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读