如何用设计模式解决子类仅需部分继承变量的赋值与调用问题?
解决方案:拆分字段+重写专属字段设置方法
针对你遇到的子类冗余继承字段、同时需要基类指针统一赋值的问题,可以通过拆分字段职责+模板方法模式的变种来解决,核心思路是让基类只管理公共字段,子类仅持有自身业务所需的字段,同时通过基类定义的统一入口完成子类字段的赋值。
具体实现步骤
- 拆分字段:将公共字段保留在基类,每个子类仅声明自己需要的专属字段
- 基类提供统一的字段设置入口,同时定义纯虚方法让子类实现自身字段的赋值逻辑
- 子类重写专属字段设置方法和业务逻辑方法,完成各自的职责
代码示例
首先用DTO封装全量数据库字段(避免参数过多,更易维护):
// 封装所有数据库字段的数据传输对象 struct RecordDTO { // 假设存在公共字段 int common_field; // Child1所需字段 int field1, field2, field3; // Child2所需字段 int field4, field5, field6; // Child3所需字段 int field7, field8, fieldN; };
重构基类Interface:
class Interface { public: // 仅保留公共字段 int common_field; // 统一的字段设置入口,接收全量DTO void SetFields(const RecordDTO& dto) { // 先设置公共字段 common_field = dto.common_field; // 调用子类的专属字段设置逻辑 SetSpecificFields(dto); } // 纯虚方法:子类实现自身专属字段的赋值 virtual void SetSpecificFields(const RecordDTO& dto) = 0; // 业务逻辑纯虚方法 virtual void Run() = 0; // 必须添加虚析构,避免基类指针释放子类对象时的内存泄漏 virtual ~Interface() = default; };
实现子类:
class Child1 : public Interface { private: // 仅持有自身需要的字段 int field1, field2, field3; public: void SetSpecificFields(const RecordDTO& dto) override { // 提取DTO中自身需要的字段赋值 field1 = dto.field1; field2 = dto.field2; field3 = dto.field3; } void Run() override { // 向接收方1发送field1、field2、field3及公共字段 // send_to_recepient1(field1, field2, field3, common_field); } }; class Child2 : public Interface { private: int field4, field5, field6; public: void SetSpecificFields(const RecordDTO& dto) override { field4 = dto.field4; field5 = dto.field5; field6 = dto.field6; } void Run() override { // 向接收方2发送field4、field5、field6及公共字段 } }; class Child3 : public Interface { private: int field7, field8, fieldN; public: void SetSpecificFields(const RecordDTO& dto) override { field7 = dto.field7; field8 = dto.field8; fieldN = dto.fieldN; } void Run() override { // 向接收方3发送field7、field8、fieldN及公共字段 } };
使用示例
int main() { // 从数据库读取全量记录,封装为DTO RecordDTO db_record{100, 1,2,3, 4,5,6, 7,8,99}; // 基类指针操作子类对象 Interface* child1 = new Child1(); child1->SetFields(db_record); // 自动完成公共字段+Child1专属字段的赋值 child1->Run(); Interface* child2 = new Child2(); child2->SetFields(db_record); child2->Run(); // 释放内存 delete child1; delete child2; return 0; }
方案优势
- 内存高效:每个子类仅持有自身业务所需字段,消除冗余内存占用
- 职责清晰:子类只关注自身业务逻辑,符合单一职责原则
- 统一接口:通过基类指针即可完成所有子类的字段赋值,无需感知具体子类类型
- 扩展性强:新增子类时,只需添加专属字段并重写两个方法,无需修改基类代码
内容的提问来源于stack exchange,提问作者user22343737
相关产品推荐
相关产品推荐

