You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用设计模式解决子类仅需部分继承变量的赋值与调用问题?

解决方案:拆分字段+重写专属字段设置方法

针对你遇到的子类冗余继承字段、同时需要基类指针统一赋值的问题,可以通过拆分字段职责+模板方法模式的变种来解决,核心思路是让基类只管理公共字段,子类仅持有自身业务所需的字段,同时通过基类定义的统一入口完成子类字段的赋值。

具体实现步骤

  • 拆分字段:将公共字段保留在基类,每个子类仅声明自己需要的专属字段
  • 基类提供统一的字段设置入口,同时定义纯虚方法让子类实现自身字段的赋值逻辑
  • 子类重写专属字段设置方法和业务逻辑方法,完成各自的职责

代码示例

首先用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:53:18