软件架构致命陷阱:分层

大多数写软件的团队会习惯性地把代码分成几层(比如控制层、服务层、数据库层),或者按技术工种分(比如做页面的/做后台的、做接口的/管数据库的)。这么分乍一看挺整齐,大家都熟悉,感觉也挺踏实。但是当软件越做越大时,就开始出些麻烦事了。

比如你只改了一行业务逻辑...结果数据库那边突然出错了。你调整了下界面...莫名其妙核心服务的测试就挂了。各层之间的界限越来越模糊,责任乱套,每次改代码都像在扯毛衣线头——一扯就全散架。

为啥会这样?因为分层架构是按代码"干什么活"来分的,不是按"会不会经常变"来分的。这种传统分法忽略了系统里哪些部分老要改、哪些基本不动,结果导致暗藏的连带关系、脆弱的边界和让人头疼的部署。最后你会得到一些看起来独立的模块,但其实像搭积木一样——随便动一块,整个就塌了。

【举个形象例子】
想象有个查询系统:客户登录后打印自己公司的数据记录。

如果按功能分的:检查数据和打印数据分成两个类。但每个类里都混杂着登录信息、账单信息、地址和交易记录。要是账单规则改了,你可能得同时改两个类——即使登录和地址的逻辑根本不用动。

如果按变化频率重构的:每个处理器管自己那块数据的所有事(比如登录处理器只管登录相关,账单处理器只管账单相关)。这样某个领域的变化(比如税率调整)就不会影响到其他功能(比如登录检查)。

效果:副作用少、责任明确、改动影响可控。

【用盖房子打比方】
传统分法就像按工种组施工队:伐木队专门砍木头,油漆队专门刷漆,水管队专门装管道。看起来专业高效对吧?但当你装修厨房时,得同时叫来油漆工、木工、水管工、电工——他们互相等来等去,还容易互相碍事。本来只装修一个房间,结果整栋楼都得协调。

新分法就像按房间组队:厨房小队包办厨房所有装修,浴室小队负责浴室全部工程。要改厨房?只找一个团队就行。他们对厨房了如指掌,独立作业,改动范围可控。这就是按变化频率分代码的精髓。

【怎么找出常变的部分】

查代码修改记录:哪些文件老在改?

问产品经理:哪些功能以后会常更新?(比如促销规则肯定比邮政编码格式变得勤,这有点像算命先生预测未来

看代码特征:老在加if语句处理特殊情况的,多半经常变

听程序员吐槽:"最怕改这个文件"、"一改就出问题"的地方就是热点区

找到这些"易变区"后,关键是把它们单独拎出来,和稳定的代码隔开。目标是让每个模块只有一种改动的理由,按自己的节奏变化。

【重要原则】
模块之间要划清界限,通过定义稳定的接口(就像签合同)。接口要尽量简单,只暴露必要部分。这样内部怎么改都不影响其他模块。

【终极道理】
软件很少因为功能本身失败,而是因为改不动才垮的。

传统架构总在问"这段代码是干什么的?",我们应该问"这段代码多久会变?"。
按变化频率来组织代码,就能把变化从风险变成优势——改动范围小、可预测、好管理。
这样你就能花更少时间修bug,更多时间做有用功能。

但是,预测未来容易陷入假设误区:

  • 你给家人准备了草莓,没想到这次草莓很好吃,大家不够分,你如何预测这个变化?事先尝一下看好不好吃?其他变化你能预测吗?
  • 图书馆为了让大家休息,准备沙发,结果有人躺在沙发睡觉,出乎预期怎么办?撤走沙发,结果是双输,人性关怀何在?