vendredi 7 mai 2021

What is the best way to initialize a more complex class construct with many unchangeable members in c++

I'm currently designing classes that should represent a chaotic storage system.

Lets say we have slots in rows and columns with certain properties. So the slots have different restrictions in min/max height, width, length, weight and some more that come from a parameter file. Also the Slots have a max total weight that must be checked before a new parcel gets added to that slot. And also the max weight that a row of slots can hold is lower than the sum of the max weights of the single slots. So for example each individual slot might be able to hold 50kg but the row of 10 slots must not exceed 200kg, so it is not allowed to fill every slot by 100%. The same is true for the Columns where the maximum weight is lower than the sum of the individual weights of the single rows. The row_id and column_id are atrificial numbers for adressing the slot in the physical system with barcodes or whatever that get read for positioning.

As all this parameters do not change over the lifetime of the program, my intention was to design the classes in a way that this properties are readable by getter functions but there should not be any setter functions (maybe not even private ones) in the object o the values cannot be changed by accident.

There is one class/function that reads the config-file and generates the data structure for the rows and columns with the slots. This function should be able to read the config and create objects for every column holding a row of slots and pass all the values from the config down to the slot.

Later when the program is running I also need some way to search for the best matching slot to add the next parcel or for searching parcels and unload them in a certain sequence.

So the (simplfied) basic structure of the classes would be like this:

Class Parcel {
  int width;
  int height;
  int length;
  int weight;
}

Class Slot {
  vector<Parcel> parcel;

  int min_width;
  int max_width;
  int min_height;
  int max_height;
  int min_length;
  int max_length;

  int max_total_weight;
  int act_total_weight;
  int total_length;
  int free_length;
}

Class Row {
  vector<Slot> slot;

  int row_id;
  int max_total_weight;
  int act_total_weight;
}

Class Column {
  vector<Row> row;

  int column_id;    
  int max_total_weight;
  int act_total_weight;
}

Class Storage {
  vector<Column> column;
}

So here are my thoughts about how to initialize the data structure:

First possibility would be to pass all the properties in the constructor(s) of the classes, but then the constructors has some huge parameter lists specially for the Slot class that has a lot of properties.

Second thing that came to my mind (and currently my fafourite way to go) is to use config-data-structures that hold all the parameters. This parameter-objects get filled by the config-function and passed to the constructor when initializing the class. Then it also may be useful to use the parameter class as such and not having all the parameters defined in the storage class once more.

Third way is to use private setter and public getter and make the config class friends with the data structure classes to be able to access the setter functions (but i would prefer to have no setters at all in the final storage structure classes.

Fourth way that i was thinking off, was to derive child classes from the structure classes that hold the setter functions (and also some other logic needed for creating the data structure) so the child has no own variables but only additional functions. So the child class is used to fill the properties but the base class gets added to the data structure vector.

I also want to use Factory pattern to initialize the data structure because the objects have often similar or only slightly different properties. So with the second aproach after creating one row of slots I would maybe want to change the max weight of the slots in that row. Therefore I would need to change the setting in the factory and the factory then fills the parameter data structure differently and passes it to the Slot class. Or is it better to pass the data structure to the factory directly and the factory assigns it but then i think this is not what the factory pattern is meant to be.

I don't know if this is a good aproach or which of the above is best practice. Or am I missing something and there is a way more convenient solution or this?

Thank you (and sorry if the question is maybe not the way it should be)

Aucun commentaire:

Enregistrer un commentaire