vendredi 30 novembre 2018

Using factory when loading from file

I'm relativity new to C++ , though I do have some experience in java. Trying to approach to following problem ;(this is part of a bigger task from my university)

class myCustomer :public Customer {/.../}


class myEmployee :public Employee {/.../}

So Customer is an interface , and myCustomer is a derived class with the implementation ,same goes for employee .(i have to use it that way)

Followed by this (sort-of) an API for a flight company data base ;

class MyImplementation{
   //I want to link id's to an object so i can call id using a given id
   map <string,myCustomer*> customers_map;
   map <string,myEmployee*> employees_map;
...
   //must implement this function
   virtual Customer* addCustomer(string full_name, int priority){
    if(!customers_loaded){
        load_customers();
    }
    auto curr_customer = new myCustomer(id,full_name,priority);
    customers_map.insert(pair<string,myCustomer*>(id,curr_customer));
    }



    void load_customers(){
        vector<string> parameters;
        string line;
        fstream customers_file;
        customers_file.open(CUSTOMER_INFO_PATH,fstream::out);
        //check if null is returned
        if (!customers_file.is_open()) {
            throw "Error:cannot open employees file";
        }
        //iterate over lines
        while(getline(customers_file,line)){
            //just a function to split a line from file to a vector               
            parameters=splitLine(line,SPLITTER);
            try{
                customer_from_string(parameters);
            }catch(...){
                //could not load current object 
                cout << "Could not load customer "<< parameters[0] <<
                "(line number:"<< lineNumber << ")" <<endl;
                continue;
            }
        }
        customers_file.close();
    }


    void customer_from_string(vector<string> parameters){
        string id = parameters[0];
        string name = parameters[1];
        int priority = stoi(parameters [2];
        auto curr_customer = new myCustomer(id,name,priority);
        customers_map.insert(pair<string,myCustomer*>(id,curr_customer));
    }
    /** more code**/

So i have to do this to about 6 classes , each has its own constructor with different number of parameters. Trying to avoid this code duplication I understand i need to approach this using an Abstract factory design pattern. So i thought about implementing the following :

class Factory {
virtual void create(vector<string>& parameters,
                    map<string,Factory*>&id_map,/*..more parameters*/)=0;
 }

and let the load method decide which object to create (maybe send a char as identifier) , using the create method above, Let each class Implement the factory interface and than using the create function.So i think i need to change the maps to

 map <string,Factory *> objectName_map;

Now im kinda stuck since the map holdes A pointer to a factory object , and I want to use the maps id's to do the following :

virtual Customer* getCustomer(string id){   //must implement this function
    if(!customers_loaded){
        load('C');
    }
    return customers_map.find(id)->second;
}

And i cannot call any inner functions for each object ,after , lets say :

void setEmployer(Employee* employer){//...//}

Since the maps are holding a Factory* . I tried to keep the maps as they are but couldnt use them in a create function since it cannot convert a myCustomer* object to Factory* . Im kinda lost , tried to find solutions online but had no luck , though i feel im implementing this wrong. Thanks in advance for any help with this!

Aucun commentaire:

Enregistrer un commentaire