在KV存储项目中,随着引擎类型的增加,使用switch/case
或长串的if-else
来处理不同引擎的逻辑会导致代码臃肿、难以维护。以下是几种适合的设计模式及其实现方式:
1. 工厂模式(Factory Pattern)
核心思想:将引擎对象的创建逻辑封装到工厂类中,通过统一的接口创建不同引擎实例。
适用场景:需要动态选择或扩展多种引擎类型。
实现示例:
class KVEngine { public: virtual void Put(const std::string& key, const std::string& value) = 0; virtual std::string Get(const std::string& key) = 0; }; class RocksDBEngine : public KVEngine { /*...*/ }; class LevelDBEngine : public KVEngine { /*...*/ }; class KVEngineFactory { public: static std::unique_ptr<KVEngine> Create(EngineType type) { switch (type) { case EngineType::RocksDB: return std::make_unique<RocksDBEngine>(); case EngineType::LevelDB: return std::make_unique<LevelDBEngine>(); default: throw std::invalid_argument("Unknown engine type"); } } }; // 使用 auto engine = KVEngineFactory::Create(EngineType::RocksDB);
2. 抽象工厂模式(Abstract Factory Pattern)
- 核心思想:为引擎族(如基于磁盘的、内存的、分布式的)提供统一的创建接口。
- 适用场景:需要支持多类引擎族,且每族有多个子类。
- 优势:避免在客户端代码中硬编码具体引擎类型。
3. 策略模式(Strategy Pattern)
核心思想:将每种引擎的实现封装成独立的策略类,运行时动态切换。
适用场景:需要在运行时灵活切换不同引擎的行为。
实现示例:
class IKVStrategy { public: virtual void ExecutePut(const std::string& key, const std::string& value) = 0; }; class RocksDBStrategy : public IKVStrategy { /*...*/ }; class KVStore { std::unique_ptr<IKVStrategy> strategy_; public: void SetStrategy(std::unique_ptr<IKVStrategy> strategy) { strategy_ = std::move(strategy); } void Put(const std::string& key, const std::string& value) { strategy_->ExecutePut(key, value); } };
4. 注册表模式(Registry Pattern)
核心思想:通过全局注册表动态绑定引擎名称与创建函数,避免硬编码
switch/case
。适用场景:支持插件化或动态加载新引擎。
实现示例:
using EngineCreator = std::function<std::unique_ptr<KVEngine>()>; class EngineRegistry { std::unordered_map<std::string, EngineCreator> creators_; public: void Register(const string& name, EngineCreator creator) { creators_[name] = creator; } auto Create(const string& name) { return creators_.at(name)(); } }; // 注册引擎 registry.Register("rocksdb", []() { return make_unique<RocksDBEngine>(); }); // 使用 auto engine = registry.Create("rocksdb");
5. 依赖注入(Dependency Injection)
结合框架(如Google Guice或手动注入),将具体引擎实例从外部注入,解耦调用方与实现。
选择建议:
- 固定/少量引擎类型 → 工厂模式足够。
- 需运行时动态切换行为 → 策略模式。
- 支持插件化/动态扩展 → 注册表模式 + 配置文件。
通过以上模式可以消除冗长的switch/case
,提升代码的可扩展性和可维护性。
内容由零声教学AI助手提供,问题来源于学员提问