一点关于"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的反思,另一方面是对《企业应用架构模式》理解的深入。下一步的方向是将事务脚本的代码转变成为领域模型的形式,削弱业务逻辑对模型层的依赖,增加数据映射器的使用。

转载于:https://www.cnblogs.com/zhangjpn/p/8762802.html

MATLAB实战:用ARMAX模型搞定电力系统惯量评估(附完整代码) 本文详细介绍了如何利用MATLAB中的ARMAX模型进行电力系统惯量评估,解决新能源占比提高带来的系统惯量下降问题。通过系统辨识技术,从电网运行数据中准确提取惯量参数,并提供完整的代码实现,帮助工程师快速应用于实际工程。 阅读详情

相关推荐

Vivado 2021.1 实战:手把手教你用IEEE1735 V2加密你的Verilog源码(附完整TCL命令)

本文详细介绍了在Vivado 2021.1中使用IEEE1735 V2标准加密Verilog源码的全流程,包括许可证申请、密钥文件配置、TCL命令执行及加密后验证。通过实战步骤和完整TCL命令,帮助开发者有效保护FPGA设计知识产权,确保核心算法安全。

weixin_42706667的博客 191

腾讯FAT | 未来感知的多样化趋势推荐框架

“本文介绍了腾讯提出的一种未来感知的多样化趋势推荐框架FAT,根据相似用户的行为来构建未来序列,再通过动态路由学习多样化的趋势。实验表明,考虑了潜在未来偏好趋势的FAT不仅能够提升推荐的...

abcdefg90876的博客 1214

使用STC15F104W产生PWM脉冲

最近的小项目中使用到了STC15F104W产生PWM脉冲

yeats1989的专栏 1万+

什么是胖Model和瘦Model?

胖Model (Fat Model):在Model 中对数据根据需要进行处理,让Controller可以直接使用经过处理后的数据。 瘦Model(Thin Model):Model中的数据不进行任何处理或修改,原封不动的把服务器返回内容发送给Controller。 举例:后台服务器返回时间格式:yyyy-mm-dd hh:mm:ss,但客户端只需要显示yyyy-mm-dd, 在胖Mode

LVXIANGAN的专栏 2383

用Cloudflare Worker搭建你的私人Gemini Pro API

文章介绍如何通过开源项目gemini-cli-openai将谷歌Gemini模型转换为兼容OpenAI API的服务,解决Gemini CLI的三大使用障碍:网络访问、命令行操作和生态整合问题。部署流程主要包括获取Google OAuth2凭证、配置Cloudflare Worker项目并设置KV存储,最终可在CherryStudio等图形客户端中调用Gemini。该方法利用Cloudflare全球网络实现加速访问,同时保持认证信息安全可控。

Hsiao的二进制生活 1684

Pixel 4/4 XL 刷机小白必看:Magisk Root 全流程详解(附电信网络适配技巧)

本文为Pixel 4/4 XL用户提供了一份详尽的Magisk Root全流程指南。从解锁Bootloader、刷入Magisk,到解决电信网络VoLTE适配问题,再到隐藏Root以通过银行App检测,手把手教你安全获取系统最高权限并优化日常使用体验。

weixin_29310605的博客 266

[转]MVC之患上肥胖症的Controller

[转]MVC之患上肥胖症的Controller 转自:尘埃落定的blog,原文地址:http://www.lovelucy.info/fat-controller-bad-mvc.html#more-809,感谢作者~ 来这边负责做的一个项目,用了一个叫做Y...

adujy5846的博客 162

大数据分析工具Power BI(二):Power BI下载安装和模块介绍

首先在Microsoft官方网站上下载PowerBI Desktop,然后进行安装。id=58494点击"Next"后会弹出下载框,进行下载即可,下载好的PowerBI名称为"PBIDesktopSetup_x64.exe",也可以在"资料"中获取安装包,双击安装包即可安装。

Lansonli(蓝深李)的博客 2319

推荐系统遇上深度学习(一零五)-[腾讯]提升推荐多样性的推荐框架FAT

作为2021年的第一篇原创,首先祝大家在新的一年里身体健康,万事顺意。今天给大家介绍的是腾讯发表的一篇论文《Future-Aware Diverse Trends Framework f...

abcdefg90876的博客 1278

智驾芯片新天团!NVIDIA Thor vs 高通8797 vs 蔚来神玑NX9031,2025-2026谁能称王?

应用场景推荐芯片理由高阶NOA + L4 Robotaxi千TOPS以上,满足BEV+TransformerL2+/L3级别NOAThor-U / 高通8797算力适中,功耗控制佳,生态成熟经济型城市NOAThor-Z / S性价比均衡,适合前装普及自研平台一体化NX9031华为之外最强自研整合方案📌 TOPS不再是天花板,GPU、带宽、功耗、上市时间和车企绑定都是决胜关键📌 Thor系列仍然统治高端,但国产神经元开始觉醒📌 智驾芯片的选择,从“强”走向“适合场景”

weixin_43199439的博客 2647

QGIS编译(跨平台编译)001:Flex、Bison编译(安装)(Windows、Linux、MacOS环境下安装)

QGIS编译;Flex、Bison编译(安装)(Windows、Linux、MacOS环境下安装)

LuckyHanMo的博客 3080

[转]Skinny Controller, Fat Model

不错的文章,出处:[url]http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model[/url] When first getting started with Rails, it is tempting to shove lots of logic in the view. I’ll admit that I was ...

简单就是美 263

python全栈入门到实战【基础篇 02】环境搭建:Python解释器与PyCharm、VSCode编辑器安装配置详解

本文详解Python环境搭建步骤。首先安装解释器(运行代码核心),需从官网下载,选3.8及以上版本(勿选2.x)。Windows安装必勾“Add Python.exe to PATH”,验证用`python --version`;Mac选universal2安装包,验证用`python3 --version`。 编辑器二选一:PyCharm社区版(免费,新手推荐),安装后需配置解释器路径;VSCode轻量,需装Python插件并选择解释器。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 5万+

ASP.NET MVC Model

ASP.NET MVC中的Model是应用程序的主要数据源 Model模型是程序中的数据,Model本身并不属于个别应用程序,在大中型应用系统的设计上,Model并不只归属于某个应用程序,而是特别将Model剥离到架构层面上,让Model可被大部分应用程序所共享,并在Model和实际数据源之间插入一个中介层,由中介层负责与数据源进行互动,而不必担心数据源的数据管理与读写方式,这...

JunChow 637

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Rails: 通过模型中添加Vitrual Attribute精简控制层代码

最近在看Rails Best Practices网站上的文章,虽然文章发布的时间比较久远(最后一篇是4年前发布的),但里面仍然有大把干货,打算把他们逐个过一遍,顺道会在这里翻译记录一下,有兴趣的同学可以持续关注哈。 坏味道的代码 视图层 form_for @user do |f| %> text_field_tag :full_name %> end %>

qwbtc的博客 403

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

富model,瘦controller

很久以前看过的一篇文章。挺简单,不过这种思想很重要。简单的复述,也不能完全算翻译。 原文地址:[url]http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model[/url] ----先看这么一段rhtml代码:渲染模板中加入了这么多的逻辑,看起来不伦不类,这么做行是行,但是缺点很多,新手一般有这个毛病。那么这样做,

u011345213的专栏 574

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

ruby on rails 框架笔记

Ruby On Rails框架介绍 下文都是对上面这个文章的一个感想. Ruby on Rails, often shortened to Rails, is an open source full-stack web application framework for the Ruby programming language. Ruby on Rails is not to b

Kay's space 1581

rails最佳实践 --codeschool笔记

为什么80%的码农都做不了架构师?>>> ...

weixin_34006965的博客 534

FAT:一种快速的Triplet Loss近似方法,学习更鲁棒的特征表示,并进行有噪声标签的提纯...

点击上方“AI公园”,关注公众号,选择加“星标“或“置顶”导读Triplet的两大问题,计算复杂度和噪声敏感,看看这篇文章如何用一种对Triple的近似的方法来解决这两大问题。摘要三元组...

AI公园 752

瘦controller,富model

----先看这么一段rhtml代码:渲染模板中加入了这么多的逻辑,看起来不伦不类,这么做行是行,但是缺点很多,新手一般有这个毛病。那么这样做,首先是可读性很差,因为在渲染代码中最好都是贴近HTML代码,而这堆代码里把C的内容也加进来了。 [code="java"] ["added_at > ? and deleted = ?", Time.now.utc, false], ...

冰醇小馆 187

Spring Boot 数据源与 MyBatis(-Plus) 自定义配置详解

本文详解 Spring Boot 中单数据源环境下 HikariCP 与 MyBatis-Plus 的自定义配置。通过手动声明 SqlSessionFactory,实现下划线转驼峰、日志输出、一级缓存策略等精细化控制。结合 HikariCP 核心参数调优(如最大连接数、连接生命周期),确保高性能与稳定性。适用于仅需访问单一数据库的场景,避免多数据源复杂性,兼顾性能与可维护性。

BADAO_LIUMANG_QIZHI的博客 206

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)

要努力去发光,而不是被照亮~ 142

Docker Compose:搭建本地多服务开发环境

从一个 Java API、PostgreSQL 和 Redis 开始,配置服务名、端口、环境变量、健康检查、数据卷和依赖关系。理解 Compose 文件如何被解析、项目如何隔离,以及哪些数据不能依赖“重建容器”保留,能够把个人开发环境整理成团队可复用的启动入口。

m0_62221377的博客 462

AI全栈实战 | 3.9-01 爬虫入门:requests 加 BeautifulSoup 三分钟跑通,但 90% 的人栽在这 4 个“礼貌“问题上

⚠️:本文内容仅用于。请遵守目标站点的服务条款与相关法律法规,不得对目标服务造成负担,不得采集、传播个人隐私数据。技术是中性的,边界在你手里。爬虫的入门技术(requests 发请求 + BeautifulSoup 解析)三分钟就能学会。真正区分"会用爬虫"和"会做爬虫的人"的,是这篇我们跑通"请求→解析→存储"的最小闭环,然后重点把"合规与礼貌"这根弦给你绷上。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 420

数据库主键选型指南:BIGINT vs VARCHAR

主键选型关乎数据库性能与架构演进。BIGINT(如雪花算法)在顺序写入、二级索引开销和分布式生成上优势显著,适合高并发核心链路;而传统 VARCHAR UUIDv4 因随机性导致频繁页分裂、存储膨胀,性能堪忧。UUIDv7 通过时间戳有序性实现高效追加写入,结合 BINARY(16) 存储可兼顾性能与安全,成为现代微服务新选择。关键在于:主键应稳定、无业务含义,优先选用趋势递增的紧凑类型,并根据场景合理采用双主键模式或 ULID 等替代方案。

小李同学的博客 306

【基于 WebSocket 的多用户网页五子棋】—— 数据管理模块

但行好事,莫问前程

qq_42996461的博客 220
上一篇: flask+gunicorn中文文件下载报错问题及解决
下一篇: python日志模块笔记
dinght2000
博客等级 码龄11年 3粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值