c++ - How to design a public API to read configration settings? -
this general design question. have following format configuration file , i'd design api read it. should parse strings loaded config file , assign converted values related typed objects (to int
or string
in example). parsing errors occur during process.
<configuration> <appsettings> <add key="countoffiles" value="7" /> <add key="logfilelocation" value="abc.txt" /> </appsettings> </configuration>
i can think of 2 methods. problems these 2 designs? comments appreciated.
one 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 inttype }
since configuration file supposed read once @ beginning of program, singleton design pattern 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 getint } private: config(){}; config(config const&); void operator=(config const&); };
when designing configuration provider, should take consideration:
testability , injection
design can inject custom configurations in tests. a singleton object loads same xml file not enough this. tests, want able create custom configuration in test code, , inject class or module being tested. if xml, can use xml defining test configurations well. tests, define particular configuration should different default.
for injecting configurations application code, advisable use kind of ioc container, stores configuration. if working framework takes care of that, great. otherwise, not sure if there popular libraries this, start search existing code (see http://turncoder.blogspot.ru/2014/02/a-simple-c11-ioc-container-thats-all.html discussion on topic). such ioc container accessible globally, , typically expose methods fetching objects types.
immutability
as indicated, configuration immutable, should passed around const
object.
multiple config objects reduce coupling
don't create lots of single-field config objects, because need pass them around function arguments, , you'll functions lots of arguments. need choose whether put configurations in 1 object, or divide them smaller, more cohesive objects share topic. if you're not sure, start single configuration object, , see whether makes sense divide, each consumer of configurations configurations needs. thing single object makes easier pass configuration around. bad thing makes depend on 1 object.
support command-line arguments , environment variables
it helpful enable parse configuration not xml command-line and/or environment variables. makes easy start instances of application custom configurations, either manually or automatically, debugging or testing, without bothering edit xml file.
Comments
Post a Comment