Clean架构分层太多DTO垃圾满天飞:眼前干净背后脏

说实话,每次看到那些明明一个简单功能却硬要套上十几层架构的项目,我就忍不住想吐槽——这到底是写代码还是搞官僚主义?DTO(Data Transfer Object)说白了就是个数据搬运工的小纸条,但在某些项目里它愣是被捧成了圣旨。比如你只是想从服务层拿个用户信息,本来直接返回一个JSON对象就完事了,结果非要先定义个UserDTO,再搞个UserVO,最后还要经过三四层转换才能到前端。我就纳闷了,你们公司是开数据加工厂的么?这么爱折腾数据包装?更搞笑的是有些项目总共就五六个接口,全是增删改查,结果架构图上画得跟操作系统内核似的,从Controller到Service再到Repository,中间还夹着DTO、VO、DO、PO,知道的以为在写业务代码,不知道的还以为在搭建联合国数据交换中心呢!

说到底,这些过度设计的架构90%都是为了装X——怕别人觉得自己不够"专业",所以赶紧把Spring全家桶能用的设计模式全堆上去。你说DTO有用吗?在真正复杂的分布式系统里确实有用,它能规范数据格式、避免敏感字段泄露。但你们那个破后台管理系统,访问量还没我家路由器高,搞这么多层抽象是图啥?每次新加个字段都得改五六个文件,这不是写代码,这是在玩大家来找茬吧?最讽刺的是,那些号称"高扩展性"的架构,等到真需要改需求的时候,改起来比屎山代码还费劲,因为光理清楚这些DTO、VO之间的关系就得花半天。

我现在算看明白了,Java圈子里这些所谓的"最佳实践",有一大半都是被"简历驱动开发"逼出来的——不用点设计模式怎么体现我年薪百万的水平?不搞点架构分层怎么证明我精通"企业级开发"?结果就是简单的事情复杂化,把"用户登录"这种功能写得跟银行跨境转账一样严谨。要我说啊,写代码就该像说话一样自然——你想表达什么就直接说,别动不动就"根据SOLID原则,这里应该增加一个抽象层",累不累啊?Python和JS开发者看到Java这些套路估计都笑疯了:人家传个字典就搞定的事,你们非要搞出七八个类,这不是自己给自己挖坑么?当然我不是说架构不重要,但得看场景啊!你要是做个淘宝级别的系统,那确实得严格分层;但你要就做个公司内部用的报销系统,还整这套花里胡哨的,那不是脱裤子放屁么?



但等等,也有人出来劝架(理性补刀版):

哎,兄弟,我懂你气得牙痒痒。  确实,很多小项目里,一堆人拿着“整洁架构”当圣经,  不管三七二十一,上来就建七八个包:  controller、service、repository、dto、vo、bo、po、dto2voConverter……  搞得像在开发火箭发射系统,结果实际需求只是做个计算器。

这些“设计模式”本来是好心人总结的经验,  是为了解决大项目里的复杂问题,比如:  
- 多个前端(网页、APP、小程序)要不同格式的数据  
- 安全不能把数据库字段全暴露出去  
- 团队太大,得靠“契约”避免互相改崩  

结果现在呢?  小团队三个人开发个内部管理系统,  也非要搞个“DTO层”,  搞得代码像俄罗斯套娃——打开一层,还有层,再打开,还有!  最后找一个字段得花半小时,人都绕晕了。这就叫:杀鸡用牛刀,还把刀供起来天天拜。

但反过来,如果真遇到复杂系统,  比如你这个接口要同时给APP、网页、第三方API用,  每个要的数据还不一样,那你搞个DTO,  就等于“定制化打包”,谁来拿数据,就给谁发对应版本的“小纸条”,  这时候DTO就不是累赘,而是救星。

所以关键不是“DTO好不好”,  而是:你现在是住茅屋,还是盖摩天大楼?你家就一间房,非得在门口加个“接待大厅”、“安检通道”、“访客登记处”?  
——纯属添乱!  但你要建个五星级酒店,那这些流程就有用了。



上下文决定一切

你有没有见过那种人——  穿个西装,打着领带,拎着公文包,  大夏天40度,非得去楼下买个冰棍,  还得先递名片,说:“您好,我是消费者张三,现正式申请购买绿豆冰棍一支,烦请受理。”你一看就想笑:  “哥,就买个冰棍,至于吗?”这事儿听起来离谱吧?  可很多程序员干的事,就跟这差不多。


一、上下文!上下文!上下文!重要的事说三遍!

我们吐槽的不是“DTO”这玩意儿本身,  也不是“整洁架构”、“设计模式”这些词有多坏,  而是——你得看场合啊!

就像你去学校升旗,穿校服是应该的;  但你要去游泳,还穿着校服下水?  那你不是讲礼貌,你是不会变通。写代码也一样。



二、小项目?别整花活!

你做个班级花名册管理系统,就五个页面:  添加学生、删除学生、修改电话、查成绩、导出Excel。  总共就你一个人写,维护的人也是你,  甚至下个月这系统就下线了。

这时候你还搞什么“DTO层”?  还建个 UserRequestDTO.java、UserResponseVO.java、UserConverter.java?  然后每个接口都要跳三个文件才能看懂数据长啥样?兄弟,你这不是写代码,  你是在给自己挖“代码迷宫”,  以后你自己进来都得带地图。这叫:用航母的流程造玩具船。

这时候的上下文是:  
✅ 项目小  
✅ 人少  
✅ 需求简单  
✅ 没人会调你的接口  
✅ 改天就删了  

在这种情况下,  最干净的架构,就是没有架构。  直接 controller 调 service,传个对象,拿个结果,完事。  简单、直接、没人迷路。


三、大项目?那还真得讲规矩!

但反过来,如果你在腾讯做微信通讯录接口,  那就不一样了。

你这个接口,  
- 网页端要显示昵称+头像  
- APP要加个“最近聊天时间”  
- 开放平台给第三方,只能看昵称,不能看手机号  
- 还得防数据库字段泄露(比如你不能把用户密码字段传出去)

这时候,你还直接把数据库的 User 对象扔出去?  那不叫“简洁”,那叫“闯祸”。

所以你得搞个 DTO ——  也就是“定制化小纸条”:  
- 给网页的,写一张  
- 给APP的,多加一行  
- 给第三方的,只写两行,其他打码  

这时候 DTO 不是累赘,  它是“安全门”+“翻译官”+“客服专员”。这就是上下文变了,做法就得变

四、设计模式不是“正确”,而是“应对问题”

所有设计模式,比如 MVC、DTO、工厂、单例……  它们都不是“正确代码”的标准答案,  而是前人踩过坑后总结的:  哎,上次我们直接传数据库对象,结果前端改了个字段,后端崩了,后来我们加个 DTO 层,就稳了; 团队50个人改同一个模块,乱成一锅粥,后来分层,各干各的,就顺了。

所以这些“套路”本质是:  为了解决某个具体问题而生的工具。

但问题是——  很多人学了这些“企业级开发套路”,  就像小孩拿到新玩具,不管啥场合,  见人就想秀:“你看我会用设计模式!”结果项目明明只需要一把螺丝刀,  他非得把整个工具箱搬出来,  电钻、电焊、切割机全上,  最后螺丝没拧上,房子先炸了。

五、终极判断标准:问自己一句话

下次你犹豫要不要加 DTO、要不要分层、要不要搞设计模式,  
别问:  
❌ “这是不是‘标准做法’?”  
❌ “别人会不会觉得我不专业?”  

而是问:   “我现在遇到的问题,真的需要这个吗?”,如果答案没有,  那你加的不是“架构”,  是“技术表演”。就像你在家穿拖鞋吃饭很舒服,  但不代表你去结婚典礼也能穿拖鞋。  不是拖鞋不好,是场合不对



总结(三句话记一辈子):

1. 没有“最好”的架构,只有“最合适”的架构。  
2. 小项目讲效率,大项目讲秩序。  
3. 一切脱离上下文的“最佳实践”,都是耍流氓。

最后送一句程序员界的至理名言:如果你手里有把锤子,   别看全世界都是钉子,  有时候——它可能只是个西瓜。

(别砸,会爆汁)