In factory design, when I create the new object with factory class I ask the user to his/her input and get the input from the user in factory class after that I create the object with these inputs.
Is it practicable to get the user input in factory class? How should I get user input in factory class?
The factory class is below;
Type *Factory::create_type(int Type){
switch(Type){
case 1:{
return new A(this->getUserTime(),this->getUserValue());
}
case 2:{
float min = this->getUserMin();
float max = this->getUserMax();
if(this->validMinMax(min,max))
return new B(this->getUserSpeed(),this >getUserValue(),min,max);
else
return NULL;
}
case 3:{
float min = this->getUserMin();
float max = this->getUserMax();
if(this->validUserMinMax(max,min))
return new C(this->getUserSpeed(),this->getUserValue(),max,min);
else
return NULL;
}
case 4:{
return new D(this->getUserDistance(),this->getUserSpeed(),this->getUserValue());
}
}}
One of inputs function in factory class;
float Factory::getUserValue(){
float m;
std::cout<<"\n enter value:";
std::cin>>m
return m; }
Short answer: No, don't get the user input in a factory class.
Long answer: Without more context (the project size for example would be interesting) it is difficult to give an advice for a part of a single class. But nevertheless consider the Single Responsibility Principle , one of the SOLID principles.
It tells us to give one module / class / function exactly one responsibility. So if you have a class that is a factory (one responsibility) and reads input from the user (second responsibility), that principle is violated.
Instead you should think of something similar to this
Type *Factory::create_type(int Type, const UserInput &input)
{
switch (Type)
{
case 1:
return new A(input.getTime(), input.getValue());
case 2:
float min = input.getMin();
float max = input.getMax();
/* and so on */
}
}
And some
class UserInput
{
public:
Time getTime() const;
float getMin() const;
float getMax() const;
/* and so on */
};
Alternatively the factory could have UserInput
as a constructor parameter so it is called like this
UserInput input;
// read input
auto Instance = Factory(input).create_type(3);
Doing this you follow another important principle, the Separation Of Concerns .
But, again, I cannot tell you what is best in your situation because I don't know the whole situation. You will find out ;-)
As others have suggested, if required, Your factory could take an input parameter to determine which instance to create. For example, for a simple Shape factory that creates different shapes, you could take a string/ Enum that determines which shape to create. But I would strongly suggest that your factory returns Unique Ptr by value to those instances, which is called a sink so that the memory is now managed and owned by the requestor.
class Shape
{
public:
virtual ~Shape() {}
virtual void draw() = 0;
};
class Circle : public Shape
{
public:
virtual void draw() override { // Implementation }
};
class Square : public Shape
{
public:
virtual void draw() override { // Implementation }
};
class ShapeFactory
{
public:
std::unique_ptr<Shape> createShape(const std::string& shapeType)
{
if(shapeType == "Circle")
return std::make_unique<Circle>();
else if(shapeType == "Square")
return std::make_unique<Square>();
else
return nullptr;
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.