架构设计基础原则
架构设计不是凭空创造,而是在约束与目标之间寻找最优解。掌握基础原则是做出正确决策的前提。
1. SOLID 原则
单一职责原则(SRP)
一个类只应该有一个引起它变化的原因。
// 反例:UserService 同时处理用户管理与邮件发送
class UserService {
void createUser() { ... }
void sendEmail() { ... } // 职责混杂
}
// 正例:分离职责
class UserService { void createUser() { ... } }
class EmailService { void sendEmail() { ... } }
开闭原则(OCP)
对扩展开放,对修改关闭。 通过抽象和多态实现。
interface DiscountStrategy { double calculate(double price); }
class VIPDiscount implements DiscountStrategy {
public double calculate(double price) { return price * 0.8; }
}
// 新增折扣策略无需修改原有代码
里氏替换原则(LSP)
子类应能替换父类而不影响程序正确性。正方形/矩形问题是经典反例。
接口隔离原则(ISP)
客户端不应依赖它不需要的接口。
// 反例:大而全的接口
interface Animal { void fly(); void swim(); }
// 正例:细化接口
interface Flyable { void fly(); }
interface Swimmable { void swim(); }
依赖倒置原则(DIP)
高层模块不应依赖低层模块,两者都应依赖抽象。
// 依赖抽象而非具体实现
class OrderService {
private final PaymentGateway gateway; // 接口注入
public OrderService(PaymentGateway gateway) {
this.gateway = gateway;
}
}
2. 高内聚低耦合
| 维度 | 高内聚 | 低耦合 |
|---|---|---|
| 含义 | 模块内部职责紧密相关 | 模块间依赖最小化 |
| 实现 | 单一职责、信息隐藏 | 接口隔离、依赖注入 |
| 收益 | 易理解、易维护 | 可独立演进、易测试 |
耦合度从低到高
无耦合 → 数据耦合 → 标记耦合 → 控制耦合 → 外部耦合 → 公共耦合 → 内容耦合
目标:模块间仅通过接口进行数据耦合。
3. 分层架构
经典三层架构标准化了职责边界:
┌─────────────────────────────────────┐
│ 表示层(Presentation) │
│ - Controller / Router / View │
├─────────────────────────────────────┤
│ 业务层(Business/Domain) │
│ - Service / Domain Model / Use Case │
├─────────────────────────────────────┤
│ 数据层(Data Access) │
│ - Repository / DAO / ORM │
├─────────────────────────────────────┤
│ 数据库(Database) │
└─────────────────────────────────────┘
依赖规则
上层依赖下层,下层不依赖上层。严禁跨层调用。
分层架构的演进
- 纯净架构:业务逻辑独立于框架、UI 和数据库
- 六边形架构:端口与适配器模式,强调可测试性
- 洋葱架构:以领域模型为核心,层层向外扩展
4. CAP 定理
在分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance) 三者不可同时满足,最多只能满足两项。
┌──────────┐
/ CAP \
/ \
Consistency ──── Availability
\ /
\ /
└ Partition┘
三种组合
| 组合 | 说明 | 适用场景 |
|---|---|---|
| CP | 牺牲可用性,保证一致性和分区容错 | 金融交易、库存扣减 |
| AP | 牺牲一致性(最终一致),保证可用性 | 社交网络、内容展示 |
| CA | 不处理分区,仅单机使用 | 非分布式系统 |
注意:分区容错性是分布式系统的固有属性,实际中的抉择往往是 CP vs AP。
5. BASE 理论
CAP 定理的实践延伸,面向高可用场景的权衡策略:
- Basically Available(基本可用):允许部分故障时的降级服务
- Soft state(软状态):允许数据存在中间状态
- Eventually consistent(最终一致):不保证实时一致,但最终会收敛
BASE vs ACID
| 特性 | ACID | BASE |
|---|---|---|
| 一致性 | 强一致 | 最终一致 |
| 可用性 | 事务期间锁定 | 优先可用 |
| 复杂度 | 简单(单节点) | 复杂(分布式) |
| 场景 | 关系型数据库 | 分布式/NoSQL 系统 |
6. 架构决策记录(ADR)
架构设计是持续的过程,ADR 是记录决策的标准格式:
# ADR-001: 采用微服务架构
## 状态
Accepted
## 上下文
业务快速增长,单体系统维护困难
## 决策
将核心服务拆分为独立的微服务
## 后果
+ 团队可独立部署
+ 技术栈可选
- 运维复杂度提升
- 分布式事务处理
总结
| 原则 | 核心要义 | 应用场景 |
|---|---|---|
| SOLID | 面向对象设计准则 | 代码级别架构 |
| 高内聚低耦合 | 模块边界清晰 | 组件划分 |
| 分层架构 | 职责分离 | 应用架构 |
| CAP | 分布式权衡 | 系统设计选型 |
| BASE | 最终一致性 | 高可用分布式 |
架构设计的本质,是在约束条件下持续做出最优技术决策的能力。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。