AntiPattern Name: Functional Decomposition
Also Known As: No Object-Oriented AntiPattern “No OO”
Most Frequent Scale: Application
Refactored Solution Name: Object-Oriented Reengineering
Refactored Solution Type: Process
Root Causes: Avarice, Greed, Sloth
Unbalanced Forces: Management of Complexity, Change
“This is our ‘main’ routine, here in the class called LISTENER.”
Functional Decomposition is good in a procedural programming environment. It’s even useful for understanding the modular nature of a larger-scale application.
Unfortunately, it doesn’t translate directly into a class hierarchy, and this is where the problem begins. In defining this AntiPattern, the authors started with Michael Akroyd’s original thoughts on this topic. We have reformatted it to fit in with our template, and extended it somewhat with explanations and diagrams.
This AntiPattern is the result of experienced, nonobject-oriented developers who design and implement an application in an object-oriented language. When developers are comfortable with a “main” routine that calls numerous subroutines, they may tend to make every subroutine a class, ignoring class hierarchy altogether (and pretty much ignoring object orientation entirely).
The resulting code resembles a structural language such as Pascal or FORTRAN in class structure. It can be incredibly complex, as smart procedural developers devise very clever ways to replicate their time-tested methods in an object-oriented architecture.
You will most likely encounter this AntiPattern in a C shop that has recently gone to C++, or has tried to incorporate CORBA interfaces, or has just implemented some kind of object tool that is supposed to help them. It’s usually cheaper in the long run to spend the money
on object-oriented training or just hire new programmers who think in objects.
Symptoms And Consequences
Classes with “function” names such as Calculate_Interest or Display_Table may indicate the existence of this AntiPattern.
All class attributes are private and used only inside the class.
Classes with a single action such as a function.
An incredibly degenerate architecture that completely misses the point of object-oriented architecture.
Absolutely no leveraging of object-oriented principles such as inheritance and polymorphism. This can be extremely expensive to maintain (if it ever worked in the first place; but never underestimate the ingenuity of an old programmer who’s slowly losing the race to technology).
No way to clearly document (or even explain) how the system works. Class models make absolutely no sense.
No hope of ever obtaining software reuse.
Frustration and hopelessness on the part of testers.
Lack of object-oriented understanding. The implementers didn’t “get it.” This is fairly common when developers switch from programming in a nonobject-oriented programming language to an object-oriented programming language. Because there are architecture, design, and implementation paradigm changes, object-orientation can take up to three years for a company to fully achieve.
Lack of architecture enforcement. When the implementers are clueless about object orientation, it doesn’t matter how well the architecture has been designed; they simply won’t understand what they’re doing. And without the right supervision, they will usually find a way to fudge something using the techniques they do know.