我正在设计一个创建一系列类并管理它的库。我需要设计用于从类中实例化实例的配置类。这个配置类只是配置信息。
设计配置类的最佳方法是什么? config类是否应包含创建族中任何类的对象所需的信息的超集?或者,是否存在镜像实际类层次结构的类层次结构。
一个具体的例子。假设我有一个名为animalManager
的库,它根据用户配置创建各种动物并管理:
class animal { // Animal base class
public:
animal(bool isHerbivore, bool isMammal, bool isNocturnal) :
mIsHerbivore(isHerbivore), mIsMammal(isMammal), mIsNocturnal(isNocturnal) { }
virtual ~animal() { }
// methods that do stuffs..
private:
bool mIsHerbivore;
bool mIsMammal;
bool mIsNocturnal;
};
class snake : public animal { // Snake animal
public:
snake(bool isHerbivore, bool isMammal, bool isNocturnal, bool haveHood) :
animal(isHerbivore, isMammal, isNocturnal), mHaveHood(haveHood) { }
virtual ~snake() {}
private:
bool mHaveHood;
};
class fish : public animal {
public:
fish(bool isHerbivore, bool isMammal, bool isNocturnal, int numFins) :
animal(isHerbivore, isMammal, isNocturnal), mNumFins(numFins) {
}
virtual ~fish() {}
private:
int mNumFins;
};
// Cat, parrot, elephant, so on
class animalConfig { // User settings to create animals
// What is the best way to design this class (/hierarchy) ?
};
class animalManager
{
public:
animalManager() {}
~animalManager() {}
animal* createAnimal(animalConfig *settings) {
// Create and return animal
}
// So on
};
在上面的示例中,snake
和fish
需要在animal
config之上添加其他配置。如何表示这些配置?
答案 0 :(得分:1)
我建议有一个meta_class实例,工厂函数在配置解析和生成真正的动物类时使用,而animalConfig
只是一个流。每个真实类都有一个meta_class对象。
class base_animals;
struct meta_base
{
static std::vector< meta_base* > meta_base_list;
meta_base(...):fn_(...), recognition_data_(...) { meta_base_list.push_back( this ); }
std::unique_ptr< base_animals > fn_( animalConfig * );
std::string recognition_data_;
};
class rabbit: public base_animal
{
static meta_base mb;
static std::unique_ptr< base_animals > make_bunny( animalConfig * );
...
};
// In source file
meta_base rabbit::mb( &rabbit::make_bunny, "rabbit" );
然后你有一个animal* createAnimal(animalConfig *settings)
可以用来实例化任意动物类型的元对象列表。
for( auto meta* : meta_base::meta_base_list )
{
if( settings->section_label() == meta->recognition_data_ )
{
return *(meta->fn_)( settings );
}
// Handle case where no meta class found
}
此输入数据可以是包含以下文本的流:
section rabbit
length X
weight Y
end
animalConfig搜索文本“section”并获取标签“rabbit”(它存储并从section_label()
返回),然后rabbit :: make_bunny方法负责解析特定于兔子的值。我不认为尝试使用所有特定数据的超集创建一个animalConfig类更容易。