应优先从主谓结构和交互关系识别类与职责:反复出现的实体名词可能成类,但需有状态和行为;动词驱动职责拆分,避免伪类和过早抽象;草图可快速验证类边界与协作关系。

看需求描述里的“名词”和“谁在干什么”
需求里反复出现的实体名词,大概率要变成类——比如“用户登录系统”,User、LoginService、Authenticator 都可能成类;但不是所有名词都该独立成类,得看它有没有自己的状态和行为。重点盯住带动作的主谓结构:“订单被取消”→Order 要有 cancel();“管理员审核申请”→Admin 和 Application 可能都需要,但更可能是 Application 自己提供 submitForReview(),而审核逻辑放在 ReviewService 里更合适。
警惕“伪类”:字符串、ID、配置项别硬凑成类
需求写“用户手机号必须是11位数字”,别急着建 PhoneNumber 类——除非你后续要频繁验证、格式化、脱敏、比较或跨模块复用。多数情况下,用 std::string 或 std::int64_t 存储更轻量。同理,“系统支持三种支付方式”不等于立刻写 Alipay、WechatPay、BankTransfer 三个类,先用 enum class PaymentMethod + 统一接口 PaymentProcessor 更灵活。过早拆分会导致类爆炸,且后期重构成本高。
从动词和交互关系反推职责边界
需求说“下单时检查库存、扣减库存、生成订单、发通知”,这串动作不能全塞进 Order 类。应该拆:InventoryService 负责库存检查与扣减,OrderFactory 或 OrderService 负责创建和持久化,NotificationService 处理通知。判断依据是:这个行为是否只跟当前数据强耦合?是否会被其他流程复用?是否涉及外部依赖(如数据库、消息队列)?满足任一,就该抽离。
-
InventoryService依赖数据库连接,Order不该持有它 -
NotificationService可能被退款、注册等多个流程调用,不该绑定到Order -
Order的核心职责只是表达“这是个订单”,含 ID、时间、商品列表、状态等字段
画草图比写代码更快暴露遗漏
拿笔在纸上写几个关键名词,用箭头标出“谁调用谁”“谁持有谁”。比如“用户提交订单 → 订单服务创建订单 → 订单服务调用库存服务 → 库存服务返回结果 → 订单服务决定是否继续”。这时候会发现:OrderService 是协调者,InventoryService 是能力提供者,两者都该是类;而“提交订单”这个动作本身,可能只是 OrderService::createOrder(const OrderRequest&) 一个函数,不需要额外类。草图里如果某个“类”周围没箭头、也没属性,大概率是多余的。
立即学习“C++免费学习笔记(深入)”;
真正难的不是找类,而是判断哪个类该管哪段逻辑、以及什么时候该让两个类协作而不是合并。很多设计问题,拖到写完第一版再改,代价远大于开头十分钟画张草图。


















