软件工程

2026-05-111 引用
  • S:在学习和实践“软件工程”时,需要建立统一的概念和问题边界。
  • C:相关概念、实现机制和工程取舍容易混在一起,导致只记住结论而无法判断适用条件。
  • Q:“软件工程”要解决什么问题?它的核心抽象、工作机制和边界分别是什么?
  • A:本文围绕“软件工程”整理核心概念、关键机制和工程实践,并明确其适用边界。

软件工程的目标,就是在现实约束下管理复杂度:对必然复杂度做清晰建模,对偶然复杂度做持续压缩。

  • 必然复杂度:业务世界本身的复杂度
  • 偶然复杂度:协作 / 技术 / 实现带来,非业务需求,但是在实现业务的过程种引入的

软件工程不是消灭复杂度,而是识别、控制与隔离复杂度,并尽可能分摊和降低复杂度带来的成本。

方式

复杂性不能凭空消失,只能被吸收、转移、隔离或自动化。

命名、隔离、分解、抽象、约束、自动化

  • 业务
    • 规则复杂:可以被集中、命名、建模和保护
    • 变化复杂:隔离变化,把变化限制在局部
  • 偶然
    • 认知复杂:局部代码局部理解
    • 协作复杂:用系统边界降低协作成本
    • 状态复杂:明确状态、状态转移和不变量(让系统在失败、重复、乱序下仍然可恢复)
    • 数据复杂:区分事实数据和派生数据
    • 交付复杂:把交付过程工程化、自动化、可回滚
    • 分布式复杂:承认不可靠,并为不确定性设计

命名: 隔离:让失败、变化、脏逻辑不扩散。 分解:把大问题拆成小问题。 抽象:通过隐藏细节、建立边界、定义接口、压缩认知负担,让人可以局部理解系统。例如模块、函数、类型、协议、服务边界、领域模型,都是抽象。 约束:用规范、测试、类型、文档减少不确定性。 自动化:用 CI、部署脚本、格式化、代码生成减少人工复杂度。

总结:软件工程 = 在约束下管理复杂度;架构 = 决定复杂度应该被放在哪里;抽象 = 用边界和接口压缩复杂度。


                Software Engineer
                       │
          ┌────────────┴────────────┐
          │                         │
      Build things              Judge things
          │                         │
      Coding Agent             Human Engineer
       increasingly                 │
       handles it                    │
                         ┌───────────┼───────────┐
                         │           │           │
                       Data      Architecture   Reliability
                         │           │           │
                  access pattern   tradeoff     failure model
                  transaction      state        security
                  lifecycle        boundary     blast radius
                         │           │           │
                         └──────┬────┴─────┬─────┘
                                │
                           Production
                                │
                     observe / scale / evolve

评论