jeudi 31 mars 2016

Overall configuration object for a god object and late initialisation

There are two main parts to this question: storing configuration values in a single file/place and delaying initialisation of a contained object.

I have an embedded program which controls a PCB test fixture for a semi-automated test. I would like to store all of the limits/test parameters in a single place (preferably as read only/constants) so that they can be easily located and tweaked in the future. The problem is that some of the values are within nested structs and the only way that I know of initialising these objects is using the dreaded initialiser list where all traceability is lost (or a constructor which is almost as bad).

e.g.

class Configuration {

public:
  struct NestedStruct {
    float value1;
    float value2;
    float value3;
  };

  struct ContainerStruct {
    int value1;
    float value2;
    NestedStruct nested1;
    NestedStruct nested2;
    NestedStruct nested3;
    float value3;
  };

  // Initialise struct data member.
  // Not obvious which value is which?
  constexpr static const ContainerStruct containerStruct {5, 2.3, 1.4, 4.2, 0.7, 3.5, 2.5, 3.5, 0.2, 0.2, 0.1, 4.6};

};

How can I store read only configuration values made up of complex/nested struct values in one place while maintaining readability?

I've decided to wrap the core functionality into a single controller object that instantiates multiple contained objects. One of these objects is passed to some of the other objects via a pointer. I use the configuration values mentioned above (for which there are lots!) to initialise these objects.

Using an initialiser list makes the constructor of the Controller class long and untidy. One way I could get around this is by creating a default initialiser for the contained objects that which a separate initialiser function which I can call in the body of the Controller's constructor.

I've always read that two step/ lazy initialisation is bad as the object isn't immediately usable. Is there another way around this?

Maybe there is a better way than wrapping it in a god object?

Example parameters that I want to store in one place:
Adc object parameters:

float voltageReference;
uint8_t slaveSelectPin;

NavigationButtons object parameters:

struct AdcValues {
  uint_fast16_t buttonUp;
  uint_fast16_t buttonDown;
  uint_fast16_t buttonLeft;
  uint_fast16_t buttonRight;
  uint_fast16_t buttonCentre;
  uint_fast8_t tolerance;
};

UutPower object parameters:

struct CurrentCompensation {
  float LowX;
  float LowC;
  float MidX;
  float MidC;
  float HighX;
  float HighC;
};

VoltageTests object parameters:

struct TestParameter {
  float scalingFactor; // Potential divider scaling for voltages >voltageRef.
  float limitLower;
  float limitUpper;
  const char *signalName;
};

// Lots of nested structs.
struct TestParameters {
  TestParameter tb1_1;
  TestParameter tp15;
  TestParameter tp4;
  TestParameter tp1;
  TestParameter tp3;
  TestParameter tp20;
  TestParameter tp12;
  TestParameter tp29;
  TestParameter tp28;
  TestParameter con3_6;
  TestParameter con3_2;
}

Other parameters:

float currentLimitLow;
float currentLimitHigh;
const char *version; 

Any help appreciated.

Aucun commentaire:

Enregistrer un commentaire