软件架构分层方法论

        

  点击上方“JavaEdge”,关注公众号
web

设为“星标”,好文章不错过!



通常初创软件,为快速上线,几乎不考虑分层。但随业务愈加复杂,就会致使逻辑复杂、模块相互依赖、代码扩展性差等各类问题。数据库

架构分层迫在眉睫。缓存


1 什么是架构分层?安全



软件工程中常见的设计方式,将总体系统拆分红N个层次,每一个层次有独立的职责,多个层次协同提供完整的功能。
微信

初学 JavaWeb 时通常要求设计成 MVC 架构。另一种常见的分层方式是将总体架构分为网络

  • 表现层(Web)
    展现数据结果和接受用户指令的,是最靠近用户的一层;架构

  • 逻辑层(Service)
    复杂业务的具体实现;并发

  • 数据访问层(Dao)
    主要处理和存储之间的交互。app

这就能够隔离关注点,让不一样的层专一作不一样的事情。其它分层案例,好比OSI网络七层模型,TCP/IP协议网络四层模型。运维


2 分层有什么好处?






简化设计


各司专职,而没必要将本身活成全才。




高复用


好比在设计某系统时,发现某层具备通用性,就可把它抽取独立出来,在设计其它系统时使用。




横向扩展


可让咱们更容易作横向扩展。若是系统没有分层,当流量增长时咱们须要针对总体系统来作扩展。可是,若是咱们按照上面提到的三层架构将系统分层后,就能够针对具体的问题来作细致的扩展。

好比业务逻辑里面包含有比较复杂的计算,致使CPU成为性能的瓶颈,那这样就能够把逻辑层单独抽取出来独立部署,而后只对逻辑层来作扩展,这相比于针对总体系统扩展所付出的代价就要小的多了。

架构分层究竟和高并发设计的关系是怎样的?咱们知道横向扩展是高并发设计思想之一,既然架构分层可方便横向扩展, 那么高并发系统必定是分层的。


3 如何架构分层?



关键在于理清层次边界。
若按三层架构分层,边界不就很容易界定吗?
是的没毛病,当业务逻辑简单时,层次间边界的确清晰,开发新功能时也知道把代码往哪写。但当业务逻辑愈来愈复杂,边界也会变得模糊。




3.1 案例


任一系统都有用户模块,好比返回用户信息的接口,它调用逻辑层的GetUser方法,GetUser方法又和User DB交互获取数据,就像下图左边展现的样子。

这时,产品提出一个需求,在APP中展现用户信息的时候,若用户不存在,那么要自动给用户建立一个用户。同时,要作一个HTML5页面保留以前的逻辑,即不须要建立用户。这时逻辑层的边界就变得不清晰,表现层也承担了一部分的业务逻辑(将获取用户和建立用户接口关联)。




3.2 主流分层职责


MVC架构的简单性让太多的人以为项目工程结构理所应当就是这样的,而后呢,一大堆的业务逻辑就随意的堆砌在了service中,对象啥的,只是单纯的数据传输做用,出现了用面向对象的语言,写面向过程的程序的广泛现象。按照领域驱动设计的思路,最重要的还要有领域模型层。固然manage层这种方案也是一种思路,可是我以为,这种方式,还不够,必须有清晰的业务模型和合理的分层结构配合,才能更好的提现分层的做用。


终端显示层


各端模板渲染并执行显示的层。当前主要是 Velocity/framemaker渲染、js渲染、移动端展现等


开放接口层


将Service层方法封装成开放接口,同时进行网关安全控制和流量控制等


Web层


主要是对访问控制进行转发,各种基本参数校验,或者不复用的业务简单处理等


Service层


业务逻辑层。调用manager层和dao层处理业务,即简单的业务能够不抽取manager,直接调用dao。
业务类的校验放在service层,通常性的参数校验能够放在web层,这能够通用化。


Manager 层(通用业务处理层)


DDD中也叫领域层。

  1. 能够将原先Service层的一些通用能力下沉到这一层,好比与缓存和存储交互策略,中间件的接入。业务逻辑放在manager,service来编排manager的原子服务。

  2. 也可在这一层封装对第三方接口的调用,好比调用支付服务,调用审核服务等


该分层架构相比MVC主要就是增长了Manager层,它与Service层的关系:Manager层提供原子的服务接口,Service层负责依据业务逻辑来编排原子接口。

  • 业务逻辑就是你的产品逻辑,好比建立用户要具体作什么。

  • manager层的原子服务指的是实现单一功能的服务。

  • 事务应该在service层


DAO层(数据持久层)


数据访问层,与底层 MySQL、Oracle、HBase 等进行数据交互。缓存能够放在存储层。


外部接口或第三方平台


包括其它部门 RPC 开放接口,基础平台,其它公司的 HTTP 接口


例如,Manager层提供建立用户和获取用户信息的接口,Service层负责将这两个接口组装起来。这样就把原先散布在表现层的业务逻辑都统一至Service层,每层边界就清晰了。

好比作一个接口,可将实现放在service层。以后公司内部调用逻辑可放在web层。而哪一天公司要开放这个接口,可直接新抽象一层(一个新的服务),即开放平台层!这样的好处是,能够将本司使用和第三方使用作隔离。好比在提供服务时,为了保证自家接口性能,对开放平台层作限流处理。

传统公司不少是分层部署的,好比保险和金融。service和dao部署在比较严密的网络区域,controller层部署在一个较宽松的网络区域,对外提供服务。等于在网络上增长了一个缓冲区,来保证服务的安全;并且能够经过单向网络规范层级调用,controller能够调用服务层,而服务层是不能调用web层的。
若是将数据访问层单独部署,好比拆分为单独的rpc服务,固然这样拆分粒度比较细。controller就是对外的门面,调用单独的服务层

  • 能够为后期服务运维下降成本

  • 能够提升数据访问层的复用度(数据访问层对外提供API,其余层的应用经过API方式与数据库进行交互),三来能够屏蔽各个数据库实现的具体细节。




3.3 层间依赖


数据流转只能在相邻层间。以三层架构为例,数据从表示层进入后必定要流转到逻辑层,作业务逻辑处理,而后流转到数据访问层和DB交互。但若业务逻辑很简单,能否从表示层直接到数据访问层,甚至直接读DB?
功能上是能够的,但从长远架构设计考虑,这会形成层级调用混乱,好比一旦DB地址变动,就需更改多层,这就失去了分层价值,且维护或重构都是灾难。


4 架构分层的缺陷






4.1 增长代码复杂度


本来可在接收请求后直接查询DB得到结果,却非要在中间多层设计,每层只简单地作数据传递。
有时增长一个小需求,可能还需更改全部层的代码,增长了开发成本,也增长了调试复杂度,增长了与其它模块负责人的沟通成本。




4.2 性能损耗


若每层独立部署,层间经过网络交互,那多层架构势必会在性能上有所损耗。

那是否还要选择架构分层呢?确定的。

你要知道,任何的方案架构都是有优点有缺陷的,天地尚且不全况且咱们的架构呢?分层架构当然会增长系统复杂度,也可能会有性能的损耗,可是相比于它能带给咱们的好处来讲,这些都是能够接受的,或者能够经过其它的方案解决的。咱们在作决策的时候切不能够偏概全,因噎废食。


5 总结



分层架构是软件设计思想的外在体现,是一种实现方式。一些软件设计原则都在分层架构中有所体现。

比方单一职责原则规定每一个类只有单一的功能,在这里可引伸为每层拥有单一职责,且层与层之间边界清晰;
迪米特法则原意是一个对象应当对其它对象尽量少的了解,在分层架构的体现是数据的交互不能跨层,只能在相邻层之间进行;

开闭原则要求软件对扩展开放,对修改关闭。它的含义其实就是将抽象层和实现层分离,抽象层是对实现层共有特征的概括总结,不可修改,但具体实现可无限扩展,随意替换。

参考

  • 《阿里巴巴Java开发手册》


往期推荐

RocketMQ干货集|完全看懂RocketMQ事务实现原理

你知道ZooKeeper为Kafka付出了多少吗?

Redis干货集|Redis分片原理深度讲解

纯干货|Redis过时策略&内存淘汰策略

这多是你见过最好的Redis主从复制原理








目前交流群已有 800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群


喜欢文章,点个“在看、点赞、分享”素质三连支持一下~

本文分享自微信公众号 - JavaEdge(Java-Edge)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索