C++多地点数据处理重构咨询:基于基类拆分NY与AU处理逻辑
当然可行!用抽象基类拆分地点逻辑的重构方案
作为C++新手,能想到用基类拆分逻辑来写整洁代码,这思路非常棒!这正好对应面向对象里的开闭原则——对扩展开放,对修改关闭,再也不用在原有代码里硬加一堆if-else了。咱们一步步来拆解重构方案:
第一步:抽象地点相关的核心逻辑
首先,我们把和地点强相关的两个行为(解码特定字段、处理对应动作)抽象成一个基类,让不同地点的实现去继承它:
// 抽象基类:定义地点处理的通用接口 class LocationProcessor { public: virtual ~LocationProcessor() = default; // 虚析构函数,确保子类正确析构 // 解码当前地点特有的数据字段 virtual void decodeSpecificData(const std::string& data, DecodeData& decoder) = 0; // 处理解码完成后的特定动作 virtual void handleDecodedData(const DecodeData& decoder) = 0; };
第二步:为每个地点实现具体的处理器
接下来,分别给纽约和澳洲写具体的子类,各自实现自己的解码和动作逻辑:
纽约处理器
class NewYorkProcessor : public LocationProcessor { public: void decodeSpecificData(const std::string& data, DecodeData& decoder) override { // 原来DecodeData里处理纽约特有的key逻辑,比如key1、key2 if (data包含key1) { decoder.setValue1(对应值); } if (data包含key2) { decoder.setValue2(对应值); } } void handleDecodedData(const DecodeData& decoder) override { // 原来DataManager里判断XYZ的逻辑 if (decoder.getValue() == "XYZ") { doActionA(); } } };
澳洲处理器
class AustraliaProcessor : public LocationProcessor { public: void decodeSpecificData(const std::string& data, DecodeData& decoder) override { // 澳洲特有的解码逻辑,比如key3、key4 if (data包含key3) { decoder.setValue3(对应值); } if (data包含key4) { decoder.setValue4(对应值); } } void handleDecodedData(const DecodeData& decoder) override { // 澳洲对应的动作,比如doActionB、doActionC if (decoder.getOzValue() == "ABC") { doActionB(); } } };
第三步:重构原有类,依赖抽象而不是具体实现
现在我们把原有DecodeData和DataManager里的硬编码逻辑去掉,改成依赖上面的抽象基类:
重构DecodeData
让DecodeData只处理通用解码逻辑,地点特定的交给注入的Processor:
class DecodeData { private: // 假设原来的成员变量和getter/setter保留 std::string _value1; std::string _value3; // ...其他成员 public: // 通用解码逻辑(如果有的话) void decodeCommonData(const std::string& data) { // 处理所有地点都需要解码的字段 } // 对外的统一解码入口,调用通用+地点特定逻辑 void decode(const std::string& data, LocationProcessor& processor) { decodeCommonData(data); processor.decodeSpecificData(data, *this); } // 原有getter/setter保留 void setValue1(const std::string& val) { _value1 = val; } std::string getValue1() const { return _value1; } // ...其他getter/setter };
重构DataManager
同样,DataManager不再硬编码动作,而是调用Processor的处理逻辑:
class DataManager { private: std::shared_ptr<LocationProcessor> _processor; public: // 构造时注入对应的地点处理器 explicit DataManager(std::shared_ptr<LocationProcessor> processor) : _processor(std::move(processor)) {} void processData(const std::string& data) { DecodeData dd; dd.decode(data, *_processor); _processor->handleDecodedData(dd); } };
调整类A
类A可以保持简洁,只负责持有DataManager(顺便修正了原代码里的拼写错误:recieve→receive):
class A { public: void setDataManager(std::shared_ptr<DataManager> dm) { _dm = std::move(dm); } void receiveData(const std::string& data) { _dm->processData(data); } private: std::shared_ptr<DataManager> _dm; };
第四步:在main函数中根据配置注入对应处理器
最后,根据配置文件读取的地点类型,创建对应的Processor,再传给DataManager:
int main() { // 从ConfigManager读取地点类型 std::string location = ConfigManager::getLocationType(); // 根据地点创建对应的处理器 std::shared_ptr<LocationProcessor> processor; if (location == "NewYork") { processor = std::make_shared<NewYorkProcessor>(); } else if (location == "Australia") { processor = std::make_shared<AustraliaProcessor>(); } else { // 处理未知地点的默认逻辑 throw std::invalid_argument("Unsupported location type"); } // 组装依赖 std::shared_ptr<DataManager> dm = std::make_shared<DataManager>(processor); A a; a.setDataManager(dm); // 后续调用a.receiveData(data)即可自动适配对应地点逻辑 return 0; }
重构后的好处
- 可扩展性极强:新增其他地点(比如伦敦)时,只需要新增一个
LondonProcessor子类,完全不用修改原有DecodeData、DataManager的代码,完美符合开闭原则 - 职责更清晰:每个类只做一件事——DecodeData管通用解码,LocationProcessor子类管地点特定逻辑,DataManager管流程调度
- 代码更易维护:地点相关的逻辑都集中在各自的Processor里,不用在多个类里找分散的if-else
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

