I face a problem with derived classes having their own functions when using Factory Pattern. Please share how you design OOP in this case.
Assume I have a general class B, and many derived classes, named D1, D2, D3, etc. Each of these classes has its own function, named F1, F2, F3, etc. respectively. Using Factory Pattern, we will have a program like this:
class FactoryPattern {
static B* create(string type) {
if (type == "D1")
return new D1();
if (type == "D2")
return new D2();
...
}
};
However, B must have its virtual functions for all of the F, and for each of the derived classes, I will print (or throw an error or anything else) to prevent the user from using the functions.
With the below implementation, the program will scale tremendously, as when we need to implement a new function, for example, function F3 for class D3, we need to update the program for both D1 and D2.
class B {
protected:
virtual void F1() = 0;
virtual void F2() = 0;
};
class D1: public B {
public:
void F1() {
cout << "F1 from D1\n";
}
void F2() {
cout << "This function is not implemented\n";
}
};
class D2: public B {
public:
void F1() {
cout << "This function is not implemented\n";
}
void F2() {
cout << "F2 from D2\n";
}
};
I thought about using a general function for class B, and just overriding if needed in the derived class, however, when combining with Factory Pattern, the returned pointer calls directly to B::F1 and B::F2, which are not implemented.
class B {
protected:
void F1() {
cout << "This function is not implemented\n";
}
void F2() {
cout << "This function is not implemented\n";
}
};
class D1: public B {
public:
void F1() {
cout << "F1 from D1\n";
}
};
class D2: public B {
public:
void F2() {
cout << "F2 from D2\n";
}
};
Edit: The function F can take different types of parameters, and the naming is also specific, so I can not use a general function like foo.
Edit2: For a more detailed problem, let Inference be the general class (B), and I have 2 derived classes, named Classifier, and Detector. For initialisation, all of them take model_path, however, Detector can take the list of output information (bounding_box, label, etc.) in addition, then the initialisation of them will take different types of parameters. There are many other special functions, this is just an example.
class Inference {
public:
virtual void Initilisation(string model_path) = 0;
virtual void Initilisation(string model_path, vector<string> output_information) = 0;
};
class Detector: public Inference {
public:
void Initilisation(string model_path) {
cout << "Not implemented\n";
}
void Initilisation(string model_path, vector<string> output_information) {
// do some initialisation
// for example, output_information can be {"label", "conf", ...}
}
};
class Classifier: public Inference {
public:
void Initilisation(string model_path) {
// do some initialisation
}
void Initilisation(string model_path, vector<string> output_information) {
cout << "Not implemented\n";
}
};
Declaring a new function for each derived class kind of defeats to point of polymorphism. The usual way to go is to declare one
virtualfunction in the base class, then to override it in the derivatives with their own functionality.Example: