一、前言


都说”不想做架构师的开发不是好前端“,”一千个读者心中有一千个哈姆雷特“。我相信每个开发者心中,都有一个属于自己的框架,所以今天我就给大家探讨一下我心中的简单分层架构设计。


在说分层架构设计之前,先说下我对架构设计的理解,不足之处还希望大神指点。《.NET应用架构设计》这本书里面写到:架构设计其实为“架构”和”设计”的两个概念,架构是对业务需求的高层抽象,而设计是将高层抽象的需求与具体的技术实现联系起来,在此过程中,会根据实际情况考虑到系统的稳定性、安全性、扩展性兼容性等各种因素。所以在项目业务需求提出之后,经过架构分析,得到系统的机构方案,然后根据架构方案做不同的设计方案,选择适合的设计方案进行开发。架构设计和代码重构一样,他不是一蹴而就的,他也是在迭代中变得完善和稳定。


说到这里,我想说一下框架和模式,平常中或多或少都会看到xx框架、xx模式,架构设计主要体现在设计上面,他们输出可能是文档或者伪代码等,而框架就是对架构设计的累计实现。比如工作中的项目框架,都是在我们经过多次设计、重构过后,得到公共模块(也就是我们说的轮子),在这个基础上,开发就会很便利。模式这是根据开发经验,提出某些问题比较好的解决方案。比如说单例模式、工厂模式等。

当然架构设计肯定没有说得这么简单,他还有很多设计原则和理论,感兴趣的朋友可以自己去了解一下。

下面就是蜗牛根据自己的理解,结合到一个例子对多层架构设计和实现,如果有不合理的地方,希望大家都多指点。

二、分层架构设计实现


一说到分层(这里我们说的是逻辑分层),相信很多人都会想到经典的三层架构。其实分层的目的是把功能按照不同的角色分隔开,便于后期系统扩展、维护,所以三层只是一个最少的层次划分,具体的层次需要根据项目实际的业务情况以及系统的部署情况进行划分。下面我就以一个项目进行说明。

现在需要实现一个论坛的项目,并发量等非业务因素现在都不做考虑,由于经费原因,只能提供一台服务器作为部署环境,可以支持PC端和手机端访问。


我相信很多园友在做项目的时候,都遇到过这个情况,客户只知道他想要这个东西,但是其他的,他一概没考虑。由于这个是例子,就直接按照上面的需求做了,细节方面就后面再修改。

2.1、分层约束


<https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190913073838678-73882663.png>

2.2、分层描述

界面层:用户界面或表现层,即MCV中的view层;


界面控制层和API接口层:界面控制层即MCV中的Control层(使用.net的mvc),API接口层主要以Webapi提供接口,主要用于实现轻业务、参数校验、异常封装以及权限验证;

业务逻辑层(Service层):实现业务处理逻辑;

业务Manager层:可复用逻辑层,完成:1. 对第三方平台封装的层,预处理返回结果及转化异常信息;2.
对Service层通用能力的下沉,如cache,mq等通用处理;

数据持久层(Dao层):数据库访问层。


Common层:里面主要包含业务方法库和公共方法库,业务方法库:主要是协助业务逻辑层处理逻辑,即含业务的公共方法,只被业务逻辑层调用;公共方法库:包含公共方法,可以被所有层调用。公共方法库还有一个原则,就是他不依赖Model,他对于任何层次都可以单独调用,以后作为框架的一个公共库模块。这也就是为什么还会存在一个业务方法库。

分层说明:因为界面层使用的MVC,所以对应的就有界面控制层,如果前后端分离,就只需要API接口层即可。

2.3、分层模型描述

Entity:主要是对数据库表结构一一对应;

DTO:数据传输类型总称,这里将他作为一个象征名词,具体分为:Request(请求对象),Response(响应对象)和DTO(数据传输对象)。

模型运用场景:


界面层发送Request参数请求,界面控制层将请求分发到对应的Service层,Service层根据业务拆分成不同的DTO参数请求或者不做拆分,再发送到Dao层,Dao层访问数据库。如果是数据库表查询,返回Entity对象,如果是多表业务查询,返回DTO对象,Service层经过业务处理返回Response对象到界面控制层,界面层直接返回Response对象。由于项目较小,返回过程中的Entity对象和DTO对象也可以直接返回。

2.4、实现技术

前端技术:html5,css3,javascript,jquery,layui以及它的fly论坛界面;

后端技术:采用.net MVC、WabAPI以及.net
Framework为目标框架;类库采用standard作为目标框架;ORM使用Dapper;依赖注入采用Unity;日志框架使用Log4Net;

技术选型说明:界面层和界面控制层选用的是.net Framework为目标框架的.net MVC,而.net
Core是以后的大势,所以剩下的类库都选用standard作为目标框架,后面如果使用.Net
Core进行跨平台,直接替换界面层和界面控制层即可。在研发过程中还会添加其他的技术,所以架构设计也要不断的迭代。

2.5、编码规范

这里的规范只对架构方面的规范,至于代码书写的规范(命名,注释等)就不做描述了。

1、命名规范

业务逻辑层(Service层)所有文件必须以Service结尾;

业务Manager层所有文件必须以Manage结尾;

数据持久层(Dao层)所有文件必须以Repository结尾;

Entity对象所有文件必须以Entity结尾;

界面层发送的请求必须以Request结尾;

返回给界面层的数据必须以Response结尾;

其余的传输的数据对象必须以DTO结尾。

2、依赖注入

业务逻辑层(Service层),业务Manager层,数据持久层(Dao层)必须有对应的接口层,采用依赖注入的方式实例化对象。

3、方法库

业务方法库和公共方法库都必须是静态方法,并且业务方法库只能被业务逻辑层(Service层)调用。

4、参数规范

所有的方法,请求和返回对象都必须一一对应。(主要是防止一个对象多用,导致后期混乱不堪)

5、文档归类

同一功能或者同一类型方法或者对象,需要用文件夹同一依赖。

备注:开发过程中还有其他的约定规范,后面不断的迭代。

2.5、分层架构实现


先创建一个命名为“PFTSnailSystem”的空白解决方案,然后根据分层约束,我们将他们归纳为:CommonLayer、ModelLayer、BusinessLayer、DataLayer和PresentationLayer。为了给他们指定顺序,所以在他们前边加上编号。

如图:
<https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190913073839681-1113439082.png>

现在我们就将各层分别创建到指定的文件中。如图:
<https://img2018.cnblogs.com/blog/1764554/201909/1764554-20190913073840372-1200712516.png>


注意:创建类库一定选择standard框架。


其中,PFT.Snail.Core为业务方法库,PFT.Snail.Utility为公共方法库。其他的项目跟前面分层描述一一对应,并且都有单独的对应的接口类库。

三、总结


到目前为止,我们整理好了架构,架构方案的样子也在项目中有个轮廓了,虽然也存在着设计,但设计还没做完。其实对于设计是否完成,也是仁者见仁智者见智,设计可以详细到具体的UML类图。前面,我们虽然对每层做了规范限制,也说明了项目的使用的相关技术,但是都说得很抽象。因为设计的结果,就是项目的“规格说明”,而我们现在的都没有设计到项目需求,这个架构也可以适用到其他项目。所以后面我们将针对不同的功能模块,先做设计方案,然后编写实现设计方案,同时将逐步实现架构里面的基础功能。