Ravi Mohan's Blog

Friday, October 07, 2005

I.need(true).someMoney();

The "code should be readable" principle, like any other, can be taken to extremes.

Recently, someone advocated replacing (junit's) assertEqual(5,obj1.getValue()) with Result.Of(obj1.GetValue()).ShouldEqual(5);

Yet another suggestion I heard was to replace assertTrue(x > y) with Should.be(true).that(x).greaterThan(y) !!!

A class called "Should" with a method called "be"?

The best reaction I heard was from a friend who said,

"I can write a program to substitute spaces with "." and put a "()" at the end of requirements written in English. That would be better than this lunacy. Thus I.need(true).someMoney() :-p"

Remember the language where you could just "express business requirements in English" without "developer speak" coming in the way? Yes, COBOL.

This ridiculous notion that code should look like English comes from a misunderstanding of the "Objects model the domain" principle.It also makes sense to those who have only (an imperfectly understood) Object Oriented Paradigm in their bag of tools and frequently those who can only "speak" Java (although I have seen this happen to some self proclaimed "smalltalk experts").

I once worked on a project where the "Chief Designer" was Object crazy and we ended up creating Objects that replicated all the components of a relational Database imperfectly. Thus we had classes like "Table" and"Query" right in the code, with all sorts of fancy tree creation (and tonnes of Visitor classes)to create simple "Select *" queries as objects. We even had a ridiculous "FieldedBusinessObject" class that was essentially a glorified Hashtable, with well over 300 fields and methods with the interrelationships laboriously hand coded. All in the name of "OOD" (and in a "100% pure XP" project too !!!). I pity the client who paid good money for this hogwash.

Genuinely understanding a paradigm means knowing what it is not good for, just as well as how to apply it effectively when it is suited.

Using an object structure to create a poor man's version of a very ambigous spoken language like English is a warning that the practitioner probably shouldn't be programming live systems in the first place. Doubly so when this misunderstanding is couched in terms like "Ubiquitous Domain Language", which have very precise meanings and context, totally unrelated to such foolishness.

If you must have a totally unrelated language embedded in your code, it is far better to learn how interpreters and compilers work and and how to embed sublanguages in your code (no,XML is NOT a good way to do this!) Yes, that means learning some "esoteric" computer science theory.

If you ever find yourself contemplating classes like "Should" with methods like "be" (coming soon to a framework near you! I am NOT joking), find the nearest wall, bang your head thrice on it, very very hard. Do this enough and you'll be ok! Or at the least you will soon not be able to do much harm.

Alternatively, the nearest walmart is probably looking for checkout clerks.

4 comments:

Anonymous said...

Ravi,

You might be a very good programmer overall but you still need to master the finer points of OO Design.

Every instance of class ThinkingProgrammer has a method called

run.away(fast).and.hide(true)

which should be invoked when you meet such morons.

Hilarious! I am sending the permalink url to all my friends.
:-)

you ARE joking about that framework?

Ravi said...

Joe,

run.away(fast).and.hide(true)

heh heh nice!

As to the framework,no iam NOT joking. Keep watching the "tech space".

Anonymous said...

I agree that you shouldn't sacrifice good object design for English readable "sentences", but the two are not mutually exclusive. Something like (recently brought into my project)

assertThat(something, eq(someOther))

reads very nicely and seems to belong to a Test class. In some cases, the syntax niceties (such as eq, which is a JMock Condition) are statically imported to clean up the readability a bit.

Ravi said...

Nate,
You said,
"I agree that you shouldn't sacrifice good object design for English readable "sentences", but the two are not mutually exclusive"

I agree. What I oppose(d) is the desire to have code read like English at the expense of good design,and with an explicit intent to avoid "developerspeak".

In the discussion I referred to, the argument for "Should.be(true).blah" etc was based soleley on the "English -like" nature of the resulting sentence.

By that principle the "eq" in teh example you give would be rejected as "not enough like English" and be replaced by something like "Should.makeEqual(something, other)" which in my opinion is nonsense.

As I pointed out in the very first sentence, it is not the principle of "code whould be redable" that is at fault. It is when this principle is understood to mean "code should read like English at any cost" that problems arise.