首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >软件设计实战:先定边界,再写代码

软件设计实战:先定边界,再写代码

原创
作者头像
资源shanxueit.com
发布于 2026-10-12 11:30:01
发布于 2026-10-12 11:30:01
30
举报

一、设计的核心:把变化关进接口里

业务里永远有稳定部分和变化部分。

比如订单结算,稳定的是“下单、扣款、返回结果”;变化的是“用支付宝、微信、银行卡还是积分支付”。

如果直接在核心逻辑里写:

代码语言:javascript
复制
if pay_type == "alipay":
    ...
elif pay_type == "wechat":
    ...

每新增一种支付方式,都要改核心代码。这就是把变化放进了稳定模块,迟早会失控。

更好的做法是:核心业务依赖抽象,具体实现依赖抽象。

下面这段代码很少,但能说明问题:

代码语言:javascript
复制
from typing import Protocol

class Payment(Protocol):
    def pay(self, amount: float) -> str: ...

class Alipay:
    def pay(self, amount: float) -> str:
        return f"支付宝支付 {amount}"

class Wechat:
    def pay(self, amount: float) -> str:
        return f"微信支付 {amount}"

class OrderService:
    def __init__(self, payment: Payment):
        self.payment = payment

    def checkout(self, amount: float) -> str:
        return self.payment.pay(amount)

# 使用
OrderService(Alipay()).checkout(99.0)

这段代码的关键不是“用了策略模式”,而是:

  • OrderService 不知道支付宝、微信的存在;
  • 新增支付方式,只加一个新类;
  • 测试时可以注入 FakePayment;
  • 核心业务没有被外部渠道污染。

这就是设计:把变化关进接口里,让核心保持稳定。


二、四个关键设计决策

1. 模块边界按业务分,不按技术分

不要一上来就 controller、service、dao 三件套。 更好的切分是:订单、支付、库存、履约、结算。

技术分层是横向的,业务能力是纵向的。纵向边界清楚,改动才不会到处漏。

2. 契约先行,接口比实现长寿

设计接口时,重点写清楚:

  • 输入输出是什么;
  • 错误怎么表达;
  • 是否幂等;
  • 版本怎么兼容;
  • 超时和重试怎么办。

实现可以换,契约不能随便碎。

3. 依赖方向要朝稳定侧

业务核心不应该依赖数据库、Web 框架、消息队列、UI。 它们应该是插件,而不是地基。

这就是依赖倒置:稳定模块定义接口,易变模块实现接口。

4. 数据所有权要清楚

谁写谁负责。 不要让三个模块同时写同一张表,否则边界只是纸面上的。


三、常见误区

  • 过度设计:为不存在的扩展点提前抽象,结果代码更复杂。
  • 贫血模型:业务规则全散在 Service,领域对象只是数据袋子。
  • 迷信微服务:单体都没设计好,拆成微服务只会把混乱放大。
  • 忽略非功能:性能、安全、可观测性不是上线前补的,是设计的一部分。
  • 把设计模式当目标:模式是结果,不是起点。隔离变化才是目的。

四、落地时只问三个问题

每次设计评审,不用讲太多术语,只问:

  1. 边界在哪? 这个模块负责什么,不负责什么?
  2. 依赖方向对不对? 核心业务有没有依赖具体框架、数据库或第三方?
  3. 变化来时改哪里? 新增一个渠道、换一个存储、改一个规则,需要动几个文件?

如果第三个问题答案是“只改一个地方”,设计通常不会太差。


五、总结

软件设计不是画图,而是决定:什么和什么耦合,什么和什么隔离。

少量代码就能展示核心思想: 接口隔离变化,依赖倒置保护核心,边界控制复杂度。

好的设计,让改需求像换插头; 差的设计,让改需求像拆房子。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、设计的核心:把变化关进接口里
    • 二、四个关键设计决策
      • 1. 模块边界按业务分,不按技术分
      • 2. 契约先行,接口比实现长寿
      • 3. 依赖方向要朝稳定侧
      • 4. 数据所有权要清楚
    • 三、常见误区
    • 四、落地时只问三个问题
    • 五、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档