大话 DTO、DAO 和 MVC:一家饭馆怎么接住一张订单
理解 HTML、CSS 和 JavaScript 时,我们常用三句话:HTML 是人的骨架,CSS 是人的衣服,JavaScript 是人的动作。画面一出来,概念就有地方放了。
DTO、DAO 和 MVC 也可以这样记。先别背全称,只看一家饭馆:
- MVC 是整家饭馆的分工图:谁给顾客看,谁接待,谁真正做菜。
- DTO 是服务员手里的订单小票:只负责把桌号、菜品和数量送进厨房。
- DAO 是仓库取货窗口的管理员:其他人说要什么,他负责从数据库拿出来或放回去。

先把这三个画面钉在脑子里,后面的英文只是给它们贴名字。
MVC:饭馆里的三种分工
MVC 是 Model、View、Controller 的缩写。
别急着记英文。把饭馆拆成三部分就懂了。
View 是给顾客看的菜单
顾客不需要进厨房,也不需要看仓库账本。他只需要看到菜单、价格和“下单成功”。
程序里的 View 也是一样:负责把东西展示给用户。
网页、按钮、订单列表,都可以属于 View。它不应该决定满 100 元减多少钱,就像菜单不会自己跑进厨房炒菜。
Controller 是接待顾客的服务员
顾客说:“来一份宫保鸡丁。”
服务员负责听清请求,把订单送到正确的地方,最后再把结果告诉顾客。
程序里的 Controller 也是一样:负责接收请求,再安排谁来处理。
它像交通指挥员,不应该自己切菜、炒菜、算库存。Controller 写得太胖,就像服务员站在桌边架起锅开始炒菜,分工已经乱了。
Model 是真正做事的厨房
厨房知道宫保鸡丁怎么做、库存够不够、这张订单总价多少。
程序里的 Model 负责业务数据和业务规则。订单、商品、价格计算、库存规则,都属于这个范围。
Model 不只是数据库。数据库更像仓库,Model 是知道怎样把食材变成一道菜的整套知识。
所以 MVC 用一句话说就是:
View 给顾客看,Controller 接顾客的话,Model 真正办事。

MVC 不是某三个固定文件,而是一种分工方法。不同框架的目录可能不一样,只要“展示、接收、办事”没有全挤在一起,它就在使用相近的思想。
DTO:服务员手里的订单小票
顾客说:“我是小陈,3 号桌,来两份宫保鸡丁,不要花生。”
服务员不会把顾客整个人扛进厨房。他只会写一张小票:
type CreateOrderDto = {
tableNumber: number
dishId: string
quantity: number
note?: string
}这张小票就是 DTO(Data Transfer Object,数据传输对象)。
它的工作只有一个:把这次需要的数据,从一个地方送到另一个地方。
DTO 像快递盒,不是仓库,也不是工厂。盒子里装什么可以检查,但盒子自己不会生产商品。
因此 DTO 可以规定“份数必须大于 0”“桌号格式必须正确”,却不应该负责计算会员折扣、修改库存或者写数据库。
为什么不直接把顾客的全部资料交给厨房?因为厨房只需要桌号和菜品,不需要身份证、家庭住址和账户密码。
DTO 的价值就是:只带该带的数据,不多带,也不少带。
DTO 不是数据库里的正式档案
订单小票和饭馆账本长得很像,但不是同一件东西。
小票是临时传话用的,可能只有桌号、菜品和数量;正式订单还会有订单编号、创建时间、付款状态和操作记录。程序里,前者是 DTO,后者常被叫作 Entity、Model 或数据库记录。
创建订单时可以用一张 CreateOrderDto,返回结果时也可以用另一张 DTO,只告诉页面订单编号和总价。这样既不会把密码等不该给的数据送出去,也不会让接口被数据库的内部结构绑死。
DAO:专门和仓库打交道的管理员
厨房收到小票后,需要确认食材够不够。
厨师不必知道鸡肉放在第几排,也不必亲自维护仓库账本。他只要问管理员:“还有鸡肉吗?”
管理员去仓库查完,再把答案带回来。
这个管理员就是 DAO(Data Access Object,数据访问对象)。它负责读取和保存数据。
const orderDao = {
findById(id: string) {
return database.orders.find(id)
},
save(order: Order) {
return database.orders.save(order)
},
}今天仓库用纸账本,明天换成电脑,厨师不用跟着重新学一遍。程序也一样:DAO 把 SQL、数据库连接和查询细节挡在里面,其他代码只管说“帮我查订单”或“帮我保存订单”。
但 DAO 不应该决定“会员打几折”。仓库管理员负责拿东西,不负责决定饭馆怎样做生意。
厨房可以要求“查一下这道菜还剩多少”,DAO 负责查询;至于库存低于几份就不允许下单,是厨房的业务规则。DAO 管数据在哪里,Model 管业务应该怎么办。
所以 DAO 用一句话说就是:
其他人只说要什么数据,DAO 负责去数据库拿。
一张订单怎样走完整家饭馆
现在把三者连起来。
顾客点击“下单”之后:
- View 把顾客填写的内容交出去。
- Controller 接住请求。
- 输入被整理成 DTO,就像写好订单小票。
- Model 按业务规则检查库存、计算价格。
- DAO 去数据库查询商品,再保存订单。
- 结果沿原路返回,View 告诉顾客“下单成功”。

注意,DTO、DAO 和 MVC 不是三个可以互相替换的方案。
MVC 是整家饭馆怎么分工,DTO 是部门之间传话时拿的纸,DAO 是其中一个专门管理数据进出的岗位。它们完全可以同时出现在一个项目里。
最后只记三句话
- MVC:饭馆的分工。
- DTO:传递信息的订单小票。
- DAO:专门去数据库拿东西的仓库管理员。
下次看到一段代码,可以先问三个问题:这是在接待用户、处理业务,还是读写数据?传过去的是不是只有对方需要的信息?数据库细节有没有被关在一个地方?
能回答这三个问题,DTO、DAO 和 MVC 就不再是三个缩写,而是一次很普通的点餐过程。