知识体系-第四阶段:软件设计与架构哲学

9 阅读29分钟

第四阶段:软件设计与架构哲学

阶段定位:从“会用框架”到“会做设计”,从“理解实现”到“创造实现”。本阶段是前三阶段技术知识的认知升华——用设计视角重新审视已经掌握的所有技术,形成可迁移的架构决策能力。

系列间依赖关系

flowchart TB
    subgraph 根基[" 根基层 "]
        D1["④ 软件设计原则与哲学<br/>(8篇)"]
    end

    subgraph 方法论[" 方法论层 "]
        D2["① 设计模式深度<br/>(10篇)"]
        D3["② 领域驱动设计 DDD<br/>(15篇)"]
        D4["③ 架构风格与模式<br/>(10篇)"]
    end

    subgraph 实践[" 实践层 "]
        D5["⑤ 工程化与交付设计<br/>(9篇)"]
    end

    D1 --> D2
    D1 --> D3
    D1 --> D4
    D2 --> D3
    D2 --> D4
    D3 --> D4
    D2 --> D5
    D3 --> D5
    D4 --> D5

    style D1 fill:#fce4ec,stroke:#880e4f
    style D2 fill:#e8f5e9,stroke:#2e7d32
    style D3 fill:#e8f5e9,stroke:#2e7d32
    style D4 fill:#e8f5e9,stroke:#2e7d32
    style D5 fill:#e3f2fd,stroke:#1565c0
系列层级核心问题
④ 软件设计原则与哲学根基层什么样的设计是“好”的?SOLID 如何落地?复杂度如何管理?
① 设计模式深度方法论层GoF 23 种模式如何在框架中应用?何时该用、何时不该用?
② 领域驱动设计 DDD方法论层如何把业务复杂性驯服在代码结构中?
③ 架构风格与模式方法论层微服务/事件驱动/云原生等架构风格如何选型与组合?
⑤ 工程化与交付设计实践层设计如何落地为可测试、可交付、可追溯的工程体系?

依赖摘要

  • ④ → ①:SOLID 原则是设计模式的哲学根基。开闭原则(OCP)是策略模式、模板方法模式的理论来源;依赖倒置原则(DIP)是工厂模式、适配器模式的理论来源;单一职责原则(SRP)是装饰器模式的理论来源。
  • ④ → ②:限界上下文的划分依据是单一职责原则和高内聚低耦合;聚合的设计依据是迪米特法则(最小知识原则);领域事件的设计依据是开闭原则(对扩展开放,对修改封闭)。
  • ④ → ③:架构风格的选型本质上是质量属性(性能/可用性/安全性/可维护性/可测试性)之间的权衡——这正是 ATAM 权衡分析法的应用场景。
  • ② → ①:DDD 的聚合根、资源库、领域服务等战术模式,本质上是对 GoF 模式(工厂、策略、观察者)在业务层的重新诠释。
  • ② → ③:限界上下文是微服务拆分的边界;领域事件是事件驱动架构的驱动力;CQRS 是读写分离架构在业务层的实现。
  • ①/②/③ → ⑤:设计模式决定了测试策略(策略模式便于 Mock,责任链便于分段测试);DDD 的限界上下文决定 API 契约的边界;架构风格决定 Git 仓库拆分和 CI/CD 流水线设计。

系列 ① 设计模式深度(10 篇)

定位:以 GoF 23 种经典设计模式的定义与结构为骨架,以 JDK / Spring / Netty / Kafka 源码中的实现为血肉,最后以模式选型决策树收尾。

序号文章标题稳定性知识点
1创建型模式:单例、工厂、建造者与原型🟢单例模式:定义、结构(私有构造器 + 静态实例 + 静态获取方法)。JDK Runtime.getRuntime()(饿汉式)、枚举单例(防反射防序列化破坏)。Spring @Scope("singleton") 与 GoF 单例的区别(per-IoC vs per-JVM)。
工厂方法模式:定义、结构(Creator + factoryMethod() + ConcreteCreator)。JDK Iterable.iterator()。Spring FactoryBean.getObject()
抽象工厂模式:定义、结构(AbstractFactory + ConcreteFactory + AbstractProduct + ConcreteProduct)。Spring BeanFactory 层次结构。
建造者模式:定义、结构(Director + Builder + ConcreteBuilder + Product)。JDK StringBuilderStream.builder()。Spring HttpSecurity DSL 链式配置。
原型模式:定义、结构(Prototype + clone())。JDK Cloneable + Object.clone()(浅拷贝)。Spring @Scope("prototype")
2结构型模式(上):适配器、桥接与装饰器🟢适配器模式:定义、结构(Target + Adapter + Adaptee)。类适配器(继承)vs 对象适配器(组合)。JDK Arrays.asList()InputStreamReader。Spring HandlerAdapter(将 HttpRequestHandler/Controller 统一适配为 ModelAndView handle())。
桥接模式:定义、结构(Abstraction + RefinedAbstraction + Implementor + ConcreteImplementor)。JDK java.sql.DriverConnection。Spring PlatformTransactionManagerDataSourceTransactionManager/JtaTransactionManager
装饰器模式:定义、结构(Component + ConcreteComponent + Decorator + ConcreteDecorator)。JDK BufferedInputStreamCollections.synchronizedList()。Netty ChannelPipeline(每个 ChannelHandler 装饰处理逻辑)。Spring BeanDefinitionDecorator
3结构型模式(下):代理、外观、组合与享元🟢代理模式:定义、结构(Subject + RealSubject + Proxy)。JDK 动态代理(InvocationHandler)vs CGLIB(MethodInterceptor)。Spring AOP(JdkDynamicAopProxy vs CglibAopProxy)、@Lazy 延迟注入代理。
外观模式:定义、结构(Facade + 子系统类群)。JDK Class 类。Spring JdbcTemplate(封装 DataSourceConnectionStatementResultSet)。
组合模式:定义、结构(Component + Leaf + Composite)。Spring CompositePropertySource
享元模式:定义、结构(FlyweightFactory + Flyweight + ConcreteFlyweight + 非共享外部状态)。JDK Integer.valueOf(-128~127) 缓存池、String 常量池。Spring 三级缓存 singletonObjects
4行为型模式(上):策略、模板方法与观察者🟢策略模式:定义、结构(Context + Strategy + ConcreteStrategy)。JDK ComparatorThreadPoolExecutor.RejectedExecutionHandler。Spring ResourcePatternResolverInstantiationStrategy。Kafka Partitioner 接口。
模板方法模式:定义、结构(AbstractClass + templateMethod() + primitiveOperation())。JDK AbstractList.addAll() 调用子类 add()AQS.acquire() 调用子类 tryAcquire()。Spring AbstractApplicationContext.refresh()(13 步模板 + 钩子)。
观察者模式:定义、结构(Subject + Observer)。推送模型 vs 拉取模型。JDK Observer/Observable(JDK 9 废弃)、PropertyChangeListener。Spring ApplicationEvent + @EventListener(进化:同步/异步/事务绑定)。Kafka ConsumerRebalanceListener
5行为型模式(中):责任链、命令、迭代器与中介者🟢责任链模式:定义、结构(Handler + ConcreteHandler + successor)。纯链(处理或传递)vs 不纯链(处理后可继续传递)。Spring FilterChainHandlerInterceptor 链。Netty ChannelPipeline(Inbound/Outbound 双向链)。
命令模式:定义、结构(Invoker + Command + ConcreteCommand + Receiver)。JDK RunnableCallable。Kafka ProducerRecord 本质是命令对象。
迭代器模式:定义、结构(Iterator + ConcreteIterator + Aggregate + ConcreteAggregate)。JDK Iterator + fail-fast(modCount)。Spring CompositeIterator
中介者模式:定义、结构(Mediator + ConcreteMediator + Colleague)。JDK java.util.Timer。Spring DispatcherServlet 作为前端控制器协调各组件。
6行为型模式(下):状态、备忘录、访问者与解释器🟢状态模式:定义、结构(Context + State + ConcreteState)。JDK Thread 状态机。Seata AT 事务状态机(Begin→Committing→Committed/Rollbacking→Rollbacked)。
备忘录模式:定义、结构(Originator + Memento + Caretaker)。JDK Serializable。Seata AT undo_log 表(beforeImage + afterImage 行级快照)。
访问者模式:定义、结构(Visitor + ConcreteVisitor + Element + accept())。JDK java.nio.file.FileVisitor。Spring BeanDefinitionVisitor
解释器模式:定义、结构(AbstractExpression + TerminalExpression + NonterminalExpression + Context)。Spring SpEL(ExpressionParserExpressionEvaluationContextgetValue())。
7模式组合与变体:框架中的多模式协作🟢Spring AOP:代理(创建代理对象)+ 责任链(MethodInterceptor 链式调用)+ 策略(JDK 代理 vs CGLIB)+ 适配器(AdvisorAdapterAdvice 适配为 Interceptor)。
Spring IoC:工厂(BeanFactory 层次)+ 单例(singleton 作用域)+ 模板方法(refresh() 流程)+ 策略(不同 InstantiationStrategy)+ 观察者(事件机制)。
Netty 管道:责任链(ChannelPipeline)+ 装饰器(每个 ChannelHandler 增加处理能力)+ 策略(EventExecutorChooser)+ 适配器(ChannelInboundHandlerAdapter)。
Kafka 生产者:策略(Partitioner)+ 命令(ProducerRecord)+ 模板方法(Sender.run())+ 观察者(Callback)。
反模式:模式堆砌——不是所有场景都需要多模式协作,过度抽象导致代码膨胀。
8设计原则:SOLID、正交性与迪米特法则🟢SRP 单一职责:一个类应该只有一个引起变化的原因。OrderService 不应同时处理订单逻辑和发送邮件。
OCP 开闭原则:对扩展开放,对修改封闭。BeanPostProcessor 扩展点,无需修改 Spring 核心代码。
LSP 里氏替换:子类应能替换父类而不引起错误。InputStream 的子类都能替换 InputStream 使用。
ISP 接口隔离:不应强迫客户端依赖不使用的方法。CharSequence 将公共接口隔离出来。
DIP 依赖倒置:高层不应依赖低层,两者都依赖抽象。JdbcTemplate 依赖 DataSource 接口而非 HikariDataSource
正交性:不同变化维度相互独立。HandlerMapping(路由)与 HandlerAdapter(执行)的正交分离。
迪米特法则:只与直接朋友通信。a.getB().getC().doX() 的反模式。微服务中通过 API 网关通信。
9设计反模式与过度设计的识别🟢单例误用:全局状态 → 隐藏耦合、测试困难。静态工具类优于单例。
工厂误用:3 个以下实现类时,直接 new 比工厂更简单。
观察者误用:没有明确解耦需求时,同步调用优于事件通知。
责任链误用:链过长(Spring Security 默认 15 个 Filter)→ 调试困难。
装饰器误用:装饰层过多 → 类型层次复杂。
过度设计特征:为不确定需求预留扩展点、每个接口只有一个实现类、代码量增长远超业务复杂度。
KISS 原则:能用 if-else 不用策略模式,能用单机不用分布式。
YAGNI 原则:在真正需要变化时才重构引入模式。
10模式选型决策树与实战演练🟢决策树
对象创建复杂?→ Builder/Factory Method/Abstract Factory。
接口不兼容?→ Adapter。需要动态增强?→ Decorator。需要控制访问?→ Proxy。
算法需灵活切换?→ Strategy。固定流程有钩子?→ Template Method。状态决定行为?→ State。
多处理者可能响应?→ Chain of Responsibility。一对多通知?→ Observer。
实战推演 4 场景:支付系统多支付方式(Strategy)、Spring Boot 多配置源加载(Composite + Facade)、订单状态流转(State)、网关鉴权→限流→日志→转发(Chain of Responsibility)。
自检清单:是否引入了不必要的抽象?是否真的存在变化?现在不用的模式三年后会不会成为技术债?

系列 ② 领域驱动设计 DDD(15 篇)

定位:从战略设计到战术设计再到工程落地,形成完整的 DDD 方法论。贯穿案例:电商交易系统。

序号文章标题稳定性知识点
1DDD 战略设计:限界上下文、实体与值对象🟢统一语言:与业务专家协同建立术语表,在代码中映射为类名、方法名、模块名。
事件风暴:识别领域事件(OrderPlacedInventoryDeducted)、命令(PlaceOrder)、聚合(OrderInventory)→ 聚类为限界上下文。
限界上下文:语义边界,决定微服务拆分粒度;验证四大启发式规则(业务能力、组织边界、数据一致性、变化频率)。
上下文映射:共享内核、客户-供应商、防腐层、开放主机服务、发布语言。
AI 辅助事件风暴:将业务需求描述输入 LLM,自动提取候选领域事件、命令、聚合,人工复核后形成初步限界上下文。
2战术 DDD 与 Spring 实现:聚合、资源库与领域服务🟢聚合与聚合根:一致性边界,小聚合优先,通过 ID 引用其他聚合,一次事务只修改一个聚合。
值对象@Embeddable 实现 AddressMoneyequals/hashCode 基于值比较。
资源库interface OrderRepository extends JpaRepository<Order, Long>,只定义聚合根的资源库。
领域服务:跨聚合的业务逻辑(如 PricingService 计算订单总额),区别于应用服务(编排)。
领域事件AbstractAggregateRoot.registerEvent() 发布,@TransactionalEventListener 异步处理。
3Spring Modulith 与 DDD 融合:模块化单体的领域边界🟡核心组件@ApplicationModuleListener(异步事件通信)、@ApplicationModuleTest(模块级集成测试,Scenario API)。
模块验证ModuleTest.verify() 检测模块间非法依赖。
ArchUnit 约束ArchRule 禁止领域层依赖基础设施层。
与微服务拆分衔接:Modulith 作为微服务的前置过渡,限界上下文清晰后可独立拆分为微服务。
4事件驱动架构与 CQRS 的 Spring 落地🟡CQRS 命令/查询分离:写端 @Entity + JPA,读端 @Document (ES) 或 Redis;写操作发布 OrderPlaced 事件,读端消费更新物化视图。
Spring 实现:写端 ApplicationEventPublisher.publishEvent(),读端 @TransactionalEventListener(phase = AFTER_COMMIT) 异步消费。
查询优化:读端直接查询 ES/Redis,不经过写模型。
事件存储outbox 表 + Debezium CDC 保证事件可靠发布。
5领域事件设计原则与 Spring 实现:Event 建模、存储与分发🟢事件设计:命名过去式(OrderPlaced),包含聚合 ID、关键字段、时间戳;避免携带过多数据。
事件存储与发布outbox 模式在业务事务中写入 event_store 表,DebeziumPollingPublisher 读取并发送到 Kafka。
消费者幂等:通过 eventId 唯一键 INSERT ON DUPLICATE KEY UPDATE 去重。
与集成事件的区分:领域事件关注业务含义,集成事件关注技术同步。
6CQRS 与 Event Sourcing 深度:Axon Framework 实战🟡Axon 核心源码@Aggregate 标识聚合根,@CommandHandler 处理命令并发布事件,@EventSourcingHandler 根据事件重建状态。
AggregateLifecycle.apply(event):事件先经过 EventBus 发布到 EventStore,再由 TrackingEventProcessor 分发。
Saga 编排@Saga + @StartSaga + @SagaEventHandler + @EndSaga 实现分布式长事务(补偿逻辑),对比 Seata AT/TCC。
DeadlineManager:处理超时业务(如 30 分钟未支付自动取消),基于 QuartzJobRunr 调度。
7防腐层与接口适配:集成多个限界上下文的策略🟢防腐层代码实现@Component 封装 FeignClient,将上游模型 ExternalOrderDTO 翻译为内部领域对象 Order
适配器模式InventoryAdapter implements InventoryPort,内部调用 RPC 或 HTTP,领域层仅依赖 InventoryPort 接口。
集成多个 Bounded Context:每个下游对应一个 Adapter + Translator,隔离外部模型变化。
测试防腐层WireMock 模拟下游 API,验证 Translator 翻译正确性。
8聚合设计指南:大小、边界与事务一致性🟢设计原则:小聚合(减少并发冲突),通过 ID 引用其他聚合(不直接持有对象引用),最终一致性处理跨聚合操作。
事务边界:一次事务只修改一个聚合实例;跨聚合操作通过领域事件异步完成。
不变量保护:聚合根检查业务规则(如 Orderconfirm() 校验状态为 PENDING 且库存充足),校验在聚合内部而非外部 Service。
反模式:聚合过大(包含过多实体→慢 SQL、大对象图)、聚合过小(导致事务边界不完整)。
9DDD + Kubernetes:领域服务到微服务的部署映射🟡限界上下文 → K8s Deployment:每个上下文独立 DeploymentServiceConfigMap
聚合 → Pod 伸缩单元:热点聚合(如秒杀商品)独立部署与扩缩容。
领域事件 → Istio/Eventing:事件驱动通过 KafkaKnative Eventing 触发。
CI/CD:每个上下文独立代码仓库、独立流水线,与 GitOps 结合。
10微服务划分原则:从业务能力到限界上下文的映射🟢康威定律:团队组织与限界上下文对齐,每个跨职能团队负责一个上下文。
拆分决策:业务能力独立性、数据独立性、变更频率差异、可伸缩性需求四维度评估。
不应拆分:强事务耦合、数据量低、团队规模小→先用 Modulith 单体。
11复杂业务系统的模型演进与重构策略🟢遗留系统改造:Strangler Fig 模式——新功能在微服务中实现,旧单体功能逐步替换。
聚合拆分:大聚合拆分为多个小聚合,通过领域事件保持最终一致。
数据迁移pt-archiver 分批迁移,Debezium 双向同步,双写过渡期。
12业务中台化设计思想:能力复用与标准化🟢中台与限界上下文映射:中台能力(用户中心、订单中心、商品中心)对应共享内核或开放主机服务。
能力标准化模板:能力名称、输入输出、SLA、API 契约(OpenAPI 3.0)、错误码体系。
中台与微服务的边界:中台提供通用能力(如 UserService),前台提供差异化业务(如 VipOrderService)。
13从代码到架构:编写表达业务意图的陈述式代码🟢DSL 模式:订单状态转换使用状态机 DSL。
Builder 模式Order.builder() 链式调用,内部校验必填字段。
Specification 模式Specification<Order> 封装查询条件,在 Repository 中直接使用。
表达式语言@PreAuthorize("hasRole('ADMIN')") 结合 SpEL 表达业务权限。
14企业级项目实战:电商交易系统的 DDD 完整案例🟢贯穿案例:从需求出发(用户下单、支付、库存扣减、通知)。
事件风暴:识别 OrderPlacedPaymentConfirmedInventoryDeductedNotificationSent 事件。
限界上下文:订单上下文、库存上下文、支付上下文、通知上下文。
聚合设计Order 聚合(OrderIdOrderItemsStatus),Inventory 聚合(ProductIdQuantity)。
战术落地:Spring Data JPA 实现 Repository,@Transactional 保护聚合一致性,领域事件发布。
CQRS:订单查询走 ES,订单写入走 JPA。
防腐层PaymentAdapter 封装支付网关 API。
15反模式与排查宝典🟢12+ 反模式:贫血模型(@Entity 只有 getter/setter,逻辑全在 Service)、聚合过大、资源库滥用、领域事件循环、跨界上下文直调、没有统一语言、值对象错当实体、事件未幂等、CQRS 过度设计、未遵循小聚合、AI 生成的模型未经过人工验证。
六步排查法:错误示例→现象描述→排查思路(jstack/arthas、SQL 日志)→根因分析→修正方案→最佳实践。
AI 辅助代码审查:通过 LLM 扫描代码,检测贫血模型、聚合过大、缺少防腐层等反模式,输出评审报告。

系列 ③ 架构风格与模式(10 篇)

定位:跳出单一框架,理解分布式系统背后的架构模式。与第三阶段总纲呼应——总纲讲“是什么”,这里讲“为什么这样设计”和“如何选型”。

序号文章标题稳定性知识点
1分层架构与六边形架构🟢经典三层:表现层→业务逻辑层→数据访问层,依赖自上而下。
DDD 四层:接口层→应用层→领域层→基础设施层,依赖倒置(领域层是核心,不依赖任何外部)。
六边形架构(端口-适配器):领域模型在中心,端口(Port)定义接口,适配器(Adapter)实现端口连接外部。输入适配器(HTTP/RPC)和输出适配器(DB/MQ)地位对等。
与 Spring 的关系@RestController 是输入适配器,JpaRepository 是输出适配器,@Service 是应用层。
2微服务架构的拆分方法论🟢拆分策略:按业务能力拆分、按 DDD 限界上下文拆分、按康威定律(团队结构)拆分。
拆分粒度决策框架:内聚性、耦合度、团队规模、变更频率、数据一致性要求五维度量化。
何时不拆:业务紧密耦合、数据量与 TPS 不高、团队规模小。
通信选型:同步 RPC(核心链路,强一致)vs 异步消息(非核心链路,最终一致)。
数据策略:每服务独立数据库,去中心化数据管理,CQRS 读写分离。
3事件驱动架构设计🟢核心概念:事件生产者、事件消费者、事件总线(Message Broker)。
发布-订阅模式:Topic/Queue 解耦生产者与消费者。
事件溯源:所有状态变更存储为事件序列,当前状态 = 事件重放。
CQRS:写模型(Command)与读模型(Query)分离,事件驱动同步。
流处理:Kafka Streams / Flink 实时处理事件流,窗口聚合。
幂等保证:消费者通过唯一键去重,生产者通过幂等发送。
4数据密集型架构模式🟢数据分区:水平分片(ShardingSphere/Mycat),分片键 = 核心查询条件。
读写分离:一主多从,ProxySQL/ShardingSphere 延迟感知路由。
多级缓存:Caffeine L1(极热)→ Redis L2(热)→ DB L3(温冷)。
冷热分离:ES ILM Hot-Warm-Cold-Delete 四阶段,MySQL pt-archiver 归档。
数据中台:Trino 联邦查询 + PG FDW + API 网关统一入口。
一致性边界:强一致(核心交易)vs 最终一致(缓存/搜索同步),CDC 异步收敛。
5云原生架构模式🟡容器化:Docker 分层构建,Dockerfile 最佳实践。
服务网格:Istio Sidecar 透明注入,流量管理(VirtualService + DestinationRule)、安全(mTLS + AuthorizationPolicy)、可观测(Telemetry)。
声明式运维:YAML 定义期望状态,Controller 调谐至期望状态。
弹性伸缩:HPA 基于 CPU/内存/QPS 自动扩缩容,CA 扩 Node。
GitOps:Git 作为声明式配置唯一来源,ArgoCD/Flux 自动同步。
6响应式架构与流处理🟢响应式宣言:即时响应、韧性、弹性、消息驱动。
Reactor 编程模型:Mono 0-1,Flux 0-N,背压控制(request(n) 信号)。
WebFlux:非阻塞 HTTP 处理,Netty EventLoop 线程模型。
R2DBC:响应式数据库驱动,非阻塞 SQL 执行。
Kafka Streams:有状态流处理拓扑,KStream/KTable/GlobalKTable。
背压传播:从消费者到生产者,全链路非阻塞反压。
7架构演进策略🟢Strangler Fig 模式:新功能在微服务中实现,旧单体功能逐步替换,最终绞杀单体。
模块化过渡:Spring Modulith 作为微服务前置,限界上下文清晰后拆分。
可逆决策:技术选型保留回退路径,如先混合部署再逐步迁移。
技术债务管理:每季度评审超时参数、每半年压测验证容量、每年评审架构模式。
演进路径:单体 → 垂直拆分(SOA)→ 微服务 → 云原生(容器化+K8s+服务网格)。
8架构评审与检查清单🟢四维评审:通信(调用链闭环?超时遵循传递链?重试保证幂等?)、协作(分布式锁有 fencing token?事务方案匹配一致性要求?)、存储(分片键是所有核心查询条件?缓存 TTL 随机化?)、治理(熔断降级覆盖所有外部依赖?探针考虑 GC 停顿?)。
通信检查清单:超时传递链校验、重试幂等校验、MQ 死信队列监控、连接池 maxActive < DB max_connections × 0.5。
协作检查清单:锁 fencing token 校验、事务超时 > GC + 业务 + 网络、Raft 集群奇数节点。
存储检查清单:分片键区分度 > 分片数 × 10、缓存 TTL = base + random(0,300)。
治理检查清单:所有外部依赖有熔断、探针 liveness > GC × 2 + 启动、告警 P0 电话 + P1 企微 + P2 邮件。
9架构权衡分析法(ATAM)🟢质量属性场景:用场景描述性能(10000 QPS 下 P99 < 100ms)、可用性(单 AZ 故障下服务 60s 内恢复)、安全性(SQL 注入检测 < 1ms)、可维护性(新人 1 周可提交首个 PR)、可测试性(单元测试覆盖率 > 80%)。
敏感点与权衡点:敏感点(影响单一质量属性的设计决策)、权衡点(同时影响多个质量属性且存在冲突的决策)。
效用树:质量属性 → 场景 → 优先级(H/M/L)→ 难度(H/M/L)。
风险与非风险:风险(可能对质量属性产生负面影响的决策),非风险(经过验证的安全决策)。
ATAM 流程:阶段 0 准备 → 阶段 1 评估 → 阶段 2 评审 → 阶段 3 报告。
10架构风格选型决策树与实战🟢决策树
业务复杂且团队大 → 微服务。简单且团队小 → 模块化单体。
实时性要求高 → 同步 RPC。吞吐量优先 → 异步消息。
数据量大且查询多样 → CQRS + ES。数据量小且查询简单 → 单库。
需要长期存储历史事件 → Event Sourcing。
需要多平台统一查询入口 → 数据中台(联邦查询)。
实战推演:电商平台架构选型——微服务拆分(订单/库存/支付/通知)+ 同步 RPC(核心)+ 异步消息(非核心)+ AT 分布式事务(订单-库存)+ CDC 缓存刷新(MySQL → Kafka → Redis)+ ES 搜索 + K8s + Istio。
架构决策记录(ADR):记录决策上下文、备选方案、最终选择与理由、后果。

系列 ④ 软件设计原则与哲学(8 篇)

定位:提炼跨越语言和框架的设计智慧。SOLID 在设计模式系列已讲,本系列聚焦更高阶的设计哲学。

序号文章标题稳定性知识点
1高内聚低耦合的量化与实现🟢内聚度量:LCOM(Lack of Cohesion of Methods),方法共享字段越少内聚越低。巧合内聚→逻辑内聚→时间内聚→过程内聚→通信内聚→顺序内聚→功能内聚,七级内聚。
耦合度量:Afferent Coupling(传入耦合,被依赖数)vs Efferent Coupling(传出耦合,依赖别人数)。不稳定性 = Efferent / (Afferent + Efferent),0=最稳定,1=最不稳定。
代码层面实现:接口隔离(ISP)、依赖倒置(DIP)、包设计原则(REP/CCP/CRP)。
微服务中的体现:限界上下文内高内聚,上下文间低耦合,通过 API/事件异步通信。
2正交性与关注点分离🟢正交性定义:不同变化维度相互独立,修改一个维度不影响其他。
正交设计四原则:分离关注点、缩小抽象范围、一次且仅一次、限制变化传播。
AOP 与横切关注点:日志/事务/安全是横切关注点,AOP 将其与业务逻辑正交分离。
中间件管道模式:Netty ChannelPipeline、Spring FilterChain,每个处理器关注独立维度。
配置 vs 代码:环境相关配置与业务逻辑正交,配置中心(Nacos/Apollo)实现配置与代码的分离。
3约定优于配置🟢起源:Rails 的核心理念,Spring Boot 将其发扬光大。
Spring Boot 的体现@SpringBootApplication 自动组件扫描、@EnableAutoConfiguration 条件装配、application.yml 默认属性、Starter 依赖传递。
约定的层级:框架默认约定 → 团队规范约定 → 项目特殊约定。约定越靠前优先级越低。
合理约定 vs 过度魔法:约定让 80% 场景零配置,但允许覆盖约定(显式配置 > 约定)。
反模式:不理解约定原理盲目排除(exclude 滥用)、约定与团队习惯冲突时不协商直接覆盖。
4最小知识原则与迪米特法则🟢迪米特法则定义:一个对象应对其他对象保持最少的了解,只与直接朋友通信。
“火车残骸”反模式a.getB().getC().doX()——a 穿越了 B 去认识 C
修复手段:在 B 中增加委托方法 B.dox() 内部调用 C.doX(),或使用 Optional.map() 链式调用。
微服务中的体现:服务间不直接依赖其他服务的内部模型,通过 API 网关或防腐层隔离。
与 Law of Demeter 的权衡:过度委托会导致中间类膨胀(Wrapper Hell),需在简洁性与隔离性间平衡。
5简单性与复杂性管理🟢复杂性来源:本质复杂性(业务问题本身)vs 偶然复杂性(技术选型引入)。
KISS 原则:Keep It Simple, Stupid——先用最简单的方案,真正需要时再演进。
YAGNI 原则:You Ain't Gonna Need It——不要为不确定的未来需求预留扩展点。
技术选型的复杂度代价:引入 Kafka 带来运维成本,引入 CQRS 带来代码量翻倍,引入微服务带来分布式复杂性。
复杂度预算:每个系统有可承受的复杂度上限,超出后团队无法维护。新增任何技术都必须从预算中扣除。
简单性检查清单:这个方案能否用更简单的技术实现?移除它后系统还能工作吗?团队新人需要多久理解它?
6软件设计的哲学本质🟢设计是发现而非发明:好的设计不是凭空创造,而是从问题域中自然涌现。限界上下文不是设计的,是从业务中发现的。
抽象的艺术:什么是好的抽象?——隐藏实现细节,暴露意图。List 接口抽象了数组和链表,DataSource 抽象了连接来源。
分层的哲学:每一层只解决本层的问题,下层为上层提供能力,上层为下层赋予意义。OSI 七层 → TCP/IP 四层 → 架构分层,层层递进的抽象思想。
模式的本质:模式是对重复出现的问题的通用解决方案,但不是模板——每个模式都需要根据上下文调整。
权衡的必然性:软件设计没有银弹,任何选择都伴随代价。理解代价比做出选择更重要。
7设计中的认知偏差与决策陷阱🟢权威偏差:盲目追随“最佳实践”而不评估是否适合当前场景。
幸存者偏差:只看到成功案例(如“Netflix 用微服务成功了”),忽视失败案例。
沉没成本:已经投入大量时间在某个方案上,明知不合适仍不愿放弃。
新奇偏差:追逐新技术而忽视成熟方案的稳定性。
确认偏差:只收集支持自己预设立场的信息,忽略反面证据。
决策改进:ADR(架构决策记录)强制写下决策理由;预注册反驳意见(Devil's Advocate);延迟决策(在信息更充分时决定)。
8从技术到架构:工程师的思维跃迁🟢技术思维 vs 架构思维:技术思维关注“怎么实现”(How),架构思维关注“为什么这样”(Why)和“还能怎样”(What if)。
全局视角:单个组件的性能最优 ≠ 系统整体最优。局部缓存的 TTL 调整可能引发数据库雪崩。
时间视角:今天的选择对未来 3 年的影响是什么?如果 QPS 增长 10 倍,这个设计还能工作吗?
业务视角:技术选型最终服务于业务目标。降低 10ms 延迟能提升多少转化率?多机房容灾的 RPO/RTO 是否匹配业务 SLA?
组织视角:康威定律——系统设计最终会镜像组织沟通结构。跨团队协作的接口设计比单团队内部接口需要更稳定的契约。
思维跃迁路径:编码(实现功能)→ 设计(构建模块)→ 架构(构建系统)→ 哲学(构建可进化的体系)。

系列 ⑤ 工程化与交付设计(9 篇)

定位:设计不只是代码结构,还包含测试策略、版本管理、CI/CD、API 设计和架构决策记录。

序号文章标题稳定性知识点
1测试策略与测试金字塔🟢测试金字塔:单元测试(70%)→集成测试(20%)→契约测试(8%)→E2E 测试(2%)。
单元测试:Mockito + AssertJ,Mock 外部依赖,测试业务逻辑。
集成测试:Testcontainers 启动真实 MySQL/Redis/Kafka 容器,@DynamicPropertySource 动态注入。
契约测试:Spring Cloud Contract,消费者定义契约(Groovy DSL)→ 生成 Stub JAR → 生产者验证。
E2E 测试:核心业务链路端到端验证,数量少但覆盖关键路径。
测试反模式:测试污染(共享状态未清理)、慢测试(未使用 Testcontainers 复用容器)、冰激凌甜筒反金字塔(大量 E2E 少量单元)。
2API 设计与演化🟢RESTful API 设计规范:资源命名(名词复数 /orders)、HTTP 方法语义(GET/POST/PUT/DELETE)、状态码精确使用。
版本管理:URL 版本(/v1/orders)、Header 版本(Accept: application/vnd.api+json;version=1)、Query 版本(?version=1)。
向后兼容规则:新增字段兼容、新增接口兼容、新增错误码兼容。不兼容变更:删除字段、修改字段类型、修改接口语义。
OpenAPI 3.0:Swagger/Swagger UI 自动生成文档,springdoc-openapi 集成。
gRPC 接口演进:Protobuf 字段编号不可变,新增字段用新编号,保留废弃字段(reserved)。
GraphQL Schema 演进@deprecated 标记废弃字段,新字段直接添加不影响现有查询。
3Git 工作流与分支策略🟢Git Flowmain + develop + feature/* + release/* + hotfix/*,适合有固定发布周期的项目。
GitHub Flowmain + feature/*,PR 合并即部署,适合持续部署项目。
Trunk-Based Development:所有开发者在 main 分支上小批量频繁提交,Feature Flag 控制未完成功能。
分支策略选型:发布频率(周/月 → Git Flow,日/时 → GitHub Flow/TBD)。
Commit 规范:Conventional Commits(feat:/fix:/docs:/refactor:),关联 Issue 编号。
Code Review:Review 检查项(设计是否合理/测试是否覆盖/安全是否有风险/性能是否有隐患)。
4CI/CD 流水线设计🟢持续集成(CI):提交触发 → 编译 → 单元测试 → 代码扫描(SonarQube)→ 镜像构建 → 推送镜像仓库。
持续交付(CD):部署到测试环境 → 集成测试 → 部署到预发布环境 → 人工审批 → 部署到生产。
GitOps 部署:ArgoCD 监听 Git 仓库 → 自动同步 K8s 集群状态 → 自动回滚。
金丝雀发布:Istio VirtualService weight: 80/20 → 验证新版本 → 全量切换。
蓝绿部署:两套完整环境,Service Selector 一键切换。
自动化回滚Deployment revisionHistoryLimit + rollout undo
5容器化与镜像构建最佳实践🟡Dockerfile 优化:多阶段构建(maven:3.8 构建 + openjdk:8 运行)、COPY --chown 非 root 运行、.dockerignore 排除无用文件。
镜像分层:将变化频率低的依赖层(COPY pom.xml + RUN mvn dependency:resolve)放在变化频率高的源码层(COPY src)之前。
Jib:无需 Dockerfile,Maven/Gradle 插件直接构建镜像,自动分层。
镜像安全docker scan 扫描漏洞、使用 Distroless 基础镜像、不在镜像中存密钥。
JVM 容器感知-XX:+UseContainerSupport-XX:MaxRAMPercentage=75.0
6技术文档与架构决策记录(ADR)🟢ADR 模板:标题(ADR-001: 选择 Kafka 作为消息队列)、状态(提议/已采纳/已废弃/已取代)、上下文(为什么需要做决策)、决策(选择了什么)、后果(正面/负面/中性)。
ADR 的价值:让架构决策可追溯、可复审、可传承。新人可以通过 ADR 理解系统为什么这样设计。
文档即代码:Markdown 存于 Git,PR 评审,与代码同步版本。
C4 模型:Context(系统上下文图)→ Container(容器图)→ Component(组件图)→ Code(类图),逐级放大。
Arc42:架构文档模板,覆盖需求/约束/上下文/解决方案/运行时/部署/横切概念/风险。
7特性开关(Feature Flag)与渐进交付🟡Feature Toggle 类型:发布开关(控制未完成功能是否可见)、实验开关(A/B 测试)、运维开关(紧急关闭高负载功能)、权限开关(按用户级别开放功能)。
实现方式:配置中心(Nacos/Apollo)动态开关 + @ConditionalOnProperty 条件装配。
Trunk-Based Development 支撑:代码合入 main 但功能不启用,通过 Flag 控制发布。
技术债管理:Flag 有生命周期,功能稳定后及时清除 Flag 代码。
开源方案:FF4J、Unleash、LaunchDarkly。
8可观测性设计:从代码到生产的全链路可追踪🟡日志规范:MDC 注入 TraceId,统一日志格式(时间 + 级别 + TraceId + 类名 + 消息),logback-spring.xml 配置。
指标规范:Micrometer 统一指标门面,Timer(耗时)、Counter(计数)、Gauge(瞬时值)。业务指标命名规范:business.orders.created
链路追踪规范:TraceId 全链路传播(Gateway Filter → Feign Interceptor → MQ Header → ThreadPool TaskDecorator)。
SLO 定义:99.9% 请求 < 200ms,Error Budget = (1 - SLO) × 总请求数。
告警分级:P0(立即响应,Error Budget 燃烧 > 10%/h)、P1(紧急处理,> 2%/h)、P2(关注,延迟趋势上升)。
9软件交付的工程化成熟度模型🟢成熟度等级
L1 初始级:手动构建、手动部署、无自动化测试。
L2 可重复级:自动化构建、手动部署、单元测试。
L3 已定义级:CI/CD 流水线、集成测试、代码审查。
L4 已管理级:GitOps 部署、金丝雀发布、自动化回滚、SLI/SLO 监控。
L5 优化级:混沌工程验证、AI 辅助代码审查、自愈系统。
评估维度:构建自动化、测试自动化、部署自动化、监控自动化、安全自动化。
提升路径:识别当前等级 → 制定下一等级目标 → 选择最关键的一个维度提升 → 度量 → 复盘。
10技术债管理与持续重构🟢技术债四象限分类(有意/无意×鲁莽/谨慎)、六大识别方法(SonarQube技术债比率、JaCoCo覆盖率缺口、ADR过期复审、特性开关过期审计、Trivy/Dependabot依赖库漏洞与过期、契约测试/ArchUnit文档滞后度)、偿还策略(季度评审制度、Sprint投入15%-25%、童子军规则、Branch by Abstraction渐进重构、Strangler Fig绞杀者模式)、制度化预防(ADR记录有意债务、PR模板检查项、开关创建强制过期、Dependabot/Renovate自动更新)。