架构设计容易被讲得很玄:模式、视图、分层、DDD、CAP、微服务,每个词都很大。真正落到项目里,核心问题其实很朴素:职责怎么分,变化怎么隔离,失败怎么控制,团队能不能维护。
设计原则先服务可维护性
面向对象设计里的单一职责、开放封闭、里氏替换、依赖倒置、接口分离、组合复用,本质都是为了减少修改成本。
单一职责不是把类拆得越碎越好,而是让一个模块只有一个主要变化原因。开放封闭也不是禁止修改,而是把稳定部分和易变部分分开,让新增能力尽量通过扩展完成。
如果一个抽象让调用方更难理解,或者团队每次改动都要绕过它,那么这个抽象就没有真正服务架构。
Tier 和 Layer 不要混用
Layer 是逻辑分层,例如 Controller、Service、Repository。Tier 是物理部署层,例如 Web 节点、应用节点、数据库节点。
一个单体应用也可以有清晰的 Layer;一个分布式系统也可能逻辑层混乱。不要以为拆成多个服务就天然有架构,也不要因为还在单体里就放弃模块边界。
好的分层应该让依赖方向清楚:上层表达用例,下层提供能力,领域规则尽量不依赖具体框架和存储细节。
CAP 是取舍,不是口号
分布式系统里,网络分区一定可能发生,所以工程上经常是在一致性和可用性之间做选择。
强一致系统会在不确定时拒绝服务,典型是 ZooKeeper、etcd 这类协调组件。最终一致系统会优先响应,再通过重试、补偿、对账把数据修回来。
业务设计时要先问清楚:这件事能不能短时间不一致?用户能不能接受读到旧值?是否需要读自己写?这些答案比直接说“我们要 CP”或“我们要 AP”更有价值。
服务边界要和团队能力匹配
模块化和服务化能带来并行开发、独立发布、可观测、限流、熔断和灰度能力,但也会引入网络调用、超时、重试、数据一致性和排障成本。
拆服务前至少要确认:
- 这个边界是否有清晰业务语义。
- 数据是否能接受跨服务一致性方案。
- 接口是否能长期稳定。
- 团队是否有监控、日志、链路追踪和发布治理能力。
否则,拆服务只是把本地方法调用变成更脆弱的远程调用。
DDD 的价值在边界,不只在实体
DDD 常被误解成实体、值对象、聚合这些术语。它更重要的价值是限界上下文:同一个词在不同业务里可以有不同含义,不同上下文之间要通过清晰契约沟通。
战术建模可以帮助整理代码,战略建模更适合决定团队边界、服务边界和数据归属。项目早期不一定要完整套 DDD,但要避免一个“大而全模型”承载所有业务语义。
实用结论
好架构不是图画得复杂,也不是用了多少模式,而是能交付、能演进、能排障、能被团队理解。
职责清晰、依赖有方向、边界可解释、失败可控制,这些比名词更重要。每一次架构设计都应该回到一个问题:它是否降低了未来修改和维护的成本。




