.NET应用架构设计—用户端的防腐层作用及设计

发布时间:2017-09-04 12:09:31
.NET应用架构设计—用户端的防腐层作用及设计

阅读目录:

1.背景介绍 2.SOA架构下的显示端架构腐化 3.有效使用防腐层来隔离碎片服务导致显示端逻辑腐烂 4.剥离服务调用的技术组件让其依赖接口 5.将服务的DTO与显示端的ViewModel之间的转换放入防腐层 5.1.转换逻辑过程化,直接写在防腐层的方法中 5.2.转换逻辑对象化,建立起封装、重用结构,防止进一步腐化 6.防腐层的两种依赖倒置设计方法 6.1.事件驱动(防腐层监听显示逻辑事件) 6.2.依赖注入接口 7.总结 1.背景介绍

随着现在的企业应用架构都在向着SOA方向转变,目的就是将一个庞大的业务系统按照业务进行划分,不管从公司的管理上、产品的开发上,这一系列流程来看,都是正确的。SOA确实带来了解决现在大型企业级应用系统快速膨胀的解决办法。

但是本文要说的是,我们都将目光转向到了后端,也就是服务端,而将精力和时间都重点投在了后端服务的架构设计上,渐渐的忽视了显示端的架构设计。然而显示端的逻辑也越来越复杂,显示端轻薄的架构其实已经浮现出难以应付后端服务接口快速膨胀的危险,服务接口都是按照指数级增加,基本上每一个新的业务需求都是提供新的接口,这没有问题。按照服务的设计原则,服务接口就应该有着明确的作用,而不是按照代码的思维来考虑接口的设计。

但是由此带来的问题就是组合这些接口的显示端的结构是否和这种变化是一致的,是否做好了这种变化带来显示端逻辑复杂的准备。

根据我自己的亲身体会,我发现显示端的架构设计不被重视,这里的重视不是老板是否重视,而是我们开发人员没有重视,当然这里排除时间问题。我观察过很多用户接口项目架构,结构及其简单,没有封装、没有重用,看不到任何的设计原则。这样就会导致这些代码很难随着业务的快速推动由服务接口带来的冲击,这里还有一个最大的问题就是,作为程序员的我们是否有快速重构的意识,我很喜欢这条程序员职业素质。它可以让我们敏捷的、快速的跟上由业务的发展带来的项目结构的变化。

迭代重构对项目有着微妙的作用,重构不能够过早也不能够过迟,要刚好在需要的时候重构。对于重构我的经验就是,当你面对新功能写起来比较蹩脚的时候时,这是一个重构信号,此时应该是最优的重构时间。重构不是专门的去准备时间,而是穿插在你写代码的过程中,它是你编码的一部分。所以我觉得TDD被人接受的理由也在于此。

2.SOA架构下的显示端架构腐化

显示端的架构腐化我个人觉得有两个问题导致,第一个,原本显示端的结构在传统系统架构中可以工作的很好,但是现在的整体架构变了,所以需要及时作出调整。第二,显示端的架构未能及时的重构,未能将显示端结构进行进一步分离,将显示逻辑独立可测试。

这样随着SOA接口的不断增加,显示端直接将调用服务的方法嵌入到显示逻辑中,如,ASP.NET Mvc、ASP.NET Webapi的控制器中,包括两个层面之间的DTO转换。

按照DDD的上下文设计方法,在用户显示端也是可以有选择的创建面向显示的领域模型,此模型主要处理领域在即将到达服务端之后的前期处理。毕竟一个领域实体有着多个方面的职责,如果能在显示端建立起轻量级的领域模型,对显示逻辑的重构将大有好处,当然前提是你有着复杂的领域逻辑。(我之前的上一家公司(美国知名的电子商务平台),他们的显示端有着复杂的领域逻辑,就光一个显示端就复杂的让人吃惊,如果能在此基础上引入领域模型显示端上下文,将对复杂的逻辑处理很有好好处,当然这只是我未经验证的猜测而已,仅供参考。)

对显示端领域模型处理有兴趣的可以参考本人写的有关这方面的两篇文章:

.NET应用架构设计—面向查询的领域驱动设计实践(调整传统三层架构,外加维护型的业务开关)

.NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)

原本干净的显示逻辑多了很多无关的服务调用细节,还有很多转换逻辑,判断逻辑,而这些东西原本不属于这个地方,让他们放在合适的地方对显示逻辑的重构、重用很有帮助。

如果不将其移出显示逻辑中,那么随着服务接口的不断增加和扩展,将直接导致你修改显示逻辑代码,如果你的显示逻辑代码是MVC、Webapi共用的逻辑,那么情况就更加复杂了,最后显示逻辑里面将被ViewModel与Service Dto之间的转换占领,你很难找到有价值的逻辑了。

3.有效使用防腐层来隔离碎片服务导致显示端逻辑腐烂

解决这些问题的方法就是引入防腐层,尽管防腐层的初衷是为了解决系统集成时的领域模型之间的转换,但是我觉得现在的系统架构和集成有着很多相似之处,我们可以适当的借鉴这些好的设计方法来解决相似的问题。

引入防腐层之后,将原本不该出现在显示逻辑中的代码全部搬到防腐层中来,在防腐层中建立起OO机制,让这些OO对象能够和显示逻辑一起搭配使用。

图1:


将用户层分层三个子层,UiLayer,Show Logic Layer,Anticorrosive Layer,最后一个是服务的接口组,所有的服务接口调用均需要从防腐层走。

我们需要将Show Logic Layer中的服务调用,类型转换代码迁移到Anticorrsoive Layer中,在这里可以对象化转换逻辑也可以不对象化,具体可以看下项目是否需要。如果业务确实比较复杂的时候,那么我们为了封装、重用就需要进行对象化。

4.剥离服务调用的技术组件让其依赖接口

首先要做的就是将逻辑代码中的服务对象重构成面向接口的,然后让其动态的依赖注入到逻辑类型中。在ASP.NETWEBAPI中,我们基本上将显示逻辑都写在这里面,我也将使用此方式来演示本章例子,但是如果你的MVC项目和WEBAPI项目共用显示逻辑就需要将其提出来形成独立的项目(Show Logic Layer)。

using OrderManager.Port.Models; using System.Collections.Generic; using System.Web.Http; namespace OrderManager.Port.Controllers { public class OrderController : ApiController { [HttpGet] public OrderViewModel GetOrderById(long oId) { OrderService.Contract.OrderServiceClient client = new OrderService.Contract.OrderServiceClient(); var order = client.GetOrderByOid(oId); if (order == null) return null; return AutoMapper.Mapper.DynamicMap(order); } } }

这是一段很简单的调用Order服务的代码,首先需要实例化一个服务契约中包含的客户端代理,然后通过代理调用远程服务方法GetOrderByOid(long oId)。执行一个简单的判断,最后输出OrderViewModel。

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:襄阳网站建设公司 https://www.jingchucn.com/zt/xiangyang_wangzhanjianshe/