简体   繁体   中英

Get the user input for factory class in C++

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM