应先识别对象再设计流程,因流程易变而对象职责稳定;需从需求中提取实体名词,判断其状态、变化性与决策权,并明确对象间消息契约以实现高内聚低耦合。

先找对象,不是先写流程。
为什么不能从流程出发写C++面向对象程序
面向过程习惯从“先做什么、再做什么”拆解业务,比如“用户登录→验证密码→查权限→跳首页”。但一上来就写流程,容易把 login、verifyPassword、checkPermission 写成独立函数,数据(如用户名、token、角色)散落在参数或全局变量里——这直接违背封装原则,后续加日志、换认证方式、支持多因子时,改一处牵全身。
更现实的问题是:流程本身会变。今天登录走账号密码,明天加微信扫码,后天要对接LDAP。如果逻辑绑在函数调用链上,每次需求变更都得重排主函数调用顺序;而如果先识别出 User、Authenticator、SessionManager 这些对象,它们的职责边界清晰,替换 Authenticator 的具体实现(比如从 PasswordAuth 换成 WeChatAuth)就不会影响 User 或 SessionManager 的代码。
- 流程驱动 → 函数堆砌 → 数据裸露 → 修改成本高
- 对象驱动 → 职责分离 → 接口稳定 → 替换/扩展只动一个类
怎么快速找准关键对象
别想“系统里该有哪些类”,直接翻需求文档或用户故事,圈出所有名词,过滤掉临时量和冗余词:
- 保留实体类:
User、Order、PaymentGateway、InventoryService - 剔除动词/形容词化名词:
Validation(应为Validator对象的行为)、Processing(模糊,没主体) - 警惕“管理器”“处理器”后缀:
OrderManager很可能是伪对象,真正职责可能属于Order自身或OrderRepository
然后问每个名词:它有没有独立的状态?会不会随时间变化?有没有自己决定怎么做事的权力?比如 ShoppingCart 有商品列表、总价、有效期——是对象;calculateTotal 是它的行为,不是新对象。
对象之间怎么协作,而不是谁调用谁
找到对象后,重点不是画调用图,而是定义它们之间的消息契约。例如:
-
User不直接操作数据库,而是向UserRepository发送save()消息 -
Order不自己校验库存,而是询问InventoryService的isAvailable(productID, quantity)返回布尔值 -
PaymentGateway不暴露sendRequest()细节,只承诺charge(amount, cardInfo)成功返回TransactionID
这种设计下,main() 或控制器层只剩几行组合代码,比如 order.place(); payment.charge(...); ——流程退居幕后,对象才是主角。
最容易被忽略的是:对象不是名词列表,而是带边界的**责任单元**。一个 Logger 类如果同时负责格式化、输出到文件、推送告警,它就过载了;拆成 LogFormatter、FileAppender、AlertDispatcher 才算真正面向对象。边界模糊,后面加新日志源或换格式时,改一个地方就得看全类。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











