这一篇和上一篇讲的思维转变不同,它更偏「具体决定」。但我想先强调一点:一个人做产品,架构的目标和大公司完全不同。
先明确目标:可改 > 先进
大公司架构的目标常常是「支撑规模」;一个人做产品的目标应该是:
改起来容易(因为你的判断一定会变);
出问题能定位(因为只有你自己排查);
换掉某一块的代价可控(因为技术会过时);
不需要运维团队也能跑(因为只有你)。
一句话:架构好不好,用「你敢不敢改」来衡量,而不是用「看起来专业不专业」。
原则一:单体优先,别急着拆
微服务、多服务拆分是解决「组织问题」的方案,不是解决「技术问题」的方案。当你只有一个人的时候,拆分只会带来网络调用、部署复杂度、调试难度这三项纯成本。
我的做法是:先做成一个单体,用清晰的模块边界来组织代码。边界清楚但物理上不拆,等真出现「必须拆」的理由时再拆 —— 通常那个理由很久都不会来。
原则二:少依赖,依赖要记账
每引入一个外部东西,你就多了一笔长期负债:升级它、兼容它、被它的 bug 影响。
所以我给自己两条规矩:
能自己写几十行解决的事,不要引一个包;
引了就写一句「为什么需要它」,将来才能判断能不能删。
原则三:先把数据结构想清楚
这是我踩过最多次的地方,也是最贵的地方。**结构改动的成本,远高于功能改动的成本。**
所以我现在的习惯是:动手写接口之前,先画数据关系。
实体有哪些,它们之间是什么关系(一对一 / 一对多 / 多对多);
哪些字段需要被单独查询和排序(这些必须建成真正的列,不要塞进一个字段里);
哪些是「历史信息」(比如草稿、版本、操作记录),需要单独存放而不是覆盖。
尤其是最后一条:任何「会被覆盖」的数据,迟早都会有人后悔。所以我给内容加了草稿层,删除也走回收站 —— 这不是过度设计,而是替代「时刻备份」的日常保险。
原则四:把「可能会换」的东西隔离开
我不追求「永远不用换」,而是追求「换的时候只动一处」。所以我会主动做几层隔离:
数据访问集中在一层,业务代码不直接写查询语句;
外部服务(邮件、存储、推送)各自包一层,换供应商只改那一层;
界面和数据分开,这样前端换写法时业务逻辑不受影响。
原则五:把「运维」当成架构的一部分
这一条是很多人忽略的。一个人的项目,部署与恢复流程必须被设计出来,而不是「到时候再说」:
发布要有固定流程(自检 → 备份 → 同步 → 验证);
回滚要是「一条命令」,而不是「我记得上次是怎么改的」;
备份要定期验证能恢复,而不是只存着;
关键路径要有自检,能自动发现问题。
什么时候才值得拆分
我给自己的判断条件(满足其中一条才考虑拆):
某一部分的资源需求差异极大,混在一起会拖累整体;
某一部分的故障会连带影响全局,需要隔离;
某一部分的迭代频率和稳定性要求完全不同;
部署或发布的要求互相冲突(比如一个要频繁发、一个要极其稳定)。
注意这些条件里没有「因为它更优雅」。架构决策最怕的就是「为了架构而架构」。
我的架构自检清单
模块边界清楚吗?改一个功能需要动几个地方?
数据能自己导出、备份、迁移吗?
换掉某一块技术时,改动范围是否可控?
出故障时,我能不能在十分钟内定位到是哪一层的问题?
部署与回滚是不是「照着做就行」?
如果这五条都能回答「是」,那这套架构对一个人来说就是合适的 —— 哪怕它看起来一点都不酷。