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

非虚接口中带链式方法的Getter实现方案问询

实现方案

核心思路

不需要额外存储全局/外部map,也无需修改工厂函数,核心是通过在基类Foo中新增非虚接口Get,返回一个类型转换代理类的方式实现链式调用。代理类持有从map中取出的原始字符串值,提供AsString()、AsInt()等类型转换方法,既保留NVI模式的封装性,又满足链式调用需求。

具体实现步骤

1. 定义类型转换代理类

这个类负责存储原始字符串,并提供各种类型转换逻辑,可按需扩展转换方法:

class ValueProxy {
private:
    std::string m_rawValue;
public:
    explicit ValueProxy(std::string val) : m_rawValue(std::move(val)) {}

    // 返回原始字符串
    std::string AsString() const {
        return m_rawValue;
    }

    // 转换为int,可根据业务需求添加错误处理(如格式校验、默认值)
    int AsInt() const {
        return std::stoi(m_rawValue);
    }

    // 扩展其他类型转换,比如double、bool
    double AsDouble() const {
        return std::stod(m_rawValue);
    }
};

2. 扩展基类Foo的NVI接口

在基类中新增公共非虚方法Get,调用私有虚函数获取对应字符串值,再包装成代理类返回:

class Foo {
public:
    // 原有NVI接口
    void save_to_map() {
        getRecord();
    }

    // 新增链式调用的NVI接口
    ValueProxy Get(unsigned int key1, const std::string& key2) {
        return ValueProxy(getTargetValue(key1, key2));
    }

private:
    // 原有私有虚函数:负责填充子类内部的map
    virtual void getRecord() = 0;

    // 新增私有虚函数:子类实现双key的查找逻辑
    virtual std::string getTargetValue(unsigned int key1, const std::string& key2) = 0;
};

3. 修改子类Bar实现虚函数

子类Bar复用原有的map存储SQL查询结果,新增getTargetValue的实现来完成双key的查找:

class Bar : public Foo {
private:
    std::map<std::pair<unsigned int, std::string>, std::string> m_dataMap;

    void getRecord() override {
        // 原逻辑:通过SQLite的tableSelect填充m_dataMap
        // 示例:
        // m_dataMap[{0, "A"}] = "test_string";
        // m_dataMap[{0, "B"}] = "456";
    }

    std::string getTargetValue(unsigned int key1, const std::string& key2) override {
        auto iter = m_dataMap.find({key1, key2});
        if (iter != m_dataMap.end()) {
            return iter->second;
        }
        // 可根据需求返回默认值或抛出异常
        return "";
    }
};

4. 调用方式

工厂函数完全不需要修改,创建对象后直接使用链式接口:

std::unique_ptr<Foo> p = createFoo(); // 原工厂函数逻辑不变
p->save_to_map(); // 先执行数据填充
std::string strResult = p->Get(0, "A").AsString();
int intResult = p->Get(0, "B").AsInt();

方案优势

  • 严格遵循NVI模式:基类控制对外接口,子类仅实现内部逻辑,封装性不受破坏
  • 无额外存储成本:复用子类原有的map存储查询结果,无需新增全局或外部容器
  • 扩展性强:新增类型转换只需在ValueProxy中添加对应方法,无需修改核心业务逻辑
  • 语义清晰:链式调用的写法直观,符合业务代码的阅读习惯

内容的提问来源于stack exchange,提问作者Namal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 04:05:19