Friday, August 18, 2006

The "Not-Enough-Objects" anti-pattern

Definition:
This is a pattern that every single programmer in the world had used at one point or another in their programming careers. Classes become unnecessarily bloated and multi-talented in their ability to single-handedly accomplish almost anything and everything an application requires.

Root Causes:
Being lazy to create new classes for new but not aligned behaviors into existing objects; being ignorant on good objects commuication and interactions; lack of concern of each objects' goal of existence; failure to realize the importance of programming to interfaces; putting off code refactoring forever (the "kitchen sink" syndrome 1); embraces code babies2 as if they are the next American Idols; failure to effectively organize, categorize, and classify application functionalities.

UML:
eg.

Customer
+ OrderSoda() ~20 LOC
+ Sleep() ~100 LOC
+ RPCCallTolMom() ~250 LOC
+ PlayTVGames() ~500 LOC
+ WebServiceCallToWalkMyDog() ~3,000 LOC
+ RepeatRoutineEveryDay() ~275 LOC
.
.
.
(many more methods)

Symtoms:
When it appears in your code, they make your code become demoralizingly hard to read or comprehend; extremely difficult to touch code without introducing new errors; code become very brittle; code starts to look like POOP (Procedural Object-Oriented Programming); exponentially increase your programmers' after-hour caffeine consumption to life-threatening level against others (e.g. "I will kill the xxx if I knew who wrote this").

How to Avoid:
Avoid 1,000 line classes and/or 200 line methods; avoid class behaviors that are mutually exclusive; avoid class states that are mutually exclusive; avoid classes to have multiple responsibilities in favor of delegating to new objects that the classes use; avoid too many if-else statements in favor of object hierarchy (see Strategy); effectively categorize or organize your classes/namespace/file/folder structures into meaningful and humanitarian fashion; encourage collective code-ownership; frequently communicate with team members the intent of each object; feverishly unit test the heck out of each class and object using mocks and stubs; use TDD as test-driven design to think how other objects will use the object you are unit testing; pair-program with someone who reminds you of code quality is of utmost importance.

Short List of Skills Required to Avoid:
1. Programming to abstraction and not implementation
2. Object encapsulation
3. "Tell, Don't Ask" and the Law (or guideline) of Demeter (link), go back to #2 if you do not understand
4. Short methods/classes with well-intended names in favor of plethora of comments
5. Unit testing
6. All your unit tests run in sub-10 secs. because you understand Mock vs. Stub (link)
7. Dependency Injection (link)
8. Decoupling and cohesiveness (related to object-to-object communications)
9. Knowledge of design patterns of all types
10. Knowledge of anti-patterns

After-Thought:
Have we understood why good programmers are rare?

(1) kitchen sink syndrome: If it is clean, it stays clean. Once dirty dishes goes in and no one bothers cleaning up, dishes will start piling up and they never get cleaned.
(2) code babies: A snippet or chunk of code, or application functionality that is given birth by its genetically related programmer that no one else in the planet understands or dares to understand.

1 comment:

Anonymous said...

Great article. Unfortunately, there's a lot of POOP in the code at my workplace. I make POOP too, but it's not as foul smelling as others' POOP.

I look forward to refactoring and flushing out the POOP from our code.