前面用5个章节介绍了单例模式和工厂系列模式,这个过程中,如果算上网站开发人员的表示层,那么项目经历了二层多层的演变:

数据访问层+表示层 =》

数据访问层+业务逻辑层+Client层+表示层

至此,这个系列中对创建型设计模式的介绍也到此为止了。后面的文章,我们会把关注点放到具体的代码实现上,比如层与层之间如何调用,工厂模式与抽象工厂在代码实现上的异同等等,这里面会涉及到很多结构型设计模式相关的知识,由于代码架构变得愈加复杂,也只有请结构型设计模式来救场。

那有人要问了,既然提升了系统复杂度,为什么要使用多层架构?

什么是三层架构?

为什么要用三层架构?

为了达到“高内聚,低耦合”的程序设计思想,引入了三层架构,在表现层和业务层分离开来,再加上数据访问层,便形成了今天的三层架构。

没错上面又是百度百科的解释,虽然这个答案简练得连面试的要求都达不到,但无疑是百分百正确的答案,没有掺杂任何个人理解的回答。初学者最不喜欢的就是这种答案,他们更喜欢的是富有个人强烈感情色彩的解释,即使偏激。

来看掺杂了笔者个人理解,详细到能应付面试的解答:

要回答这个问题首先要知道什么是一层架构和二层架构

一层架构:只有一个表示层

二层架构: 第一层:表示层

第二层:数据访问层

没错,一层架构就是只有一个表现层的架构。您可能会有疑问:只有一个表示层,怎么可能?

这里以后OA系统的用户模块为例,给一个5-10人的小公司用,只需要一个管理员账户,用户名密码都是admin,所有人都用这一个账号登录,代码里写死就可以了,业务逻辑就是登陆的时候判断  if(username=="admin"&&pwd=="admin")。

是的,你没有任何理由来批判一层架构的缺点,因为架构本身并没有缺点,只有适不适合。只是一个显示"Hello World"的功能,是不需要分什么层的,当然,如果非要有云"Hello World"这种需求,那就不好说了。

后来,使用OA的公司慢慢做大,成了几百人的公司,OA系统需要增加考勤模块作为主打功能,这意味着每个员工都需要一个用户名来做考勤,而admin则负责管理用户。我们需要在数据库添加用户表和门禁表。

管理员可以通过表单编辑用户表中的性别、出生日期和照片,用户只能编辑部分个人信息(照片和个性签名)

管理员修改用户信息

[Authorize("admin")]
[HttpPost]
public ActionResult AdminEdit(User entity)
{using(var context=new DBContext()){var user = context.Users.Where(d => d.id == entity.id).FirstOrDefault();user.sex=entity.sex;user.birth=entity.birth;user.photo=entity.photo;if(context.SaveChanges()>0){...}....}
}

用户修改个人信息,我们把上面的代码copy过来,略加修改就可以了。

[Authorize]
[HttpPost]
public ActionResult UserEdit(User entity)
{using(var context=new DBContext()){var user = context.Users.Where(d => d.id == entity.id).FirstOrDefault();user.photo=entity.photo;user.sign=entity.sign;if(context.SaveChanges()>0){...}....}
}

表示层中多个用户表的编辑操作,造成了代码的重复,重复是远比坏味道还要严重的多的问题,我们修要提供一个通用的修改用户信息的方法来优化代码:


private bool UpdateUser(User entity,params string[] columnNames)
{...do Update...
}[Authorize("admin")]
[HttpPost]
public ActionResult AdminEdit(User entity)
{//如果编辑成功if(UpdateUser(entity, "sex", "birth","photo")){...}
}[Authorize]
[HttpPost]
public ActionResult UserEdit(User entity)
{//如果编辑成功if(UpdateUser(entity, "photo","sign")){...}
}

 一层架构为解决数据库操作造成的代码重复,不断地提供的通用方法,他们分散在表示层中的各个角落,这便是数据访问层的原型。

二层架构将这些通用方法抽离成数据访问层:

[Authorize("admin")]
[HttpPost]
public ActionResult AdminEdit(User entity)
{//如果编辑成功if(new UserDal().Update(entity, t => t.id == entity.id, "sex", "birth","photo")){...}
}[Authorize]
[HttpPost]
public ActionResult UserEdit(User entity)
{//如果编辑成功if(new UserDal().Update(entity, t => t.id == entity.id, "photo","sign")){...}
}

所以,对于高质量的代码下的一层架构来说,重构成二层所带来的改变仅仅是把对数据库的通用方法拿出来,换个地方而已,并没有其他任何复杂的改动。

{{

【能够通过sonar代码质量检查的一层架构】 VS 【能够通过sonar代码质量检查的二层架构】

优点:代码好找(管理)了,以前是在本模块里找,现在是在本模块的某一层里面找,利于分工,使开发人员可以专注于某一层。

缺点:维护起来变麻烦了,每次改动需要提交的文件变多了

具体要不要重构,看项目实际情况和个人喜好吧

----------------------------------------------------------------------------------------------------

【能够通过sonar代码质量检查的一层架构】 VS 二层架构

毫无疑问,二层架构会被完爆!!!为什么?因为只要是能够通过sonar代码质量检查的一层架构重构的二层架构,只是把代码换了个位置,略加修改,肯定通过sonar代码质量检查的。

所以【能够通过sonar代码质量检查的一层架构】就约等于【能够通过sonar代码质量检查的二层架构】

如果连一层架构的代码都组织不好,何谈二层?

}}

-----------------------------------------------------------------------------------------------------------------------

如果后面项目需求变得更加复杂,业务规则、合法性校验等业务逻辑增多,高质量代码下的一层架构肯定是提供了很多业务逻辑的通用方法,因此

高质量代码下的一层架构可以随意的重构到二层和三层,物理文件的增加,代码位置的变动,仅此而已。

所以呢,人们都说高手所见略同,模块到了他们那群高手的手中,虽然在物理上并没有分层,但是分层的思想已经随处可见了。独孤求败草木竹石皆可为剑,就是这个道理。

但是正如三国演义里,吕布说过:“我有赤兔马方天戟,过河如履平地!”,这个时候陈宫说:“你有赤兔马,你当世无敌,但是将士们不行呀!”

你不能要求所有人都有那么高的水平,笔者去年参加的项目,也是多层架构,要求是代码合格率达到60%就可以了,当时写代码就跟应付考试似的,实在是能力有限,但是进度赶得紧。

要记住,是因为通用方法的出现才不得不在物理上分层,而不是分层之后,才去写通用方法。如果一开始你分层的目的是妄图通过分层达到变相的约束程序员去写通用方法的做法,是很难实现的。

真正起到一些作用的是接口,是设计模式。我接口里声明了这些方法,你就必须去实现,而且要调用这些通用方法也只能通过接口,而设计模式来决定接口到底如何设计,我单层架构也可以用抽象工厂模式,你管我放哪儿干嘛?我就是把所有的接口和类全写一个文件里它也是抽象工厂模式。

面试问题:

什么是三层架构:

从三层架构的视角来看一层和二层:

一层架构:包含复杂数据库操作和业务逻辑的表示层

二层架构: 第一层:包含复杂业务逻辑的表示层

第二层:数据访问层

为了达到“高内聚,低耦合”的程序设计思想,引入了三层架构,将表现层和业务层分离开来,把业务规则、数据访问、合法性校验等通用方法都放到了中间层进行处理,再加上数据访问层,便形成了三层架构。

三层架构的优缺点:

【能够通过sonar代码质量检查的一(二)层架构】 VS 【能够通过sonar代码质量检查的三层架构】

【能够通过sonar代码质量检查的二层架构】 约等于【能够通过sonar代码质量检查的三层架构】只是通用方法位置不同。

优点:代码好找(管理)了,以前是在本模块里找,现在是在本模块下的某一层里面找,利于分工,使开发人员专注于某一层。

缺点:维护起来变麻烦了,每次改动需要提交的文件变多了

【能够通过sonar代码质量检查的一(二)层架构】 VS 【三层架构】

没有可比性,架构本身并不能解决代码质量的问题。

真正起到一些作用的是接口,是设计模式。设计模式通过接口约束必须实现哪些方法,层与层之间只能调用通过接口中声明的方法。这在某种程度上是一种限制,但并不影响我在具体的实现该方法的代码里,究竟干了什么。

跟着项目学设计模式(六):三层架构相关推荐

  1. mvc设计模式与三层架构

    mvc与三层架构  1.什么是mvc设计模式 写Java Web项⽬时会发现,一个中型或者大型项目随着代码的增多,会发现:代码既可以写在src目录下,也可以写在WebContent目录下. src下可 ...

  2. 跟着别人学设计模式-----(一)单例模式详解

    作者:zuoxiaolong8810(左潇龙),转载自:http://www.cnblogs.com/zuoxiaolong/p/pattern2.html 上一章,我们学习了设计模式的概念,以及为什 ...

  3. Nancy跨平台开发总结(六)三层架构之Token认证的Rest API

    在开始写本节内容前,我使用Nancy.Authentication.Token实现的Token认证,但是就在我开始写本节内容的时,我看到Nancyfx的文档中的内容更新 所以我改为使用Nancy.Au ...

  4. 跟着项目学sql(二) 三大范式

    序号 表名 说明 1 permission 权限表 2 user 用户表 3 menu 栏目表 4 news 新闻表 5 clicks 浏览信息表 ER图如下,并没有创建外键约束,因此本文中所有的外键 ...

  5. 【跟着项目学CSS】第一期-闪动LOGO

    最近期末比较忙,没有上CSDN,没有回大家私信[非常对不起]. 进阶版JavaScript下周更新. 今天先浅浅学习一下CSS样式. 22 1.body代码 <body><div c ...

  6. 跟着项目学sql——查询语句优化(一)

    现阶段,笔者的环境中只有SqlServer和Oracle.所以后面的文章更多的会以SqlServer的背景来做了. 来看这样一张表WorkLink: WorkLink表结构 WorkLink表数据,现 ...

  7. 物流快递系统前、后端+Java语言+SpringBoot项目+MVC三层架构+maven+Mysql+Tomcat+可以用于学习SpringBoot项目入门

    物流快递系统前.后端+Java语言+SpringBoot项目+MVC三层架构+Mysql+Tomcat+可以用于学习SpringBoot项目入门 可以用于课程设计.毕业设计的知识点入门学习 提示:此资 ...

  8. Java-GUI编程实战之管理系统 Day1【项目开发流程、软件三层架构、项目需求、项目结构分析】

    视频.课件.源码[链接:https://pan.baidu.com/s/13ffqGDzH-DZib6-MFViW3Q 提取码:zjxs] Java-GUI编程实战之管理系统 Day1[项目开发流程. ...

  9. 浅谈三层架构 通过这个,+Java开发模式经验。终于相通了,动软到底是为什么这么做...

    浅谈三层架构 收藏 自己理解的原理 http://www.cnblogs.com/mahaisong/archive/2011/05/12/2044665.html 浅谈三层架构  通过这个,+Jav ...

最新文章

  1. Docker 图形化页面管理工具使用
  2. 计算机视觉这篇就够了
  3. 架构师之路 — 分布式系统 — 分布式事务难题
  4. BST | 1064 完全二叉搜索树
  5. web 应用常见安全漏洞一览
  6. cocos2dX改变锚点位置
  7. 87岁老奶奶用微软自带画图软件绘画 惊艳了世人
  8. MTD/MT/MDD/MD以及LIB/DLL之间的一些联系和问题
  9. c语言插入排序算法_插入排序算法,流程图和C,C ++代码
  10. olap 多维分析_OLAP(在线分析处理)| OLAP多维数据集和操作
  11. Fences桌面图标分类
  12. erp生产管理系统流程_仁和ERP生产制造业ERP管理系统库存管理
  13. 基础:新建个maven项目
  14. 获取Bootcamp 6 下载地址(mac装win10)
  15. CBR编码与VBR编码
  16. UVA 12307 旋转卡壳
  17. Docker 安装MySql后创库、创表
  18. linux切换桌面的快捷键,SUSE Linux Gnome桌面快捷键整理
  19. 羊了个羊, 听说这游戏很难
  20. SVN_Windows安装Subversion(svn 命令行工具)教程

热门文章

  1. centos7部署calamari
  2. Ceph监控部署之inkscopeCalamari(v10.2.11)
  3. 计算机网络的一些小知识
  4. 三国经典战役\三国合肥会战\三国孙权大战张辽\三国孙权一败张文远
  5. 电脑时间调到2099年,会发生什么
  6. 在WIN10下通过网口给华为海思Hi3516DV300刷机(鸿蒙系统)
  7. 升级IOS百度人脸SDK4.0采坑记录
  8. ROS | 基于MQTT的通信方式mqtt_bridge
  9. win7 安装openssh_05、Win7上openSSH的安装与配置
  10. 大厂面试:一个四年多经验程序员的BAT面经(字节、阿里、腾讯)