Webinar: Evaluation - 05.12
Suppose, you need to implement an X functionality in your project. Theorists of software development will say that you have to take the already existing library Y, and use it to implement the things you need. Suppose, you need to implement an X functionality in your project. Theorists of software development will say that you have to take the already existing library Y, and use it to implement the things you need. In fact, it is a classic approach in the software development - reusing your own or others' previously created libraries (third-party libraries). And most of the programmers go this way.
However, those theorists in various articles and books, forget to mention what hell it will become to support several dozens of third-party libraries, existing in your project in about 10 years.
I strongly recommend to avoid adding (choking a project with libraries) a new library to a project. Please don't get me wrong. I am not saying that you shouldn't use libraries at all and write everything yourself. This would be stupid, of course. But sometimes, a new library is added to the project at the whim of some developer, intending to add a little cool small "feature" to the project. It's not hard to add a new library to the project. But then the whole team will have to carry the load of its support for many years.
Tracking the evolution of several large projects, I have seen quite a lot of problems caused by a large number of third-party libraries. I will probably enumerate only some of the issues, but this list should already provoke some thoughts:
Again, I should emphasize. I don't say that we should stop using third-party libraries at all. If we have to work with images in PNG format in the program, we'll take the LibPNG library and not reinvent the wheel.
But even working with PNG we need to stop and think. Do we need a library? What do we want to do with the images? If the task is just to save an image in *.png file, you can get by with system functions. For example, if you have a Windows application, you could use WIC. And if you're already using a MFC library, there is no need to make the code more sophisticated, because there's a CImage class (see the discussion on Stack Overflow). Minus one library-great!
Let me give you an example from my own practice. In the process of developing the PVS-Studio analyzer, we needed to use simple regular expressions in a couple of diagnostics. In general, I am convinced that static analysis isn't a right place for regular expressions. This is an extremely inefficient approach. I even wrote an article regarding this topic. But sometimes you just need to find something in a string with the help of a regular expression.
It was possible to "squeeze in" an existing libraries.
It was clear that all of them would be redundant, but regular expressions were still needed and we had to come up with something.
Absolutely coincidentally, exactly at that moment I was reading a book "Beautiful Code" (ISBN 9780596510046). This book is about simple and elegant solutions. And there I came across an extremely simple implementation of regular expressions. Just a few dozen of strings. And that's it!
I decided to use that implementation in PVS-Studio. And you know what? The abilities of this implementation are still enough for us. And some complex regular expressions are just not necessary for us.
Conclusion Instead of adding a new library we spent half an hour writing a needed functionality. We suppressed the desire to use one more library. And it turned out to be a great decision. As the time proved that we really didn't need that library.
This case really convinced me that the simpler solution, the better. Avoiding adding new libraries (if possible) you make your project simpler.
Probably the readers may be interested to know what was the code for searching regular expressions. We'll type it here from the book.
See how graceful it is. This code was slightly changed when integrating to PVS-Studio, but its essence remains unchanged. So, the code from the book:
// regular expression format
// c Matches any "c" letter
// (dot) Matches any (singular) symbol
// ^ Matches the beginning of the input string
// $ Matches the end of the input string
// * Match the appearance of the preceding character zero or
// several times
int matchhere(char *regexp, char *text);
int matchstar(int c, char *regexp, char *text);
// match: search for regular expression anywhere in text
int match(char *regexp, char *text)
{
if (regexp[0] == '^')
return matchhere(regexp+1, text);
do { /* must look even if string is empty */
if (matchhere(regexp, text))
return 1;
} while (*text++ != '\0');
return 0;
}
// matchhere: search for regexp at beginning of text
int matchhere(char *regexp, char *text)
{
if (regexp[0] == '\0')
return 1;
if (regexp[1] == '*')
return matchstar(regexp[0], regexp+2, text);
if (regexp[0] == '$' && regexp[1] == '\0')
return *text == '\0';
if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text))
return matchhere(regexp+1, text+1);
return 0;
}
// matchstar: search for c*regexp at beginning of text
int matchstar(int c, char *regexp, char *text)
{
do { /* * a * matches zero or more instances */
more instances */
if (matchhere(regexp, text))
return 1;
} while (*text != '\0' && (*text++ == c || c == '.'));
return 0;
}
Recommendation
Don't hurry adding new libraries to the project. Add only when there is no other way to manage without a library.
Here are some possible workarounds:
P.S. The things I speak about here may not be very acceptable for everybody. For example, my recommendation not to use a portable universal library, but WinAPI. There may arise objections based on the idea that going this way "binds" this project to one operating system. And then it will be very difficult to make a program portable. But I do not agree with it. Quite often the idea "and then we'll port it to a different operating system" exists only in the programmer's mind. Such a task may even be unnecessary for the managers. Another option - the project will kick the bucket due to the complexity and universality of it before gaining popularity and having the necessity to port. Also don't forget about point (7) in the list of problems, given above.
0