ArticleS. MichaelFeathers.
LibraryCodeVersusApplicationCode [add child]

Library Code versus Application Code.


Here's a simple piece of code. It takes a name that contains a dot and breaks the name into a pair of strings. If there is no dot, it returns the name in the first part of the pair and an empty string in the second part of the pair.


pair<string,string> splitName(const string& name)
{
int breakPoint = name.find(".");
if (breakPoint == string::npos)
return pair<string,string>(name,"");

return pair<string,string>(
name.substr(0,breakPoint),
name.substr(breakPoint+1));
}


How do you feel about this little piece of code? Does it need a contract?

We could add an assertion to document the fact that we expect only a single dot in the name:


pair<string,string> splitName(const string& name)
{
assert(occurrenceCount(".", name) == 1);

int breakPoint = name.find(".");
if (breakPoint == string::npos)
return pair<string,string>(name,"");

return pair<string,string>(
name.substr(0,breakPoint),
name.substr(breakPoint+1));
}


Or should it be more general? Maybe it should split the name at every dot and put all of the pieces in a vector.

Or maybe it is fine the way that it is.

Think about your answer.

Would you change your mind if I told you this was application code?
Would you change your mind if I told you it was library code?


In my mind's eye (ear?) I can hear someone saying "hey, this is moot. Library <insert name of favorite library here> has a split function." But, for the sake of argument, imagine that you didn't have one. Do we treat library and application code differently. Should we?


!commentForm


 Sun, 15 Jan 2006 00:40:25, David Chelimsky, it depends
I think it depends on what purpose the method is serving. All too often, I see developers jumping to generalize something because "if I generalize it, then everyone can use it" (thinking of application code as library code). The problem w/ "then everyone can use it" is that everyone *will* use it, and that puts a greater responsibility on that code, and that means it's more difficult to change to serve the needs of the application in which it was born.

In answer to the question "should we treat library and application code differently", I'd say yes. With application code, you only need to specify as far as the requirements of the application suggest. For library code, you have to consider all the potential uses - those things that YAGN in a an application.
 Mon, 16 Jan 2006 00:46:56, Keith Nicholas, it depends, but....
I think you need to make careful use of YAGNI, sometimes I think you can blind yourself with it. I think sometimes software developers end up leaving things in non generalized forms that are often harder to spot where theres duplication and can be harder to refactor. I also think putting in the safety nets that would catch bad uses of code can help a lot with the long term maintenance of the software. I think you should hold your code to library standards, do the extra work to get it to library standards, but perhaps not the extra functionality that a library would need. Over time slowly evolve a libraries out of the your application. ie, Engineer your code, just dont over engineer your code
 Mon, 16 Jan 2006 05:50:33, Sebastian Kübeck, Library and application code are different
Have a look at Bill Venners interviewing Erich Gamma on this:
http://www.artima.com/lejava/articles/reuse.html
 Tue, 17 Jan 2006 00:43:38, Chaz Haws, An intriguing question.
I think you can trust the YAGNI here, if you can rely on the tests to communicate the intended usage. If your library's users intend something different than you do, that becomes their problem and not yours. They can add a new test for their new usage at the time. Especially true if you don't already know what their specific usage will be. The key is that you've communicated your intentions to them.

Secondly, I notice that your method is called splitName. This is not a string-splitting method, this is a Name-splitting method. I think that's much more relevant than whether it lives in a library. If Names in this context always have a single dot, then you're good to go. To be sure it's used in the right context, upgrading from a string to an explicit Name type would guarantee that this was used by the same type of Name it was designed for.
On the same theme, I see that it returns a pair, not a vector. What *should* it do with multiple dots? A domain question, tying it even more to a specific idea of Name.

What I would change right now, then, is only one thing: Explicitly identify what type of Name we're talking about, from what domain. If it's the name of a widget, rename it to something like splitWidgetName.
 Tue, 17 Jan 2006 10:49:33, Sean Kent, It depends...
I think the assert is problematic. If occurrenceCount does what it's name says, then it should return the number of '.'s in the string, however you have already stated that if there is no dot then it returns a pair with the name and an empty string. That asside:

If you told me this code was for an application or for a library, I might consider it in another light, but most likely not. Sometimes we make library code more general than we do application code, sometimes we don't. However, I would perhaps make this piece of code a bit more general by simply pulling out a splitter method for a string on a set of seperators, with the ability to indicate the number of splits requested. But I would do that for application or library code, as I've found that if I need to split one string, I probably need to split others.