2017年末,聊聊现在的三层架构_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 2017年末,聊聊现在的三层架构

2017年末,聊聊现在的三层架构

 2017/10/20 17:30:09  RocketRobin  程序员俱乐部  我要评论(0)
  • 摘要:这几天在知乎看到了许多关于滥用三层的讨论,很多观点都暗指三层架构这东西太Low了。Low吗?其实不然。我们觉得三层Low主要是因为三层太简单了,人们往往不理解三层的思想和目的,滥用三层,加之一些劣质程序员为其加上些自认牛逼的更改搞个五六七八层,代码写得又烂,结果看起来就很Low,于是人们就把锅扣到三层头上。那么三层的目的是什么,意义在哪里呢?其实三层的出发点是“关注点分离”,三层是“关注点分离”思想的一种实现或者说体现。许多用三层的人往往不理解这一点,甚至为了让项目看起来高大上,还要再多加几层
  • 标签:架构

  这几天在知乎看到了许多关于滥用三层的讨论,很多观点都暗指三层架构这东西太Low了。Low吗?其实不然。我们觉得三层Low主要是因为三层太简单了,人们往往不理解三层的思想和目的,滥用三层,加之一些劣质程序员为其加上些自认牛逼的更改搞个五六七八层,代码写得又烂,结果看起来就很Low,于是人们就把锅扣到三层头上。

  那么三层的目的是什么,意义在哪里呢?其实三层的出发点是“关注点分离”,三层是“关注点分离”思想的一种实现或者说体现。许多用三层的人往往不理解这一点,甚至为了让项目看起来高大上,还要再多加几层,再加个Bll接口、Dal接口什么的,美其名曰N层架构,看到这我想大家都要吐了,太Low了,简直是太Low。人们已经忘记了为什么要用三层了,思想已被束缚住。

  那么怎么改?不用三层了吗?那我们用什么?业务和数据访问写一起吗?当然不,现在三层被唾弃,主要原因是因为三层还是十年前(这只是个比喻)那个三层,十年和现在写的代码和写代码的方式变化巨大,用十年前的办法解决现在的问题,显然有bug。

  技术日新月异,那年的三层是为了解决代码太多,太混乱,现在呢,前后端分离,数据访问有ORM,代码没那么乱了,我们的架构也应该跟着改进。比如你的项目里用的EF那么就可以考虑去掉数据访问层,因为EF大大减少了数据访问的代码(我看eShopOnContainers里就是),以前的一个方法,用EF可能只有一行而已。而我现在用Dapper,代码量还是有的,因为SQL格式化占行很多,都写在逻辑里还是不合适。

  大家可以看看微软的eshorpOnContainers项目的代码,里面没有分层,但是也是按照“关注点分离”的方式分了文件夹,也可以说它只是分了两层。的确,我们一定要保留层的概念吗?其实不一定,想想我们过去的多层结构里有什么层,表示层、业务逻辑层、数据访问层、通用层、模型层。你看一个基本的多层架构就有5层,好吧,这些都是层吗?仔细想想其实不是,通用层和模型成是贯穿的,不应该算作层。写到这里我去看了我过去写的采用三层的项目,只看Common一层,我发现,这里的方法、类都是特定的,特定用于某一层的,比如md5这个只有bll用的到,IsEmail等方法也只有bll用的到。所以我们可以把Common一层删掉,属于哪个层的代码,放回到那一层。比如可以在Dal和Bll里各写一个 internal  的Common(名字就随便起啦)类用来包装属于这一层的通用代码,internal保证不会和其它层冲突。我看eShop里也没有什么Common之类的项目,只是在一些项目里会有一些类,用来封装这个程序集本身会用到的东西。

 

  最近看了看IdentityServer4的源码(很少量),我发现了它和微软代码的一些共同处,其中之一就是Services,这里面包含了业务逻辑的代码。这就提示了我们:“是时候抛弃层的概念了”。是不是,其实N层里真正有层级关系的也只是3层而已,即使再加一个Cache层,比如Redis,那这个层是不是也应该只由Bll层来调用才合适呢,所以我们先抛弃层的概念,把原来层的概念抛弃,项目名字改一改,只用三层的基本概念“关注点分离”来设计项目的机构,那么项目结构就不是层状的了,而是块状的。

  我们把三层的结构改一改:

  这是一个含有Cache(比如可以用Redis)的架构,你看把Bll改成Service,Dal改成Store是不是看起来变得高大上了呢。

  我来解读一下这个架构设计: Store和Cache只由Service调用,表示层的各种程序负责收集数据、转换数据、基本数据验证(模型验证),说到数据验证,现在的Web应用的发展方向就是前后端分离,后端基本就只传个数据,不再负责渲染,这种模型就像是App了,用户浏览网页其实是我分发个html客户端给他。而且在验证数据的时候,现在几乎没有不用前端验证的吧,无论是web和app,那么后端验证数据就不用搞一个复杂的结果给前端,只要告诉前端“不对,数据不对”,说个大概就行了,因为正常用户不会绕过前端验证,不绕过前端验证服务端验证就不会有问题,所以使用简单的消息告知前端有错误。那么现在表现层的任务就简单了:收集数据、基本验证、转换传出数据。

  Service模块继续承担以前业务逻辑层的功能,搞搞业务逻辑,比如用户要数据,Api先搞一搞,看看身份啊,  Id啊什么的有没有什么问题,然后Service先验证关键数据(就是不是基本类型的,和逻辑紧密相关的,比如某个东西存不存在什么的),然后去Cache搞一搞,没有再到Store里搞一搞,最后搞点数据给后端Api,Api序列化之后再传回去。

  其实我们还是分层了,而且就是三层,服务端的三层,变化就是我们明晰了层的意义,一个层也不一定只装一类代码,分层的依据也变了,现在是调用关系主导分层,不再是过去的固定模式了。

  你也可以这样理解,整个程序只有两层,一层是Api用于暴露给,远端的Client,Service是一层,处理业务逻辑,Service用Store处理存储在数据库中的数据,用Cache处理缓存。而Model将它们联系在一起,使其成为一个monolithic程序(对,就是那个谈微服务是谈到那个monolithic),说到这里又想说在eShopOnContainers项目里的微服务,那个Web程序在读取数据的时候是去掉相应的Api通过Http去另一个App去拿取数据。需要Catalog就找CatalogApi要,需要什么就找什么Api去要。写到这里你应该能想到这篇文章一直在讨论的真正的东西“关注点分离”,你可以多种角度去观察一个项目/产品/网站,用不同的方式去归类。

  

  你看这个改进的三层架构,如果以模块的角度看,它就不是三层了,去掉了哪些无用的东西,没有定式,结构看起来还挺实用。

  一些的架构设计或者其他框架(比如说最容易和三层混淆MVC)的设计都很像三层,因为他们都有体现关注点分离,而且计算机里离不开数据和界面显示和逻辑。所以大家看起来都有三层的影子,或者说互相像互相,只是应用三层太广泛了。

  分层就像是横切,微服务就像是纵切,复杂一点的就是交叉切,整个系统编程一个一个的微粒,难道我们编写大型应用的最终形态就是微服务? 也许吧。可能当一个系统足够大的时候,横切分层就不太管用了,每一层的代码量也变得巨多,团队协作也难了。这时候拆分微服务就太恰当了,这几天看到博客园里某园有说到:“谁都不会用三层写Hello world”(大意是这个),他说的对,我们设计架构的时候,要考虑我们系统的体量,太大了就得拆,最终就是拆成颗粒,基本上就是微服务了。但是不大就没必要,微服务成本也是有的,只有系统大过某一程度(这个程度自己考量,据我观察这个程度值并不是很高)的时候,微服务带来的利益才会高出成本,微服务价值才能得到体现。

  我看eShop的源码量也很少,我想看看微软是如何写项目的,高级程序员的架构是如何设计的,能给我的开发带来什么启发,所,以希望大家也能去看看。

  纵观现有的各种框架 mvc mvp mvvm 还有什么么其它的,他们的设计方式似乎后符合“关注点分离”这一思想,那么为什么?那就得思考关注点分离能带来什么?分组开发,专人专事,擅长搞前端的去搞前端,擅长P图的去P图。提高每个人的效率,而又能让整个系统完美的运转起来,这就是我对于关注点分离的理解。

  话说回来,三层真的用不得了吗?不知道,我觉得改改还能用。
  鉴于我的理解,我在架构设计中,会关注适用性以及目的,对基本架构做出改变。加勒比海盗中有一句台词令我印象深刻:“法典只不过是一些指导,它并不是必须遵守的规定”。我们不能被框架/架构束缚住,普适性原则不是规定,它总是可以变的。

  哦,最后我还建了个上面所设计改进版的项目,贴个图。注:我还没有实际应用过这个设计,如果你要参考,那么请想好了再参考

 

 

 


  欢迎大家加入.NetCore学习交流群 群号:180537383  

 

 

发表评论
用户名: 匿名