Dont Create Verb Classes

By "Verb Classes", I mean classes whose names are really verbs in disguise. Things like Processor, Sender, Sorter, Listener. It's somewhat related to DontNameClassesObjectManagerHandlerOrData and indeed one of the articles linked from that page specifically discusses "-er", "-or" and "-ar" class names, but this particular (what I consider) antipattern is so prevalent that I think it deserves its own page. I know of one experienced developer who swears by Sender, Receiver, and Processor type classes. He's in good company - the Java and .NET frameworks are also replete with such classes.

To me, it seems obvious: if you have a class called "Sender", it's procedural code in disguise. *What* is being "sent"? Proper OO design would call for the thing being sent to be the class, and a "send" method on that class to do the actual sending.

Note that having *interfaces* with verb-like names is a totally different proposition. Since interfaces, by their very nature, describe behavior, I see no problem with interfaces like Listener, Reader, Formatter etc. since they describe a collection of behaviors that may be implemented by one or more classes. An interface is not a class.

-- Darren Sargent

I happen to love verb-classes. I call them FunctorObjects. I use readers, writers, observers, observables, procedures, functions, etc. They're wonderful for plugging procedural code together in arbitrary manners. Proper OO design doesn't limit this possibility: if you have a class called "Sender", overload operator '()' (or method 'send')... and "what" is being sent is whatever you pass to said 'send' or '()' operator, perhaps modified by some operation.

Just because you *can* do something, doesn't mean you should. There's nothing wrong with procedural coding - we created applications with it for years, and I'll take well-written procedural code over poorly-written "OO" code any day. However, if you want to do OO, then *do* OO: it's *object*-oriented, not *behavior*-oriented. Your design centers around objects; a class is supposed to model an entity in your problem domain. The name of the class, its very identity, should tell you what the entity *is*, not what it *does*. The very act of writing something like mySender.send() or myProcessor.process() should be a code smell.

There are definitely times when one's first thought is to create a verb class; but I think it's lazy design. A little reflection inevitably reveals an object lurking underneath. For example, you're writing a socket class. Your first tendency might be, "Hmm...I need a Sender...which takes a stream of bytes, and destination IP..." Then you think again, and you realize that what is actually required is a Socket class, with "transmit" and "receive" methods. --DarrenSargent

If it's ok to have a Listener interface, but you want to make it concrete, then what do you get? A RequestListener class? That's still pretty much a verb. -- MichaelSparks

An example of redesigning a verbful class hierarchy into a nouny hierarchy might be useful. --Anonymous

I am with Darren here, especially when it comes to a choice between something like mySender.send(socket) vs. mySocket.send(). I can see some instances where a class is so specialized that a verb name seems to make sense (and it actually may in some cases), but I think there are usually better non-verb alternatives. For example, instead of a class called RequestListener?(), I would prefer something like myServer.listen(). One could say that "server" is a verb, so obviously this is not a black and white argument. Verb classes are gonna creep in here and there. My opinion is that it is a good exercise in clean design to try and avoid them if possible. --JeremyMcCollum

I wont be so strict here. Example: Lets have a set of shapes we want to draw in a different styles - to stay poetic lets not say different render systems but for example pointilistic, impressionistics or realsitic style. We have Shape.draw() and shape paints itself or calls someone else to draw itself with current style. Ok fair enough. Now imagine class Painter (comes from verb paint right :o) and use Painter.draw(shape). Also makes sense, or not? Imagine a person with a canvas drawing shapes(shapes are actually not drawn themselves!) and he draws his preferred artistic style. To sum it up: Shape.draw() requires external dependency to know how to paint itself, whereas in Shape drawn by Painter still maintains loose coupling(and could be reused more easily elsewhere). Or - Post office could be seen as Sender of your letters... or... -- M.


OctoberZeroSeven

CategoryObjectOrientation


EditText of this page (last edited July 9, 2010) or FindPage with title or text search