I have an Abstract Base Class AbstractModel
class AbstractModel {
public:
struct predictionStructure{};
virtual predictionStructure predict(CompanyLib::Matrix<double> data) = 0;
std::string modelType;
public:
//constants
const uint32_t IMPORTER_VERSION = 1;
protected:
Preprocessor dataProcessor;//object calls func's to transform data. Children need capability, made into obj for SRP?
};
and child classes ABCModel
class ABCModel: AbstractModel {
public:
struct ABCPredictionStruct : AbstractModel::predictionStructure {
CompanyLib::Matrix<double> scores;
std::vector<double> q;
std::vector<double> tsqs;
};
ABCModel(std::ifstream & modelFile);
virtual predictionStructure predict(CompanyLib::Matrix<double> data) override;
private:
uint32_t varCount;
std::vector<double> otherData;
};
and XYZModel
class XYZModel: AbstractModel {
public:
struct XYZPredictionStruct : AbstractModel::predictionStructure {
CompanyLib::Matrix<double> y;
};
XYZModel(std::ifstream & modelFile);
virtual predictionStructure predict(CompanyLib::Matrix<double> data) override;
private:
CompanyLib::Matrix<double> means;
};
The problem is, I need to read the first ~64 bytes of an input file to decide which type of child class to construct, as it is a flag in the input file. While I could do this with a static function in AbstractModel
, I am trying to minimize the amount of concrete data/methods in the base class (Sr. Eng said to make it Pure Virtual Class but I need to require children to construct/use Preprocessor).
What is the best way to go about this? static protected function in AbstractModel? Make a ModelCreator class that handles file read & creation, and make AbstractModel more interface-like (called factory design pattern I think?).
I struggle a lot with designing a project structure, and this feels messy considering the Sr. Engineer said I should make AbstractModel a Pure Virtual Class/interface, and I have non-virtual things in it. If anyone can point out other mistakes I'm making in terms of best practices?
Preprocessor
) is generally not a good idea, and you should favour composition instead, which is possibly why the Sr. Engineer suggested a pure virtual class. That being said, it does not seem like it grants you any benefits for the problem you are describing.Preprocessor
just calls already-defined functions in a specified order, with specified arguments, upon model creation or model prediction.