tags:

views:

66

answers:

3

There are two obvious ways in C to provide outside access to internal attribute values (A) provide a generic interface that accepts a list of attributes that changes over time (some added / some die) or (B) a specific interface for each and every attribute.

Example A:

int x_get_attribute_value(ATT att)
{
    if (a) return a_val;
    if (b) return b_val;
}

Example B:

A_Enum x_get_a_type_attribute() {}
B_Enum x_get_b_type_attribute() {}

I recall that Eclipse's API is very much like A (I could be wrong). What I can't do is come up with a compelling argument against either.

A is clean - any user will no where to go to find out a property value. It can evolve cleanly without leaving dead interfaces around.

B has type checking to a degree - this is C enums!

Is there a big hitter argument that pushes the balance away from opinion?

A: 

B has much greater overhead for the introduction of new attributes. Introducing a new attribute into stable branch of software would bear many risks, as one would have to essentially change the interface.

Based on my personal experience, in general, I would vouch for A.

A lot also depends on how tight the software is integrated. Borrowing Booch's terminology, option A promotes weak coupling while B promotes strong coupling between the software components.

If you want to be able to freeze the interface, making it stable over long period of time, forbidding any changes, then B would allow you to do that: adding new attribute is highly visible. If you want to be able to add a new attributes any time you want, when you expect to have tons of them, then option A is obvious favorite.

You might also consider a healthy mix of the two. For important attributes to have dedicated get/set function. For the rest of less important options to use the generic get/set function. If an attribute becomes important, dedicated get/set could be introduced for it.

N.B. Obviously one shouldn't forget about performance: option B would win A in any microbenchmark.

Dummy00001
A: 

A is your best bet because you can more easily change the mechanism behind it. You could have a ladder of ifs, an array of acceptable attributes to loop through, or a hash table and no-one would be any the wiser.

SpacedMonkey
A: 

If you want to support options of various types (integers, strings, etc.), then A is a non-starter, because C functions can only return a value of one type. You can of course have the function return a void* and typecast the result, but that is just asking for trouble.

In short, if you want/need to support multiple types of options, solution B is the way to go.

Bart van Ingen Schenau