Fog Creek Software
Discussion Board




Utility functions?

What do you do with the odd utility functions that undoubtedly appear in larger projects?  I'm thinking in an OO or encapsulation sense here.  Functions that don't relate specifically to one class so there is no object that should "know" how to do this, but need to be included anyway.  Functions that have no counterpart in the language libraries.

An Example:  You have a FooPrinter class, it prints out files of the format .foo.  It is passed the output directory, and the file contents, and needs to know how to get rid of any directory separators on the end of the path so as not to end up with files of the form "D:\Bing\Bong\\baz.foo" when the file is printed.  Assume no library functions to do this exist.

Attack the idea, not the example, please (I know its lacking :).  Anyway, lately I've been putting these files into a Utilities class, or something similarly named.  But I know this won't scale.  The largest project I've worked on so far is 20k LOC, and that method was starting to break down.

So how do you manage this?

Andrew Hurst
Friday, February 28, 2003

I've often grouped sets of related utility functions into a class as static methods.

e.g. StringUtils would have utilities dealing with Strings like

static String [] split(String in, String delimiterr)  { .... }

anon
Friday, February 28, 2003

I'm not so sure it won't scale. I think good organization is really the key.

For instance, the Java Arrays class, which implements many useful utility functions for doing array stuff (binary searches, contains, etc). Or the Java Math class.

I like the way of dumping it into an appropriate class, one per category, all well documented.

Mike Swieton
Friday, February 28, 2003

I assume that both of you are talking C++ or VB since in Java methods *have* to be a member of a class.

anon's method seems to be based on the same model that Java uses. I'm mainly a C++ programmer, but I'm willing to steal good ideas from any language - and this is one of the idea's I've stolen. Create logically named classes and add your utility functions as static member functions.

By separating them into classes based on their function, it makes reusing them much easier and also makes documenting a bit easier (as well as just finding the function when you're looking for a particular routine).

RocketJeff
Friday, February 28, 2003

Well, I was thinking of something along similar lines.  But the fact of the matter is that I already have my (stubborn) mind made up regarding what I'll do about it...  :)

Anyhow, if I could broaden your topic to "code reuse", and blabber a little more (hope you don't mind).  I have a class which has been improved and tested along the way, that is a circular queue - its good in alot of generic stuff.  Its 2 simple files: cq.c, cq.h.  Do I try to integrate them into a larger library of generic stuff with a common include and /lib directory?

Well, I decided, without a whole lot of thought, that big heirarchy is not better unless necessary.  So I just kept cq.c, cq.h in the original spot they were created.  New ojects that reference these get symbolic links to the originals.  So far, no problem.  The only wart on it is that your OS must support symlinks and so must your version control.  Not a problem in my case.

Anyway, I've noticed that I do not make an effort to reuse code in the strictest sense - with alot of heirarchy.  Each device driver I've written recently has its own PCI probe function - each slightly different, either by necessity or by my not caring (does it matter?).

The drivers get tested and debugged as a unit, not against a maintained library.  My code reuse is mostly just cut/paste/modify.
FWIW.

Nat Ersoz
Friday, February 28, 2003

Nat,

  I've been doing a lot of code re-use the way you mention lately (cut/paste/modify) and thats partly what brought this up.  What if you find some bug in a part that you've cut and pasted?  What if it happens to be in 50 parts of the codebase?  It gets messy.  I spent a few hours cleaning up something exactly like that the other day.

  Though on the other extreme, you set up each function to work as a library function as well, you either end up with a heck of a lot of swtiches to set how its processed (to handle the modify in cut/paste/modify) or a slew of different functions in the library each used by only one other function.  Both of which don't sound very good in my opinion.

  Both extremes don't sound very exciting to me.  Which is why I asked this question.  I'm trying to find the safe middle ground :-)

Andrew Hurst
Friday, February 28, 2003

"static String [] split(String in, String delimiterr)  { .... } "

Why on earth isn't that a method on your string class?

"An Example:  You have a FooPrinter class, it prints out files of the format .foo."

Often "-er" classes are poor design, where a function is masquerading as a class.

I'd ask why your objects which encapsulates "files of the format .foo" doesn't have a print method.

Robert
Friday, February 28, 2003

I think, the answer is in your question.

You call them utility _functions_, right? So if your language supports functions, write them as functions. Only if it is a restricted OO-only language (like Java), you have to come up with a hack, using classes / static methods. However, using classes is just a hack, a workaround, because of language weakness (or lack of expresiveness).

If you think of them as of functions, they should be just functions. If there's not a  number of utility functions, organize them using  modules or namespaces (whatever your language supports).

raindog
Friday, February 28, 2003

correction: s/there's not a  number/there's a number/

raindog
Friday, February 28, 2003

Regarding reusablility:

One of the most reusable libraries on the planet is CPAN, a huge Perl library, which is only partially object oriented. Generally speaking, the unit of reusable code is module, not class. While it's possible that 1 module = 1class, it's not necessary. A module can contain only procedural-style code, one class or a set of related classes (+ utility functions, if needed).

Reusability is related to modular structure, not to the OO-ness of a language.

raindog
Friday, February 28, 2003

"I've been doing a lot of code re-use the way you mention lately (cut/paste/modify)"


Ahhh..the ol' "Clipboard Inheritance" design pattern...You should always be careful with this one. I've seen plenty of times where code was cut and pasted and then butchered to make work. The end result was an order of magnitude more complex than if they had just written what they needed from the ground up. Or just design the code into a class..or...

Regarding the original question, I've always struggled with this too. My preference has been to either create a Utility class with static methods or include the functions as static methods in a particular class. It's always worked for me, but I always felt as if my design were flawed if I had to have a utility class.

Go Linux Go!
Saturday, March 01, 2003

Create a Utility class and you may solve a lot of problems, however you may also get a whole lot of others, serialisation, instantiation, mutual deadly embraces of semaphores.

Utilities (if they really are utilities) are more a language extension than an operation on a class and there are far fewer real utilities than may be thought.

For instance, a 'reverse string in place' function belongs in a String class (though an entire tome the size of a volume of the Encyclopedia Brittanica could be written on the grotesque examples of String classes there are), and not in a separate function.  But a function returning the number of elapsed seconds this year?  Should it be some orphan method in an orphan class about years?  Hardly worth all the overhead; you want a function like that to almost operate as if it were inline code.

If a language doesn't support user defined functions (that is context free procedural units), then you have to define them as methods somehow but in that case I'd assume that the language also hides all of the implementation mess that can arise.

Simon Lucy
Saturday, March 01, 2003

I have always just put functions like these into library files and kept them in a common folder. I reference the files at project level, rather than sharing the source file. I'm sure there probably is a better way of doing this, but I've never bothered to look.

There is something arguably more important than *how* this is done.

That thing is documentation.

In almost all of the large places where I have worked, the main problems faced by programmers were a) knowing that a function exists to achieve what they want and b) knowing how to use it.

Every library system I've ever seen has had neither documentation nor examples (I'm talking about organic ones, not commercial ones). The other missing component which real libraries have is an search system.

Yes, I know that if I put them in classes, I *could* create an ordered list of available functions and their arguments from the interface. This does not produce a list of e.g. How to solve problem X - available functions".

If it is too hard to find or maintain library functions, programmers will simply give up and write their own.

Justin
Saturday, March 01, 2003

---------------------------------------
Why on earth isn't that a method on your string class?
-------------------------------- Robert

In Java this approach doesn't work, the String class is final.  You cannot add methods to it, so they have to go elsewhere.

Ged Byrne
Monday, March 03, 2003

Personally, I just create a file named "common_utilities.cpp" or some variation thereof, and toss all my common functions in it.

It's not necessarily pretty, but it lets me get on with my work.

Brent P. Newhall
Monday, March 03, 2003

I ususally see a need for utility functions in large projects; things that would be better maintained centrally. As such, I create a support directory to hold those classes and functions that don't clearly belong to a single project or class. What this frees me to do is move those classes and functions between major projects by branching a directory. Where OO languages can aid this even more is in cascaded namespaces (Java/.NET style locating of functions), static methods attached to classes, and similar OO tricks used for code reuse.

If you're interested in a worthwhile study of the impacts of this scenario and some others, there are excellent books on the subject. I read _Large Scale C++ Software Design_ by John Lakos and it truly changed the way I design software in C++ and in other languages. I realize this is not the only book on the topic, but it significantly improved the way I work.

Dave Brown
Monday, March 03, 2003

This thread is too old and no one will see this, but what the hey...
http://books.slashdot.org/books/03/03/02/2253212.shtml?tid=108&tid=156
This seems to be the solution looking for your problem. What do you do with all the piece that are usefull everywhere but fit nowhere.
Does anyone have any experience with aspect oriented programming.

Doug Withau
Tuesday, March 04, 2003

*  Recent Topics

*  Fog Creek Home