最常用继承写法是公有继承抽象基类,统一契约、收敛差异、降低耦合;基类仅定义状态字段、声明抽象行为、封装标准流程,子类专注业务实现,配套工厂与规范保障可维护性。

最常用继承写法在大规模团队协同开发中,核心是用公有继承 + 抽象基类统一契约、收敛差异、降低耦合。不追求语法炫技,重在让所有人“一眼看懂边界、一写就对行为、一改全链生效”。
明确抽象基类的职责边界
基类只做三件事:定义状态字段、声明抽象行为、封装标准流程。不写业务逻辑,不暴露实现细节。
- 字段统一管理:如
id、status(枚举)、creator、updatedAt——全部设为protected,子类可读可赋值,外部不可直接操作 - 强制子类实现:用
virtual ... = 0声明validate()(参数校验)、executeImpl()(核心动作)、onComplete()(收尾通知)——名字带Impl或Hook后缀,团队一看就知道这是“留给你填空的地方” - 提供不可重写的模板方法:如
run()内部按“校验→执行→持久化→触发回调”顺序调用上述抽象方法,子类只能调用,不能覆盖
子类只专注“这一节点该干什么”
每个具体类命名体现业务语义,代码里只出现和自身强相关的判断与调用。
-
OrderPaymentNode:重写validate()检查支付金额是否超单日限额;executeImpl()调第三方支付SDK;onComplete()发MQ更新订单状态 -
ContentAuditNode:validate()查敏感词库版本是否最新;executeImpl()调AI审核服务;onComplete()记录人工复审入口URL - 所有日志打点、事务控制、异常分类包装、监控埋点——均由基类
run()统一完成,子类无权绕过
配套协作规范比代码更重要
基类定得好,团队才能不跑偏。需同步落地几条硬约束:
- 新增节点必须继承该基类,禁止直接实现接口或从零写类——CI流水线自动扫描,未继承则编译失败
- 子类构造函数第一行必须调用基类初始化列表(如
: WorkflowNode(id, creator)),确保基础字段必填 - 基类新增抽象方法前,必须发起RFC文档评审,列出所有已存在子类的影响点及迁移方案
- 基类
protected字段不允许在子类中重新声明同名变量——避免隐藏导致状态不一致
用工厂+类型注册解耦实例创建
运行时根据流程配置动态创建节点,避免if-else硬编码,也方便灰度和替换。
- 定义统一工厂接口:
std::unique_ptr<workflownode> createNode(const std::string& type)</workflownode> - 各子类在模块初始化时注册自身类型,如
NodeFactory::registerType("payment", []{ return std::make_unique<orderpaymentnode>(); });</orderpaymentnode> - 流程引擎只需传入字符串
"payment",工厂返回多态对象,后续全走基类run()——子类变更不影响调度层










