Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
702 views
in Technique[技术] by (71.8m points)

c - Specific functions vs many Arguments vs context dependent

An Example

Suppose we have a text to write and could be converted to "uppercase or lowercase", and can be printed "at left, center or right".

Specific case implementation (too many functions)

writeInUpperCaseAndCentered(char *str){//..}
writeInLowerCaseAndCentered(char *str){//..}
writeInUpperCaseAndLeft(char *str){//..}
and so on...

vs

Many Argument function (bad readability and even hard to code without a nice autocompletion IDE)

write( char *str , int toUpper, int centered ){//..}

vs

Context dependent (hard to reuse, hard to code, use of ugly globals, and sometimes even impossible to "detect" a context)

writeComplex (char *str)
{    
    // analize str and perhaps some global variables and 
    // (under who knows what rules) put it center/left/right and upper/lowercase
}

And perhaps there are others options..(and are welcome)

The question is:

Is there is any good practice or experience/academic advice for this (recurrent) trilemma ?

EDIT:

What I usually do is to combine "specific case" implementation, with an internal (I mean not in header) general common many-argument function, implementing only used cases, and hiding the ugly code, but I don't know if there is a better way that I don't know. This kind of things make me realize of why OOP was invented.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'd avoid your first option because as you say the number of function you end up having to implement (though possibly only as macros) can grow out of control. The count doubles when you decide to add italic support, and doubles again for underline.

I'd probably avoid the second option as well. Againg consider what happens when you find it necessary to add support for italics or underlines. Now you need to add another parameter to the function, find all of the cases where you called the function and updated those calls. In short, anoying, though once again you could probably simplify the process with appropriate use of macros.

That leaves the third option. You can actually get some of the benefits of the other alternatives with this using bitflags. For example

#define WRITE_FORMAT_LEFT   1
#define WRITE_FORMAT_RIGHT  2
#define WRITE_FORMAT_CENTER 4
#define WRITE_FORMAT_BOLD   8
#define WRITE_FORMAT_ITALIC 16
....
write(char *string, unsigned int format)
{
  if (format & WRITE_FORMAT_LEFT)
  {
     // write left
  }

  ...
}

EDIT: To answer Greg S.

I think that the biggest improvement is that it means that if I decide, at this point, to add support for underlined text I it takes two steps

  1. Add #define WRITE_FORMAT_UNDERLINE 32 to the header
  2. Add the support for underlines in write().

At this point it can call write(..., ... | WRITE_FORMAT_UNLDERINE) where ever I like. More to the point I don't need to modify pre-existing calls to write, which I would have to do if I added a parameter to its signature.

Another potential benefit is that it allows you do something like the following:

#define WRITE_ALERT_FORMAT  (WRITE_FORMAT_CENTER | 
                             WRITE_FORMAT_BOLD |   
                             WRITE_FORMAT_ITALIC)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...