
One of the Best Bits of Programming Advice I ever Got - apgwoz
http://objology.blogspot.com/2011/09/one-of-best-bits-of-programming-advice.html?spref=tw
======
mcherm
I am unconvinced. Any absolute deserves close scrutiny, and "real nouns only"
is an absolute. In this case, it fails my test. I find that many things I work
with (especially huge Java libraries) tend to have convoluted and difficult-
to-understand webs of classes with the most confusing pieces named things like
"FooManager" or "FooController". So the author of this piece is reacting to a
genuine excess.

But Travis is overreacting. The REAL goal is to find a collection of
abstractions that is powerful enough to accomplish what the program requires
but as simple as possible (and as local as possible) to allow humans to
comprehend (and maintain) it. There are quite a few times when I have found
that one of these "verb-like" abstractions (a word ending in "-er") made
things more comprehensible.

For example: the Gang-of-Four patterns "Builder" and "Observer" both end in
"-er" and strike me as being well-named. "Builder" is an object with no
purpose other than to create (initialize) another object or data structure.
HAVING such an object is useful when something requires extensive setup or
initialization, because it is easier to understand if the extensive
initialization is kept separate from the core functionality. "Observer" is the
name for an interface of things that observe... the names of interfaces
FREQUENTLY work well as "verbs" since the interface frequently represents
"anything that does X".

Similarly, I have often had a class such as "DatabaseConnection" and then
created "DatabaseConnectionWrapper" -- a class whose purpose is to wrap a
DatabaseConnection to do something like logging, error reporting, pool
flushing, driver-bug-patching, and so forth. Suggestions that I call these
"LoggingDatabaseConnection", "ErrorReportingDatabaseConnection" and so forth
misses the key point: a different mix of features may be required at different
times (eg: logging in QA but not in Prod); the fact that they are transparent
wrappers that can be added (or not) in any order is a key feature of the
design.

So my own advice would be weaker than Travis'. Instead of "Don't make objects
that end with -er.", I would say "Be wary of confusing objects; those ending
in -er are often confusing."

~~~
pestaa
I think there is a more fundamental misunderstanding in OO than bad naming
convention. You are right about the usefulness of -er named objects -- but
then again, are they really objects, or just functionality wrapped into a
wrongly chosen language construct?

Following your example, you could have implemented the strategy pattern into
DatabaseConnection to freely inject functionality into the object when X
happens. Assuming these functions do not have additional data members other
than the parent object, they easily can be simple functions or even lambdas.

(Of course it's easier to restrict to classes, because you can validate
against interfaces in case a function signature doesn't cut it.)

What Travis is suggesting, when you have an object that defines both data
_and_ behavior, the object context should be determined by the data, not the
behavior. If done properly, you end up with less names that end in -er.

~~~
mcherm
There are many times when the objects really do have both data and behavior --
glancing at the real code that was the basis of my example, I see that the
LoggingDatabaseConnection has real state (the place to log to) and the pool
flushing one has real state (keeps track of open cursors so they can be auto-
closed when it is returned to the pool).

Of course, you also could be (and I was) using a deficient language like Java
which doesn't HAVE any way to use a function or lambda. But I agree with you:
a simple lambda a better solution where it is available.

And this kind of use is quite far from what Alan Kay intended when he designed
SmallTalk. The original idea was that the objects would correspond to real-
world entities. I would contend that since then OOP has evolved, and now the
key idea of an object is the pairing of data and methods. Choosing the
abstractions which will make the code most readable is one of the great
challenges of programming well, and I find that just going for the nouns every
time is NOT the best answer.

------
DrJokepu
I disagree with this advice and the reason I disagree with it because it
completely disregards the human tendency to name objects (not OOP objects, but
real-life objects) based on their functionality. Guess what a photocopier
does? Or a scanner? An eraser? An elevator? I don't think these are
particularly bad names; quite the contrary, their meaning is very clear.

Why would it be any different for OOP objects? If there's an object with an
internal state that chiefly responds to messages about scanning things, what's
wrong with calling it NSScanner?

~~~
sethg
I think in the author’s ideal world, we would not have Photocopier, Scanner,
and Eraser objects, but rather a Paper object that can copy, scan, and erase
itself.

~~~
languagehacker
Yeah, but good luck trying to reuse the same basic instructions to scan non-
paper objects without multiple inheritance.

~~~
ori_b

         interface ICopyable {...}

~~~
SimHacker
Back in the days at PARC, that was "IXeroxable".

------
ctdonath
Amazing how small linguistic changes can cause large semantic shifts.

Comparable to the post's rule: in English, a few rules I've picked up are

\- avoid words ending in "ly" (suffix weakens concepts; suggestion from
Stephen King)

\- never start a sentence with "I" and otherwise minimize its use

\- "but" negates everything that came before

\- avoid "to be"

Any other such suggestions, in natural or artificial languages?

~~~
pestaa
Is there a collection of suggestions from Stephen King? I love picking up
small pieces of advice from respectable writers, and he is undoubtedly one of
them.

~~~
cpeterso
Stephen King's _On Writing: A Memoir of the Craft_.

~~~
ctdonath
Most of the book is his less-than-riveting autobiography.

The ~16 pages which are in fact about writing ("Toolbox") are worth more than
the cover price.

------
5hoom
Meh.

I'm working on a video game at the moment, and have read lots of advice like
this. My old game engine experiments all used 'Entities' to describe objects
in the game world, and these 'Entities' were created, deleted and invoked by
an 'EntityManager' (kind of half factory & half controller). Every game tick,
the EntityManager calls a 'tick' method on all the current game entities and
facilitates communication between them. For the most part, all entities are
created/destroyed at the same time (game-level loading/unloading).

Trying to avoid architecture mistakes, I've come up with all sorts of tortured
designs to do away with the concept of any kind of 'manager'. It is probably
my inexperience with various design patterns, but all these alternatives were
overly complicated and difficult to use. I would end up with a mess of objects
& functors all needing pointers to each other & stepping on each others toes.

It then occurred to me that my 'manager' was in fact mapped to the real-world
concept of 'a manager', being someone/something that is given orders from
upper-management (game-level data, user-input, etc.) 'hires' & then assigns
tasks to 'workers', hands the results to upper management, then 'fires' the
workers when they are not needed ;). The metaphor works.

So I'm back to the 'manager' pattern and things are moving ahead quite nicely,
even if some OO purists might frown. Should I call my 'EntityManager'
'EntityBoss'? Gets rid of the 'er' at least...

~~~
chipsy
Similarly, my game has Managers for entities, collision components, and
renderable components. With each one of these, I don't want to try to dump all
of the data in one place where the access patterns become strained, I want
them to be "managed" from afar, where there's an interface to easily query or
update them.

~~~
5hoom
Yeah, from my own experience the 'manager' metaphor is just easier for
understanding the flow of execution & adding-new-features/maintenance.

Everything is in one place, and when the systems do need to communicate it is
usually in pretty well defined ways (eg. physics manager ticks--> passes
collision data to entity manager which ticks--> passes scene data to render
manager which draws the screen, etc)

I'll go with whatever pattern works best in the name of Just Getting Stuff
Done (with my own limited brainpower).

------
philbarr
I generally accept the point made in the article, but what should I use in
place of "Controller"? If using MVC I generally call it
"ApplicationController" or "SimpleController". Should it be "Application",
"ApplicationControl"...?

~~~
lallysingh
what do the controllers actually do? Synchronize state? Verify that
constraints are met?

~~~
philbarr
You're suggesting I call them "StateSynchronizer" or "ConstraintVerifier"?

~~~
lallysingh
No, I suggest you name it after what it actually does. "Controller" is a role
that's only defined in terms of what it interacts with. It's essentially a
declaration of rank with other types; it doesn't say anything about what
functionality the class provides.

If I'm looking at the components of the software, and I want some code to do
X, or wonder what a class Y does, what does "Controller" tell me?

If you're doing constraint verification (for example), my preference is to
have a container (e.g. vector<>) of Constraint and just run find_if() to see
when Constraint::Valid(environment) returns false. Then it's a class called
ConstraintVerificationUtil and it has a single static method: VerifyList.

------
dasil003
What do you do if you need a higher level interface to a bunch of classes that
are already fairly complex in their own right? Seems to me "plain" nouns
(since really these are all nouns) are good for simple concepts and things
with real world analogs, but in projects of any complexity you quickly end up
with complex logic whose _only_ succinct description is what it does.

My experience tells me the key aspect of software quality is the interfaces.
The simpler and less leaky the interfaces, the more understandable,
maintainable and correct the software will tend to be. Part of this is
inherent to the problem itself, but a big chunk of it—especially in the
middleware—is the ability of a software architect to have a sense of the whole
project and figure out the best places to carve the interfaces. Doing so
correctly is the difference between a maintainable million-line project and
spaghetti. Truly brilliant engineers will figure out interfaces that make code
100x more reusable and elegant, maybe spawning open source extractions, etc.

If something is named well is an orthogonal concern, and highly contingent on
what the actual object is. The best code in the world might be impossible to
name intuitively if there is no real world analog.

------
latch
Google has posted warning signs to look out for in code (1). One of them is
very similar:

    
    
      Suspicious names: context, environment, principal, container, or manager
    

(all of the things google mentions, are things I've seen much, much more in
Java codebase than anywhere else)

(1) [http://googletesting.blogspot.com/2008/11/guide-to-
writing-t...](http://googletesting.blogspot.com/2008/11/guide-to-writing-
testable-code.html)

~~~
jwdunne
[http://misko.hevery.com/code-reviewers-guide/flaw-digging-
in...](http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-
collaborators/)

This is the full article mentioned above.

------
monochromatic
Relevant snarky blog post from Steve Yegge:

[http://steve-yegge.blogspot.com/2006/03/execution-in-
kingdom...](http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-
nouns.html)

------
timclark
I particularly dislike classes called *Helper

~~~
MartinCron
I'm with you there. Aren't all classes supposed to be helpful?

------
sethg
I am upvoting this because I think it is an essay worth thinking about, but
I’m not sure if I agree with it.

------
praptak
I was lucky enough to get an equivalent piece of advice from "Object Oriented
Programming" by Peter Coad & Jill Nicola ( <http://amzn.com/013032616X> )
which was the main textbook for an OO course during my CS studies. There are
good examples there that illustrate this and many other useful rules (of
thumb) of OO modeling.

------
tmsh
The most correct program (in terms of maintainability and evolution -- as well
as mathematical correctness) approximates the most orthogonal program.

In term of modeling it with objects that contain state, this may mean having
objects that have a varying degree of state (unless you choose other purer
approaches).

But it's naive to think that all classes should be a noun. Everything should
be an abstraction that models the solution. However, nouns that end with 'er'
do tend to have a little bit of state that seem unorthogonal. But I guess my
point is that that's the wrong way to look at it. Better to think about it in
terms of DRY. Some 'manager' or 'controller' classes violate DRY (whereas it's
rare for 'connection' classes to). But not all 'manager' or 'controller'
classes do.

------
Kototama
Even better: don't use objects at all. Use a functional programming language.

~~~
cousin_it
Object oriented programming is the sweet spot solution to many problems. For
example, if you have a UI with several text fields, it's natural to think of
them as objects that have methods like setText(), setEnabled() and such. These
methods often have side effects and that's their whole point.

Of course functional programming also has use cases for which it is the sweet
spot solution, e.g. writing compilers.

~~~
danieldk
_These methods often have side effects and that's their whole point._

You don't need state and mutations, GUIs can also be programmed nicely using
functional reactive programming (FRP). A nice description of FRP:

[http://stackoverflow.com/questions/1028250/what-is-
functiona...](http://stackoverflow.com/questions/1028250/what-is-functional-
reactive-programming)

Some examples of FRP in GUIs:

<http://www.haskell.org/haskellwiki/Reactive-banana/Examples>

~~~
cousin_it
_A simple counter that can be manipulated with two buttons "Up" or "Down":_
[https://github.com/HeinrichApfelmus/reactive-
banana/blob/mas...](https://github.com/HeinrichApfelmus/reactive-
banana/blob/master/reactive-banana-wx/src/Counter.hs)

    
    
        main = start $ do
            f       <- frame [text := "Counter"]
            bup     <- button f [text := "Up"]
            bdown   <- button f [text := "Down"]
            output  <- staticText f []
        
            set f [layout := margin 10 $
                    column 5 [widget bup, widget bdown, widget output]]
        
            network <- compile $ do
                eup   <- event0 bup   command
                edown <- event0 bdown command
            
                let
                    counter :: Discrete Int
                    counter = accumD 0 $ ((+1) <$ eup) `union` (subtract 1 <$ edown)
        
                sink output [text :== show <$> counter]
        
            actuate network
    

This doesn't look like good UI code to me. It seems to use too many advanced
FP concepts that have nothing to do with the task at hand. Are you sure this
is better than the OO approach? Why?

~~~
danieldk
_This doesn't look like good UI code to me._

It replaces a mutable counter (that could potentially be changed anywhere in
the program) by a definition of the counter that describes all possible
changes it can have during its lifetime:

    
    
        counter = accumD 0 $ ((+1) <$ eup) `union` (subtract 1 <$ edown)
    

So, we have a counter that has an initial value of one. Over time, 1 can be
added and 1 can be subtracted, namely when repsectively an _eup_ or _edown_
event occurs.

Being able to capture all possible 'state mutations' of a value in one
assignment is good.

 _It seems to use too many advanced FP concepts that have nothing to do with
the task at hand._

Which is a bit ironic, since the widgets are created in the IO monad with the
'do'-notation, which simulates imperative programming in Haskell :). A user
interface should be designed with a WYSIWYG interface (Glade, Qt Designer)
anyway, but that's besides the point.

~~~
cousin_it
> _Being able to capture all possible 'state mutations' of a value in one
> assignment is good._

I think there's a duality here. If there are 20 buttons, each of which can
affect some of 30 counters, then the Haskell code would say "this counter is
affected by these buttons", while imperative/OO code would say "this button
affects these counters". It's not obvious to me that the former way of
organizing code is better.

~~~
danieldk
You are still missing the point. In imperative programming there is no
guarantee that the counter isn't modified in some place else or wrongly. In
the end it's just an integer that allows all kinds of mutations.

The possible value changes in the Haskell FRP example, on the other hand, are
completely described. There is no other manner in which the value can change.

~~~
cousin_it
OOP also has a way to guarantee that the counter can only be changed by calls
from specific parts of the code, it's called encapsulation. For example, the
counter could be an object that subscribes to button events, and the counter's
value could be a private member variable of that object. What exactly is the
win from FP here?

------
mhd
I really respect the man and his work, but I can't help groaning whenever I
read the "I invented the term 'Object Oriented Programming'…" Alan Kay quote.
Always struck me as a bit puerile and pedantic.

------
aangjie
Well, this is one of my reasons for python over Java as a programming
language. There are some procedures that don't fit naturally into a class or
object and I should be allowed write functions for them. I was a OOP fan, when
i learnt c++, but when i learnt java was put-off by its' requirement of
needing a class. I am learning Haskell now, and am a little infatuated with
FP, but not sure will enjoy using it a couple of years down the line. I
understand the Manager class has some state and methods, but just can't digest
the idea of a separate class. To overextend the metaphor, i guess, that's one
of the reasons i have shied away in my career from becoming a manager.:-P

~~~
aangjie
Just curious, why downvote. is anecdotal evidence frowned upon here? Or only
opinionated, argumentative positions welcome??

------
ilcavero
good explanation of procedural vs OO programming, but I got kind of lost with
the -er tip, is it all about naming conventions, should I go and rename all my
ZzzXxxer classes to XxxxZzz?

~~~
stefs
yes, that's his advice. Organizer -> Organization, don't ask, just do it.
while this sounds silly, i think it's all about getting into the right state
of mind.

------
bromagosa
Lots of Smalltalk lately in HackerNews :)

------
SimHacker
But I just met 'er!

------
uriel
This is interesting in view of Go's convention to use the ending _-er_ for
interface types (Reader, Writer, ...) rather than the implementations of those
interfaces.

------
3pt14159
Haha. Look at the Ruby home page: <http://www.ruby-lang.org/en/>

~~~
strictfp
Clbuttic!

