

Untangling the God Object - donw
http://werve.net/articles/untangling-the-god-object/

======
arthurcolle
I don't really understand this approach. I don't think that even in my
earliest days programming Java using object-oriented principles that I would
have added "search" to a Product class. After all, search is not a behavior
that products perform, rather it is a property of theirs... i.e. "I am
searchable". I would have most likely make some kind of ProductIndex which
consisted of a hashmap or something, mapping hashes of product strings to a
list of their properties for easy lookup or something... This is one thing
that immediately stands out to me.

Lo and behold, you created a ProductSearcher class. It seems to me that the
initial approach stems not from the view that "objects are things" but rather
the notion that any related property of an object should be included in the
class definition of the object, which can be summed up as a misunderstanding
of object-oriented programming more so than anything else, but maybe I'm
looking at this the wrong way.

Interesting article, thanks for sharing.

~~~
donw
In the past, when mentoring developers that tend towards god-objectery, they
tended to avoid creating service objects because their mental map of the
problem had a one-to-one correlation between "objects" and "the physical
problem domain" (e.g., Users, Accounts, etc.)

Given how much I've seen this sort of stuff in the wild, I felt it would be a
useful article to hand off to new-ish developers (I'm the author).

It sounds like you're well beyond that, though, but thanks for reading
nonetheless!

~~~
zbyte64
Sent this to a budding developer in our business. Thank you for the article. I
too tend to think of objects as actors with contracts.

~~~
donw
My pleasure -- I'm glad it helped!

------
mdparker89
I've seen this in iOS code. I think it's partly because MVC gets pushed so
hard. For a new programmer, it seems as if the code has to fall in to one of
those three buckets. Views and view controllers change pretty frequently so
there's only one place left.

~~~
zem
yep, that was a large problem in the early days of rails too, where everything
got pushed into the model simply because it was neither a view nor a
controller.

~~~
donw
Exactly. A lot of people learn to code for practical reasons -- which is great
-- and cut their teeth on a Rails or iOS app, where there are a set number of
"buckets" for where code goes.

The idea of just creating other objects out of rainbow tears and unicorn dust
doesn't naturally flow from this style of learning to program. :)

~~~
girvo
Amen. PHP had the same problem, and in some cases still does, but thankfully
I'm seeing more and more developers (and more and more projects I'm working on
here at work) where it's all Plain Old (language) Objects with some nice
sprinklings of proper libraries to get stuff done. What's lovely about that is
everything ends up being completely unit-testable without much extra effort.
It also means I get to use proper OOP architecture yay!

------
seanmcdirmid
Another strategy would be to use mixins: rather than think of objects as being
programmed via SI classes, you instead program them as layers of functionality
(mixins). Few languages have good support for mixins, however (Scala being one
of them).

~~~
donw
Mixins can be very useful, but my rule of thumb is only to use them when I'm
defining a behavior. Like the conjunction rule, after I've pulled in a mixin,
I should be able to say that the class is something-able.

The classic example (both for Ruby and Scala, I believe) is to use mixins to
add iteration behavior to a class. This is a perfect example -- to my mind --
of where mixins really shine.

Where things get dangerous is when people start breaking objects apart into
mixins because the class has gotten too big (rather than using delegation and
separating concerns).

Everything is still tightly coupled together -- none of the mixins can work
independently of each other, or be used by other classes. It's very difficult
to test, and when a project goes crazy with this pattern, you spend a _lot_ of
time playing Hunt The Wumpus, trying to figure out exactly where behavior is
defined.

I do not like Hunt the Wumpus. :)

Do keep in mind -- I've only done the _tiniest_ amount of Scala programming,
so take what I have to say with the proverbial salt-grain. But from what I
understand, Scala mixins work much like Ruby mixins -- not exactly the same,
but they fill a similar role.

~~~
seanmcdirmid
I dislike using mixins for one off -able features...I mean, I do it, but not
often. Where mixins really shine is when used in "layers" to modularize system
functionality that otherwise cross cuts class boundaries. So you can take one
aspect of your system...say syntax in a compiler, and separate parsing from
type checking in its own layer. This an easy solution to the expression
problem and compares favorably with the giant case statements favored in the
functional programming community. And its quite nice: you know where
functionality X of class C is, its in the C section of file X (i.e. a grid!).

Also, see virtual classes, though very few languages have first-class support
for those these days.

Scala mixins (traits) are basically classes that undergo liearized multiple
inheritance; they are designed to work well in a statically typed language
(they can be used as constraints for type members, and they can refer to those
type members themselves, leading to some nice constructions).

------
PeterisP
OOP design practices often consider NounVerber classes as a design smell that
should be avoided at all costs; this article introduces them as the solution
for everything.

How does it go together?

~~~
donw
That's fair criticism -- I've updated the article to make it a bit more clear.

The point isn't to create "NounVerber" classes as a solution for everything,
but to break your objects apart according to the roles that they play in
solving the problem.

Thinking of objects as actors has helped me with this over the years.

In the example "ProductSearcher" should probably have been named
"ProductSearch" \-- you can instantiate it, pass it around, and so on, so it
doesn't quite behave like many the "NounVerber" objects in Javaland (e.g.,
AbstractFactoryBeanBuilderImpl).

When you couple this with a functional approach -- where you separate
transformation and state -- magic happens. But that's a future article. :)

~~~
Double_Cast
Maybe the objects-as-agents could pass around a struct? E.g. I imagine the
Store_Manager (driver class) could call (like on the telephone) the Accountant
and ask to submit a report (struct) of all the inventory that fits the
parameters. Or would that be another anti-pattern?

------
snorkel
I much prefer Noun.verb() over
NounVerberFactoryInterfaceAbstractInsanityTurtleTurlteTurtleRussianNestedDollSet
so this case is just missing a noun such as Catalog, so the Catalog has
Products, and Catalog.search(parameters) would return a list of Products.

~~~
seanmcdirmid
>
> NounVerberFactoryInterfaceAbstractInsanityTurtleTurlteTurtleRussianNestedDollSet

Ya, how often do you see that in OO programming?

~~~
cesarbs
The Java standard library has its share of such insanity.

~~~
seanmcdirmid
Then it should be easy enough to provide me with an example? I've only ever
seen factories with an indirection of one level in Java's standard libraries,
I wouldn't be surprised if that was part of their coding style rules.

I think you would only find such monstrosities in Ecliopse.

~~~
nardi
I was curious, since I've seen this joke a lot of times, and thought surely
there must be some truth to it. The longest class name I could find in the
Java standard library is "SQLIntegrityConstraintViolationException". The next
few longest names were also exception classes with descriptive names. The
longest factory name I could find was "ContextualRenderedImageFactory", which
also seems pretty reasonable.

~~~
arethuza
What about this one:

InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState

[http://javapapers.com/core-java/longest-class-method-and-
att...](http://javapapers.com/core-java/longest-class-method-and-attribute-
names-in-java/)

~~~
seanmcdirmid
There are no design patterns in that name (Factory, Proxy, Singleton). Also,
it sounds like the name is machine generated, which shouldn't count.

~~~
arethuza
I would certainly agree that the name was clearly generated by the mechanical
application of some naming rule without the application of much judgement...
:-)

