在设计用于配置库/实用程序的C API时,我有一个同事喜欢将所有配置参数集中到一个函数调用中。例如:
int set_diagnostic_email_config( char *to_address,
bool include_timestamp,
bool send_for_crashes,
bool send_daily_status,
bool send_on_event1,
bool send_on_event2 )有一个类似的"get“函数,它有很多参数。这种方法的主要优点是,如果有人添加了一个新的选项,例如"bool send_on_event3",那么因为原型改变了,所以您必须更新使用此函数调用的每个地方(假设有多个地方有人调用此函数)。
我更喜欢这样的东西:
int get_diagnostic_email_config( struct email_config *p_config );
int set_diagnostic_email_config( struct email_config *p_config );您只需根据需要更改结构元素即可。但是..。如果有人更新了email_config的结构,它不会强迫人们更新所有使用它的地方(尽管我们经常想这样做)。另外,我的同事抱怨说,如果有人只是试图手动初始化"email_config“,那么如果后来添加了一些东西,那么这些新字段将不会被初始化,没有任何警告。
对于哪种方法是首选的,有没有强烈的共识?或者也许我错过了另一种选择?
发布于 2009-07-03 05:38:05
一个结构比一个长列表要好。长长的列表很难维护,因为没有人记得确切的顺序。
您可以创建一个用安全(默认和/或无效)项填充此结构的构造函数。总是(可能在存取器函数中)检查无效值,这样可以很容易地在初始化过程中发现错误。
你可以在这个结构中隐藏一个神奇的数字。第一个字段是CONFIG_MAGIC,它需要等于您定义的常量。您在构造函数中设置此字段,并期望在任何时候都设置。这就避免了有人仅仅通过malloc()对结构进行手动初始化。这样的程序员需要了解这个CONFIG_MAGIC常量,并且很可能找到并使用正确的构造函数。
发布于 2009-07-03 06:01:22
我将使用下面的方式,它是您的方式的扩展。
struct INFO
{
char *to_address;
bool include_timestamp;
bool send_for_crashes;
bool send_daily_status;
bool send_on_event1;
bool send_on_event2;
};
struct INFO *createINFO()
{
// initialize to defaults.
// return a pointer to the new created struct.
}
void include_timestamp(struct INFO *info, bool vInclude_timestamp)
{
// set the field.
}
// add the required setters...
void destroyINFO(struct INFO *info)
{
// destroy the struct.
}这样,无论何时添加新字段,您都可以按需添加“setters”。而不允许用户扰乱结构本身。
发布于 2009-07-03 05:31:15
在所有地方更新函数调用怎么会是件好事呢?当然,您应该使用新的更新头重新构建所有内容,但理想情况下,每次更改配置时,您都希望尽可能少地更改代码。
https://stackoverflow.com/questions/1077877
复制相似问题