web开发MVC结构扩展,更加合理的代码分层

原文链接

传统MVC存在的问题

web开发中MVC已经是一个常见的结构了,然而对于稍微复杂的项目还是有一些问题:

  1. 业务代码写在model层,导致model越来越臃肿,新旧业务、不同场景杂糅,越来越难以维护。
  2. 复杂业务同时设计多个model(多张表),到底应该放在哪个model里?
  3. 网上有的说MVC导致代码难以测试什么的,其实并不是这样,代码写在model里和写在service里都是可以单元测试的。这里主要还是写在model里太臃肿的问题(第1点)
  4. 代码复用的问题。
    一般model都是orm映射数据库的,所以在这里写完的代码是直接进出数据库的。那么问题来了,如果我在不同的场景对数据进行不同处理呢?比如:自己可以看自己的手机号,别人看到的是加密后的手机号。为了安全问题,需要在后端就加密好再传到前端,那么这个加密我就只能写在controller里。那么需要在另一个接口看到自己的手机号呢?是不是得再写一遍?当然这只是一个很简单的场景,有更好的例子欢迎补充。

更合理的代码分层

接下来说说为了解决上面的问题,我个人在代码结构上总结的方法:
通过添加service层、repository模式、transform层,结合原有的MVC,来保障代码的复用、隔离、稳定、可测
下面按照重要性倒序介绍~

1.【必须】MVC

这里重新界定一下:

  • controller层用于接收用户数据、进行简单的数据处理。至于数据校验,有的框架在controller里,比如laravel的表单验证,而yii2是直接将验证规则放在了model里,所以不一概而论。
  • model层不再写任何业务逻辑,仅作为数据库访问层(DAO)使用,包括:
    1. 数据表字段映射
    2. 数据表关联关系映射

2.【必须】service业务层

这个service不是框架中抽象的service(不是service provider的service,也不是service locator的service),而是指实际业务的那个service。比如,处理订单的业务层,就是OrderService.
service层用于写业务逻辑,比如电商网站下订单功能,本质上就是订单表增加一条数据,然而业务上却连接着库存、购物车、销量等等等等。这种涉及了多表操作的,单独放在哪个表里都不合适。那么就放在service层,在OrderService中写一个createOrder()方法,保证所有的下单操作都调用这个方法即可。

3.【推荐】repository查询层

这一层封装了查询数据的方法,介于model和controller中间,使用repository封装好常用的查询,会让controller感觉不到model的存在。
使用前:查询时经常要select字段,或者做字段判断,用字符串手写,但是字符串这个东西,用起来一时爽,重构火葬场。当我需要修改某字段或修改查询条件时,只能全文ctrl f + 人工识别,对着自己写的一行行代码无语凝噎。
使用后:因为提前封装在了repository层,所以之后查询、select用这一层的方法,重构就根本不是问题。
当然了,如果项目或者功能比较简单,没有太大的必要用这一层.

4.【推荐】transform层

这一层主要是对model层取出的数据做一些转换,controller调用repository层获得原始数据库数据,再交给transform层根据业务要求转换数据。

关于过度设计

这个问题还是要回到实际项目来说,如果是简单的项目,MVC就足够了,但是如果是电商类复杂一些的项目,做更合理的代码分层是非常必要的。
首先,这种设计能够应对所有复杂情况,其次,每层的职责分明,就算是刚上手项目的程序员了解了也能够快速掌握。否则把所有业务揉在一坨if else里,读起来就像拆积木,维护的难度更大。

这样的优点

  1. 代码可测部分更全面,写完了心里更有底
    现在的代码结构除了controller都可以测试,当然不必每个都写单元测试,但是针对一些复杂的情况,比如搜索附近的美食信息这个功能,是关键字搜索+距离排序,我就为repository层对应的方法写一个测试实例,就算以后业务变动也能够保障这个方法没有问题。
  2. 代码结构更加清晰,职责更加单一。
    面向对象开发的原则之一就是职责单一,一个类只负责一个职责。
    想象有一天,产品经理突发奇想让你开发一个奇葩的新功能,这时候,有两个选择在你面前:1.把这些奇葩功能继续放在之前的类里,让它们和正常功能傻傻分不清楚;2.建一个QiPaService专门做这些需求,等到产品经理清醒过来,一键delete就完事。
  3. 把更多的注意力关注在业务实现上,而不是怎么代码怎么写上。
    脱离实际业务谈开发等同于纸上谈兵,学会了《电商开发》课程实际上手时也还是会遇到问题,因为业务一直有新的需求,功能也需要迭代。所以我们的重点就是把业务封装在service这个黑盒里,在快速开发阶段也不必太过纠结service实现的是否完美,等到项目稳定的时候再来进行优化重构即可(然而大多数功能听不到优化就删改了)。

这样的缺点

虽然我自己一直在用这一套代码结构,但是我还是不得不承认它的一些问题:

  1. 降低性能(虽然在我看来可以忽略不计)
  2. 代码结构复杂,代码工作量大
    写得代码越多就越累,也越容易犯错,想象我们每写一个功能都要建一个controller、一个model、一个repostiroy、一个transform、一个service是一种什么样的体验?
    我个人很讨厌重复无意义的事情,所以在经历了一段时间上述的折磨后,我找到了很好的解决方案,将在下一篇介绍下我的独(tou)家(lan)方法~

最后,文中涉及的内容都是我的个人总结,可能会有一些问题,欢迎交流指正!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容