mardi 2 février 2016

How to design a public API to read configration settings?

This is a general design question. I have the following format configuration file and I'd like to design an API to read it. We should parse strings loaded from the config file and assign the converted values to the related typed objects (to int or string in this example). Parsing errors could occur during this process.

<configuration>
  <appSettings>
    <add key="countoffiles" value="7" />
    <add key="logfilelocation" value="abc.txt" />
  </appSettings>
</configuration>

I can think of two methods. What are the problems with these two designs? Any comments are appreciated.

One is template method pattern:

class Config
{
public:
    virtual bool ParseValues() = 0;
    virtual void SetDefaultValues() = 0;
    bool TrySetValuesOrDefault()
    {
        if (!ParseValues())
        {
            SetDefaultValues();
            return false;
        }
        return true;
    }
}

class IntType::Config
{
    string str;
public: 
    int output_int;
    IntType(string str){
         this.str = str;
    }
    bool ParseValue() 
    {
        return someParseFoo(str, output_int);
    }
    void SetDefaultValue() 
    {
        output_int = 3;
    }
}
class StringType::Config
{ // similar with IntType
}

Since the configuration file is supposed to be only read once at the beginning of the program, the singleton design pattern is desired too.

class Config
{
public:
   int output_int;
   string output_str;

   static Config *getInstantce(){
       static Config *instance;
       return instance;
   }
   bool ParseValues_Int()
   {
        return someParseFoo(str, output_int);
   }
   bool ParseValues_String()
   {
        return someParseFoo(str, output_Str);
   }
   void SetDefaultValues_Int() 
   {
       output_int = 3;
   }
   void SetDefaultValues_String() 
   {
       output_Str = "abcd";
   } 
   int getInt(string name, int default)
   {
       if (!ParseValues_Int())
       {
           SetDefaultValues_Int();
       }
       return output_int;
   }
   string getString(string name, string default)
   {// similar with getInt
   }

private:
   Config(){};
   Config(Config const&);
   void operator=(Config const&);
};

Aucun commentaire:

Enregistrer un commentaire