Skip to content

宏观指导

软件工程中有一些宏观方向层面的指导原则,这些原则不是具体的技术指南,而是对软件开发规律的深刻洞察,它们帮助我们在复杂的技术决策中找到方向,避免陷入细节而迷失全局。

康威定律

康威定律指出:"设计系统的组织,其产生的设计方案在结构上必然是该组织沟通结构的写照。"

架构设计不仅仅是技术问题,更是组织问题。如果你想做一个微服务架构,但团队是按行政职能划分的(前端组、后端组、DBA 组),那么你的架构边界永远划不清楚。

传统组织结构:
┌─────────┐  ┌─────────┐  ┌─────────┐
│ 前端组  │   │ 后端组  │  │ DBA 组  │
└─────────┘  └─────────┘  └─────────┘
    ↓            ↓            ↓
产生的架构:
┌─────────┐  ┌─────────┐  ┌─────────┐
│ 前端层  │   │ 后端层  │  │ 数据层  │
└─────────┘  └─────────┘  └─────────┘

康威式组织结构:
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ 订单服务团队 │  │ 支付服务团队 │  │ 用户服务团队 │
└──────────────┘  └──────────────┘  └──────────────┘
      ↓                 ↓                 ↓
产生的架构:
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ 订单服务     │  │ 支付服务     │  │ 用户服务     │
└──────────────┘  └──────────────┘  └──────────────┘

逆向康威定律

既然架构会反映组织结构,那么我们也可以通过调整组织结构来引导架构演进。亚马逊的"两个披萨团队"原则就是康威定律的逆向应用:每个团队应该足够小(两个披萨就能吃饱),并且全权负责一个独立的服务。

这一定律给我们的启发是:如果想做一个微服务架构,但团队是按行政职能划分的,那么架构边界永远划不清楚。组织结构必须与架构目标相匹配。

墨菲定律

"凡是可能出错的事,就一定会出错。"

在软件系统中,任何可能发生错误的地方最终都会发生错误。网络会中断、服务器会宕机、用户会输入非法数据、依赖服务会不可用。因此设计系统时必须假设一切都会出问题,并为此做好准备。

  • 所有的外部调用都要有超时机制和降级策略
  • 关键操作必须有幂等性设计,支持重试
  • 数据变更必须可追溯、可回滚
  • 永远不要信任客户端传来的数据

奥卡姆剃刀

"如无必要,勿增实体。"

在能够满足需求的前提下,选择最简单的方案,避免为了显摆技术而引入不必要的复杂性。能用关系数据库解决的就不要上分布式存储,能用单机解决的就不要上集群,能用同步调用的就不要引入消息队列。

很多技术选型并非基于真实需求,而是基于工程师的技术追求或简历驱动开发。奥卡姆剃刀提醒我们,技术的引入必须带来明确的价值收益,否则就是负债。

帕累托法则

80% 的复杂度往往是由 20% 的核心功能引起的。同样,80% 的价值来自于 20% 的核心功能。

聚焦关键路径,识别系统中那 20% 的核心功能和瓶颈,投入主要精力进行优化,往往能够事半功倍。不要在边缘功能上浪费太多时间,更不要为了完美而优化那些很少被调用的代码。

在有限的开发资源下,应该优先保证核心功能的稳定性和性能。边缘功能可以做得粗糙一些,甚至在某些情况下可以不做。

破窗效应

如果代码里有一处烂代码没修,很快整个项目的代码都会腐烂。

技术债务的加速积累,当一个项目中出现明显的坏代码而没有及时修复,其他开发者在提交代码时也会降低标准。"既然这里都这么写了,那我这样写也没什么问题。"这种心态会像病毒一样传播,最终导致整个代码库无法维护。

  • 建立代码审查机制,不让坏代码进入代码库
  • 发现烂代码及时修复,不要说"以后再重构"
  • 定义清晰的编码规范,并严格执行
  • 定期进行技术债务清理,保持代码健康

阿姆达尔定律

并行系统的加速效果受限于系统中必须串行执行的部分。

并行的边界。如果一个程序中 50% 的代码必须串行执行,那么无论投入多少计算资源,整体加速比的上限就是 2 倍。这意味着盲目增加服务器数量不一定能带来线性性能提升。

性能优化应该从串行瓶颈入手,减少锁竞争、减少跨节点通信、减少必须串行的业务逻辑。这些才是真正制约系统扩展能力的因素。