Best practices are like everything else. There are times to ignore or break the rules. The anti-pattern we cover in this episode results from not doing so. The poltergeist anti-pattern occurs when we have a bunch of infrastructure code that serves the design but is otherwise useless. When you are creating methods and classes solely as place-holders or pass-throughs, then you are feeding this anti-pattern.
Defining the Poltergeist Anti-Pattern
Once again, I found the best definition for our purposes in a blog article about anti-patterns. [Click Here to See The Page]
“Useless classes with no real responsibility of their own, often used to just invoke methods in another class or add an unneeded layer of abstraction.“
You might think of these sort of methods or classes as “filler” much like the stuff in boxes when you are shipped an object that could bounce around in its package. However, shipping filler provides more value. The challenge is that there might be a fine line between short methods and poltergeists in your thinking. In that case, you can find guidance in this post, discussion, and comments.
Design To Taste
The most common source of the poltergeist anti-pattern is a designer that grabs a template or best practice intended for much larger systems. We see this when a student comes out of college into the real world and has a bad habit of including unneeded programming concepts. It is almost like a Golden Hammer or Boat Anchor situation. Instead of code or a product being treated as the perfect fit, this time the culprits are design concepts. For example, designing for flexibility that will never be used. We see this when a system is designed to plug-and-play with the database back end yet there will never be any database used outside of the original decision. We do not need to create flexibility when it is not used.
Understand The Cost
All design decisions include trade-offs. Think about it for a minute. A hard-coded, brute force solution is almost always going to be the fastest one. There is less for the computer to process. A simple example may help.
Let’s think about a program to add 3 to 5 and print out the result. In pseudocode you can probably write it like this:
output(3+5)
The computer will parse the expression (3+5), execute it and print out the result. A prettier, but slower example might look like this:
Function outputSum (x, y) { z = x + y output(z) return } x = 3 y = 5 outputSum(x, y)
While both approaches give you the results, one is faster to write and execute. If you do not need to use that “outputSum” function anywhere else, then why write it? This thought process is exactly the one we need to avoid a poltergeist. While we ask ourselves whether a block of source that is repeated should be abstracted to a method or function, there also should be a question whether a method is needed if it only is called once.