我正在编写一个通用软件,将加载到同一基本硬件的许多不同的变体.它们都具有相同的处理器,但具有不同的外设和自己的功能需要执行.该软件将通过读取硬件开关值来知道应该运行哪个变体.
这是我目前的实现:
class MyBase { public: MyBase() { } virtual run() = 0; } class VariantA : public MyBase { public: VariantA () { } virtual run() { // Run code specific to hardware Variant-A } } class VariantB : public MyBase { public: VariantB () { } virtual run() { // Run code specific to hardware Variant-B } } void main() { MyBase* variant; uint_8 switchValue = readSwitchValue(); switch(switchValue) { case 0: variant = new VariantA(); break; case 1: variant = new VariantB(); break; } variant->run(); }
现在这个工作很好我读取硬件值并使用switch语句创建新的对应类.
问题是有很多变种我必须处理.目前约有15个,有可能在不久的将来再增加20-30个.我真的来鄙视开关数十行的switch语句,所以我真的在寻找一个更好的方式来做到这一点,可能是通过模板.
我想要使用我的硬件值查找类型并使用该类型来创建我的新对象.理想情况下,当我添加一个新的变体时,我创建了一个新的类,将该类添加到查找表中,具有匹配的硬件值,而且很好.
这是可能的吗这里有什么好的解决方案?
解决方法
如上所述,你做一个工厂,但不一定是天真的switch语句.您可以做一个模板类来创建相关对象,并将它们动态地添加到工厂.
class VariantinatorBase { public: VariantinatorBase() {} virtual ~VariantinatorBase() {} virtual std::unique_ptr<Variant> Create() = 0; }; template< class T > class Variantinator : public VariantinatorBase { public: Variantinator() {} virtual ~Variantinator() {} virtual std::unique_ptr<Variant> Create() { return new T; } };
现在你有一个班级工厂,让你注册这些.
class VariantFactory { public: VariantFactory() { // If you want,you can do all your Register() calls in here,and even // make the Register() function private. } void Register( uint_8 type,std::unique_ptr<VariantinatorBase> creator ) { m_switchToVariant[type] = creator; } std::unique_ptr<Variant> Create( uint_8 type ) { TSwitchToVariant::iterator it = m_switchToVariant.find( type ); if( it == m_switchToVariant.end() ) return nullptr; return it->second->Create(); } private: typedef std::map<uint_8,std::unique_ptr<VariantinatorBase> > TSwitchToVariant; TSwitchToVariant m_switchToVariant; };
在程序开始时,创建工厂并注册您的类型:
VariantFactory factory; factory.Register( 0,new Variantinator<VariantA> ); factory.Register( 1,new Variantinator<VariantB> ); factory.Register( 2,new Variantinator<VariantC> );
然后,你想打电话给它:
std::unique_ptr<Variant> thing = factory.Create( switchValue );