一点关于"fat model, skinny controller"的思考
导言
想来从事服务器端开发也有将近一年的时间,服务端开发不能忽略的一个架构就是MVC架构,但一开始作为小白的我对这些高大上的概念也是很迷惑,由于很长一段时间应对的业务也是十分简单,业务代码也是流水一样的代码,所以对架构方面的东西接触也不是很多。
而随着过去几个月应对的业务越来复杂,越来越觉得脚本一样的模式写起来非常吃力。
思考
此前用flask和nodejs写过一些接口,这些代码一直是这样的:
# flask
from flask import Flask
app = Flask(__name__)
@app.route('/api/path')
def get_path():
    # do something
    return jsonify({'code':'0'})
// NodeJS express框架
var express = require('express');
var app = new express();
function dosomething(){
    // do something
}
app.route('/api/path').get(dosomething);
以NodeJS express框架搭建的项目为例,项目目录结构只有两层:
app/
    |-- users/
        |-- user.model.js
        |-- user.controller.js
        |-- user.routes.js
    |-- products/
        |-- product.model.js
        |-- product.controller.js
        |-- product.routes.js
其中*.model.js就是对应的是一个数据库的表,*.routes.js文件定义路由,*.controller.js定义了所有的业务逻辑。这种结构一开始工作良好,但随着需求增加,接口代码不断增加,上述每个*.controller.js的代码量急速增加,部分甚至达到一万多行,而且里面基本就是一个接口对应一个函数,每个函数里面就是各种通过对数据库的增删改查操作。
如果只是代码量增多那可以接受,问题是业务需求经常改动,经常牵一发而动全身,此外还要考虑版本的兼容性。有些接口功能、逻辑基本上一样,只有细微的差别,但就是这一点点差别不得不另外再写一个类似的函数,造成代码大量冗余。
几经寻找找到一个思路,就是"fat model,skinny controller",它的观点是将部分的业务逻辑放到数据模型中定义,作为数据模型类的方法。这对我来说是一种新的尝试,因为使用这种代码编排方法意味着很多类似的代码可以放到model中,从而分担controller的负担。而NodeJS项目中使用的mongoose本身就提供了许多现成的方法。
然而使用了一段时间之后我发现,一个业务操作往往涉及了多个模块的数据库操作,*.model.js因此引入了大量其他模块中的模型,这样的结果反而更加复杂,严重的时候甚至出现了循环引用的问题:一个功能逻辑上本应该属于模型A,然而由于这个功能需要引用模型B,而B模型在其它功能上又引用了模型A。结果就是很多模型相互缠绕在一起。
偶然看到一篇文章,里面指出,"fat model,skinny controller"的分工不是一个好主意,虽然它相比于"fat controller"有优势,但并好不了多少。因为随着功能的增加,开发者不得不将所有的代码放到少数的几个类中,最终造成所谓的"god object",也就是上帝对象,一个用数千行代码来定义的类实例。
最近在读《企业应用架构模式》这本书,书中总结的一些架构模式启发了我不少。
其中有一部分专门讲数据源架构模式,讲的是业务逻辑应当与数据源适当地隔开。复杂的业务逻辑往往需要隔离数据源层。这一定程度体现了"一个类只做一件事并把它做好"的原则,也就是关注点分离。"fat model,skinny-controller"的模式的问题在于,一个模型既扮演了数据读写的功能又承担了作为业务逻辑主体的角色。这不符合书中提出的分层原则。
前面的文章也指出,我们应当突破框架的局限,突破mvc这种设计模式的限制,使用更多的类取更好地组织你的代码。
重读这篇文章收获颇多,一方面是对fat model的反思,另一方面是对《企业应用架构模式》理解的深入。下一步的方向是将事务脚本的代码转变成为领域模型的形式,削弱业务逻辑对模型层的依赖,增加数据映射器的使用。
一点关于"fat model, skinny controller"的思考的更多相关文章
- MVC(Model View Controller)框架
		
MVC框架 同义词 MVC一般指MVC框架 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一 ...
 - MVC模式(Model View Controller)下实现数据库的连接,对数据的删,查操作
		
MVC模式(Model View Controller): Model:DAO模型 View:JSP 在页面上填写java代码实现显示 Controller:Servlet 重定向和请求的转发: 若 ...
 - 深入浅出Java          MVC(Model View Controller) ----     (JSP + servlet + javabean实例)
		
在DRP中终于接触到了MVC,感触是确实这样的架构系统灵活性不少,现在感触最深的就是使用tomcat作为服务器发布比IIS好多了,起码发布很简单,使用起来方便. 首先来简单的学习一下MVC的基础知识, ...
 - Model View Controller (MVC) Overview
		
By Rakesh Chavda on Jul 01, 2015 What is MVC?Model View Controller is a type of user interface archi ...
 - Model View Controller(MVC) in PHP
		
The model view controller pattern is the most used pattern for today’s world web applications. It ha ...
 - What is the difference between Reactjs and Rxjs?--React is the V (View) in MVC (Model/View/Controller).
		
This is really different, React is view library; and Rxjs is reactive programming library for javasc ...
 - Go语言根据数据表自动生成model以及controller代码
		
手写model的用法请参考: https://www.jianshu.com/p/f5784b8c00d0 这里仅说明自动生成model文件的过程 bee generate appcode -tabl ...
 - AngularJS开发指南11:AngularJS的model,controller,view详解
		
model model这个词在AngularJS中,既可以表示一个(比如,一个叫做phones的model,它的值是一个包含多个phone的数组)对象,也可以表示应用中的整个数据模型,这取决于我们所讨 ...
 - 设计模式 --- 模型-视图-控制器(Model View Controller)
		
模型-视图-控制器(Model-View-Controller,MVC)是Xerox PARC在20世纪80年代为编程语言Smalltalk-80发明的一种软件设计模式,至今已广泛应用于用户交互应用程 ...
 
随机推荐
- 项目启动报错: No naming context bound to this class loader
			
发步项目到本地tomcat,启动后,一直包错: 警告: Failed to retrieve JNDI naming context for container [StandardEngine[Ca ...
 - 福大软工1816:Alpha(3/10)
			
Alpha 冲刺 (3/10) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.学习qqbot库: 2.实 ...
 - 【UML】活动图介绍
			
1.活动图,即Activity Diagram,是UML中用于对系统的动态行为建模的一种常用工具,它描述活动的顺序,展现从一种活动到另一种活动的控制流.其本质上是一种流程图,着重表现从一个活动到另一个 ...
 - microtime()
			
PHP函数microtime()返回当前 Unix 时间戳和微秒数.
 - 【bzoj3813】奇数国  线段树
			
题目描述 给出一个长度为n的序列,每个数都可以由前60个质数的乘积表示,初始每个数都是3.支持两种操作:(1)修改一个数 (2)查询一段区间内所有数的乘积的欧拉函数值模19961993. 输入 第一行 ...
 - 这次OpenSSL HeartBleed漏洞是怎么一回事呢?
			
“心脏出血”(Heartbleed)被称为互联网史上最严重的安全漏洞之一,波及了大量常用网站.服务,包括很多人每天都在用的 Gmail 等等,可能导致用户的密码.信用卡轻易泄露.但是我们可能对它还不是 ...
 - 理解JavaScript的function
			
JavaScript中最有特色而又让你困惑的function算一个了,下面看一下常用操作: function doit(){ ..... } doit(); JavaScript中的函数我们可以把它当 ...
 - 门户系统整合sso cookie共享及显示用户信息
			
1.1 门户系统整合sso 在门户系统点击登录连接跳转到登录页面.登录成功后,跳转到门户系统的首页,在门户系统中需要从cookie中 把token取出来.所以必须在登录成功后把token写入cooki ...
 - 如何开始创建第一个基于Spring MVC的Controller
			
万事开头难,良好的开端是成功的一半! 以下示例怎么开始创建我们的第一个Spring MVC控制器Controller 1.新建一个java类,命名为:MyFirstController,包含以下代码, ...
 - C#语法糖大汇总【转发】
			
首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕不已,呵呵. 1. ...