Steve Smith's Blog

Musings on Software and the Developer Community

Principles, Patterns, and Practices of Mediocre Programming

This is my first pass at a list of anti-principles, anti-patterns, and anti-practices that make up mediocre programming.  I’m hoping to refine this list and update this listing based on community feedback, so please leave a comment or contact me to let me know what I’ve missed, and I’ll gladly credit you with a name and a link if you’d like.

 

Principles

Fast Beats Right (FBR) – It’s more important to get something done that probably works, or that works right now even if it will be hard to change later, than to spend time ensuring that it is correct or is well designed.  This is classic “cowboy coder” or “duct tape programmer” thinking, and sometimes management may be OK with dictating that for a given feature or prototype, speed is more important than anything else.  However, for typical, long-term projects where someone is going to have to maintain the application for years to come, this can be a very expensive principle to follow.

Preferred Principle(s)

“Continuous attention to technical excellence and good design enhances agility” – Agile Manifesto

Feaping Creaturitis Driven (FCD)  - A project built using FCD never, ever has a cycle that completes appropriately. Just when you can see the horizon, someone on the team adds yet another nozzle or value that they are desperately in love with.

Preferred Principle(s)

Plan with a short delivery schedule, deliver on that plan, and plan the next cycle.  Avoid throwing new work into the current cycle.

“Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.” – Agile Manifesto

Source

Roger Pence (with credit to PL Plauger for the term “feeping creaturitis”)

Assumption Driven Programming (ADP) – Rather than wasting time thinking about edge cases, assume that the user will only use your software the way you mean for them to, and that nothing bad will happen.  This is the quickest way to knock out a feature and be able to demo it to the customer anyway (as long as you are in charge of the demo script), and besides, it should be obvious to anyone how they’re supposed to use the application, so it’s the user’s fault if they do something unexpected.

Some typical “Assumptionist” questions:

“What do you mean, you can’t change the configuration on a shared host?”

“Why would the user type garbage in the address bar?”

“Who would try to put a script file through this image upload form?”

“Why would someone type SQL into a textbox clearly labeled ‘username’?”

ADP often leads to uncaught “sad path” bugs and security holes.

Preferred Principle(s)

Practice some defensive coding, and verify that inputs to your method are what you expect before working with them.

Define with the customer what should happen when the unexpected occurs, and treat this behavior like any other feature.

Write one test for the “happy (expected) path” but write several tests for various “sad paths” where things could go wrong.

Source

Felix Pleşoianu

The Pragmatic Programmer calls this Programming by Coincidence (per Adam)

Telemarketer Principle (TP)  - Programming is about control, and the best way to ensure that your software does exactly what you want is for you to manage exactly when and how it behaves at all times.  The Telemarketer Principle is summed up as “Make lots of calls to anything you might need in the system for your program.”  If you cede control to other modules or let the system or a framework do things on your behalf, can you really be sure they’ll do it right?  And just in case, don’t forget that for anything really important you can always Reinvent The Wheel (RTW) and call your own routine all over the place instead.

 

Preferred Principle(s)

Follow the Hollywood Principle: “Don’t call us; we’ll call you.”  If you find for instance that you’re making Response.Write or Console.Write or Window.Draw calls throughout your business logic, it’s likely that your design would benefit from this principle.

The Dependency Inversion Principle can also help remove dependencies like these, and set up the ability for the callee to become the caller.

 

(do you have more principles of mediocre programming?  Leave a comment below!)

Patterns

Static Cling Pattern (SCP) – Static (global) methods and objects are often an expedient way to add some functionality to an application without spending any time worrying about where the “right” place for it to live might be.  Using static methods for truly stateless operations that work only on the parameters passed in and do not have any other dependencies is fine, but problems arise when static methods instantiate objects or call other methods outside the scope of the passed in parameters.  Once this has gone on for a while, it can be very difficult to introduce seams into the application to decouple its components from one another – it has begun to suffer from “static cling”.

Preferred Pattern(s)

Dependency Inversion Principle.  Calls to static methods are direct dependencies that cannot be easily injected.  Replace them with interfaces and calls to instance methods on injected objects.

More Reading

Static Methods are Death to Testability

Source

Bob Lee, (of Guice) - (via Nate Kohari)

Vestigial Structures Pattern (VSP) – When features are removed that span multiple tiers, the bits that are no longer used are left behind “just in case.”  As in biology, Vestigial Structures are usually in a degenerate, atrophied, or rudimentary condition, and tend to be much more variable than similar parts. Although structures usually called "vestigial" are largely or entirely functionless, a vestigial structure may retain lesser functions or develop minor new ones.

Preferred Pattern(s)

Vestigial Structures are typically symptoms of a muddled architecture, where it is difficult to tell where one feature ends and another begins.  See also Big Ball of Mud.

Source control.  Delete it if it’s not used; if you end up needing it, pull it back out of source control.

Source

Richard Dingwall

Flags Over Objects (FOO) – Instead of using objects, polymorphism, or delegation, it’s much faster to just add a flag to a class and expose it.  Then anywhere in the system that cares about that condition can simply add an if(foo.IsBar()) { … } clause to deal with this condition.  Who needs inheritance?

Preferred Pattern(s)

Replace Conditional with Polymorphism, Refactoring, p255 (online)

Source

Curtis Cooley

The God Class (TGC) – Everybody knows that object-oriented programming is great because it lets us leverage and reuse classes to do all the work in our programs.  And of course, nobody wants to have to look for the right class to do something, and the more classes you have, the less powerful each one is.  It’s much better to just write (in Lord of the Rings voice here) one class to rule them all, a master class, capable of doing anything and everything your application might require.  And who cares if it’s 5,000 lines of code?

Preferred Pattern(s)

Follow the Single Responsibility Principle (SRP), which states that a class should have only one reason to change.  If your class has more than one responsibility, it should be split into several classes.

Source

Corey Coogan

 

Data Driven Architecture (DDA) – Professional developers know that building applications in layers or tiers is a best practice.  The traditional approach is to have at least 3 such layers: UI, Business, and Data.  When organized following the DDA pattern, the Business Layer will reference the Data Layer, and the UI Layer will reference the Business Layer.  This is obvious, since clearly the Business Layer needs to be able to fetch and persist data, so it has to reference the Data Layer, and the UI layer needs to provide an interface to the Business Layer, and so must reference it.  The benefit of this layered approach is that the Data Layer could, theoretically, be completely rewritten without any changes being made to the UI layer.  Only the layer one step up would need to change (and it must change, since any interfaces used can’t belong to the Business Layer using this approach, because then the Data Layer would need to reference the Business Layer in order to implement such interfaces, creating a circular reference.

Preferred Pattern(s)

The application’s Business Layer should be its Core.  It should not depend on anything if possible, and certainly not on Infrastructure like data access.  All project dependencies should point to the Business Layer / Core, which should define the interfaces it requires its collaborators to implement.  See Onion Architecture and Hexagonal Architecture.

The Dependency Inversion Principle can be valuable in achieving this reversal of project reference direction.

(do you have more patterns of mediocre programming?  Leave a comment below!)

 

Practices

Found On Internet (FOI) – When faced with a problem, the quickest fix is often to search the Internet.  This is a valuable and effective way to research solutions.  The mediocre programmer’s approach to this, however, is to locate the first blog post or forum response that looks like it might be a fit to the problem at hand, and then to cut and paste the code, hack at it until it compiles, and run the application to see if it seems to work.  If it does, move on to the next fire.  If not, continue hacking until it does or go to the next item in the search results.

Preferred Practice(s)

Spike a solution using the found code and see if it works in a variety of scenarios. 

Write some tests to confirm the behavior of the code does what it claims and works according to your expectations. 

Review a variety of possible approaches to the problem and try to determine if you’re actually asking the right question before jumping on a possible solution.

Premature Optimization (PO) – Developers like to write code that runs as quickly as possible.  Certainly, performance is one factor in nearly all software, but like all factors it must be weighed against other attributes like maintainability and velocity of feature delivery.  The practice of optimizing code before one knows if a bottleneck exists in the current code, or if the actual production performance of the application will not be sufficient without such optimization, tends to result in waste.  More often than not, the code being optimized is either good enough as is, or simply is not the bottleneck and thus any optimizations made to it will not impact the actual performance of the application.

Preferred Practice(s)

Get actual performance requirements from the customer and write tests to ensure that given scenarios comply with these performance requirements.  Do not optimize unless these tests fail.

Collect actual data on the performance of the application and identify where the bottlenecks are.  Spend your time eliminating the actual bottlenecks identified by your analysis, rather than guessing where the problem might be.

Copy-Paste-Compile (CPC) – Sometimes an application exhibits a bug or requires new functionality that has already been corrected elsewhere.  All that needs done is to locate the correct section of code, copy it, and paste it into the section of code that requires this behavior.  Make sure it still compiles and check it in.  Another task complete!

Preferred Practice(s)

Get actual performance requirements from the customer and write tests to ensure that given scenarios comply with these performance requirements.  Do not optimize unless these tests fail.

Collect actual data on the performance of the application and identify where the bottlenecks are.  Spend your time eliminating the actual bottlenecks identified by your analysis, rather than guessing where the problem might be.

(whoa, did someone copy and paste the above and forget to update it?)

Follow Don’t Repeat Yourself and move logic that repeats into its own methods or objects.  Fight duplication wherever you find it in your code.

Reinventing The Wheel (RTW) – Part of an application requires a little algorithm or utility that no doubt someone else has encountered before, but rather than using an existing framework class or well-known industry solution, the developer takes this as an opportunity to write the best XXX utility ever.  It’s often more fun to write an algorithm or regular expression than to deliver yet another boring business form or report, but reinventing the wheel doesn’t add value.  (also seen sometimes as Not Invented Here (NIH)).

Preferred Practice(s)

Know and use the framework.  If you’re a .NET developer, the .NET framework has a ton of functionality in it and is usually a good first place to look.

Share knowledge within your organization.  It’s likely someone else in your company already has solved this problem.

Quickly estimate the time it would take to build the functionality from scratch, and the cost of your time.  See if a commercial tool could do the job for less, and see if management is willing to invest in such a tool.

Copy Folder Versioning(CFV) – Sometimes, changes to an application are big enough that they seem scary (even to a cowboy coder), so they decide to make a backup.  Of course, there’s no source control software in use, so naturally the way to go is to make a copy of the folder containing the project (and, if you’re being extra professional, rename it from “Copy (2) of FooProject” to something more useful).

Preferred Practice(s)

Use Source Control!  Please, if you’re still not using some kind of source control, start doing so today!

Seriously, use source control.

Source

Brendan Enrick helped come up with the TLA for this one.

 

Golden Hammer (GH) – The Golden Hammer refers to a particular language, framework, library, or tool with which you are familiar, and with which you’re certain you can solve any problem.  When wielding the Golden Hammer, every obstacle looks like a nail, and any suggestions by teammates that other tools might be better-suited to the task at hand go unheard. (aka Silver Bullet, Magic Bullet)

Preferred Practice(s)

Learn or at least become familiar with a variety of languages, tools, and frameworks.  Keep an open mind about how to approach problems as you build an application.

Source

Peter Hickman

 

Shiny Toy (ST) – The Shiny Toy is latest, coolest tool or technology available.  Its potential is boundless.  It can solve world hunger and bring about lasting peace in the Middle East.  But it’s still beta so of course you need to spend some time learning it, since there’s no documentation for it yet and nobody you’ve heard of has released a live application running with it.  You’re sure it will do everything the application needs, though, without too much extra effort… (this is related to the Golden Hammer practice, above, but taken to the opposite extreme.  Sometimes you will find someone who thinks their Shiny Toy is a Golden Hammer, though!).

Preferred Practice(s)

Prefer existing and well-known tools and patterns to unproven ones for production use.  Learn about the new on your own time, at conferences, for your blog, or if you’re sure it solves a real problem the application has, with a spike solution that can quickly demonstrate whether or not it will work.

Source

Kevin Babcock (renamed “Shiny Toy” by Steve Smith)

 

(do you have more practices of mediocre programming?  Leave a comment below!)

Additional References

    kick it on DotNetKicks.com

Thursday, 08 October 2009

Comments

 avatar

Dave Swersky said on 08 Oct 2009 at 3:35 PM

One of the anti-patterns that drives me nuts is the "Not Invented Here" (NIH) pattern. It states that if an idea comes from outside it has no value. This tends to encompass open-source projects but often includes competing (as perceived) ideas from other groups within the same company! NIH often happens when a solution is needed to a particular problem. The problem may call for a technique, an entire framework, or a methodology.

The Preferred Practice in this case would be what I call Merit Evaluation. Developers of varying backgrounds will solve problems differently, using different tools. Let each developer choose and champion the tool (framework/technique/method) of his/her preference. Have these champions come forward and present, to the development team, a balanced evaluation of the pros and cons involved in using that tool. Now let the smart people who do things (developers) decide as a group.


 avatar

Roger Pence said on 08 Oct 2009 at 4:47 PM

Principle: FCD

Feeping Creaturitis Driven

(PL Plauger, should, I think, be credited with having created the term "feeping creaturitis.")

When a project is built using FCD, it is never, ever has a cycle that completes appropriately. Just when you can see the horizon, someone on the team adds yet another nozzle or value that they are desperately in love with.

The preferred pattern is to plan with a short delivery schedule, deliver on that plan, and then plan the next cycle. No fair throwing something into the works before the next cycle.


 avatar

Richard Dingwall said on 08 Oct 2009 at 4:54 PM

Vestigial Structures (VS)

When you remove a feature that spans multiple tiers, but leave bits behind that no longer serve any purpose.

As in biology, Vestigial Structures are usually in a degenerate, atrophied, or rudimentary condition, and tend to be much more variable than similar parts. Although structures usually called "vestigial" are largely or entirely functionless, a vestigial structure may retain lesser functions or develop minor new ones.

Vestigial Structures are typically symptoms of a muddled architecture, where it is difficult to tell where one feature ends and another begins.


 avatar

Curtis Cooley said on 08 Oct 2009 at 6:31 PM

If Bug Programming or Over Use of Flags. See ponderingobjectorienteddesign.blogspot.com/.../if-bugs.html

Instead of using objects, polymorphism, or delegation, programmers in a hurry or just out of ignorance or laziness, just add a flag and expose it. Then all over the system you see "if (foo.isBar())..." which is a fertile breeding ground for bugs.

Preferred method: Replace Conditional with Polymorphism, Rafactoring pg 255.


 avatar

Felix Pleşoianu said on 09 Oct 2009 at 4:38 AM

I blogged about my pet programming peeves in a previous life. Maybe you can find something useful there.

profiles.yahoo.com/.../FFXG7KNZPDPAKTN


 avatar

Adam said on 09 Oct 2009 at 1:42 PM

The Pragmatic Programmer calls ADP Programming by Coincidence.


 avatar

Corey Coogan said on 09 Oct 2009 at 1:52 PM

What about the God Class anti-pattern. When talking with clients and doing code reviews, I often harp on SRP, as well as other aspects of SOLID.

The number one reaction I get is "that seems like a lot of code just to do a few small things." Those who respond in this way find it easier and faster to just add another huge method to a huge class. For them, that makes more sense than "adding all that extra code", which in reality is the 3 lines it takes to declare a class and wrap it in squiggly braces. God forbid the need of a constructor, which could add up to 10 more lines of code.


 avatar

Peter Hickman said on 12 Oct 2009 at 4:01 AM

Then there is the Golden Hammer pattern. I can write programs in X therefore the best solution to this problem is to write it in X. Where X is a language, framework or just a library.


 avatar

alecs said on 12 Oct 2009 at 10:42 AM

Someone (Corey Haines) told on a conference: "Write your own code as the maintainer is psychopat who knows where you live"...


 avatar

JSmith said on 12 Oct 2009 at 10:52 AM

Nice post.

I once attended a C++ lecture by Stephen Dewhurst. During his lecture, he presented an interesting piece of code. It was a complex looking thing, with lengthy case statements and yes, "goto" statements and as well as extensive use of globals. The audience responded to the code with sighs of disbelieve and disgust.

Then he dropped the bomb, "I challenge anyone here to come up with a better solution".

No one could.

He used a great phrase to explain the code, "consider ALL the forces on this problem". The time the engineer had to solve the problem, the general environment, etc. Rules are meant to be broken.

Bottom line is to remember code never exists in a vacuum.


 avatar

Kevin Babcock said on 12 Oct 2009 at 12:45 PM

Similar to the "Golden Hammer" pattern, how about a "Silver Bullet" pattern? This is where a developer or team is overly concerned with the newest, shiniest tool available. Instead of focusing on the development of a good solution to their business need they spend all their time learning how to use the latest toy or framework in hope that it will be a silver bullet for all their problems.


 avatar

Giorgio Sironi said on 13 Oct 2009 at 1:31 PM

These are great examples, good blog. I'm going to subscribe to your feed after this comment.

However, the "preferred principle/pattern" heading can be misinterpreted as preferred by the mediocre programmer... I have mumbled a bit before figuring out it was the correct principle to apply.


 avatar

eric said on 15 Oct 2009 at 6:11 AM

hi! IT's a nice blog....


 avatar

Jeff Dickey said on 15 Oct 2009 at 10:45 AM

MBM principle: (Management By Magazine)

The preferred problem-solving approach for non-technical or, worse, formerly technical PHBs. It is expressed when an individual with corporate authority but completely ignorant of the true "situation on the ground" reads an advertising blurb in a glossy ZD-style magazine and imposes it as The Solution.

Contrast with Golden Hammer, Shiny Toy, and Found On Internet - all of which at least have the (arguable) value of being sponsored/pushed by a reasonably technically literate individual who does/should know that his job and his colleagues' jobs are at least potentially at risk. The MBM perp, by virtue of his exalted position, ordinarily has complete plausible deniability for any failures imposed by his favored policy - after all, nobody expected HIM to be technical enough to get involved in the first place - by doing so, management spin says, he was "taking initiative." Commonly cited analog: the Great Leap Forward.


 avatar

Brad said on 21 Oct 2009 at 7:05 PM

I was searching for what I need and I came across this junk! Forget all this talk and just <a href="http://forums.thedailywtf.com/forums/p/7419/139496.aspx#139496">give me teh codez</a>


 avatar

pete said on 08 Jan 2010 at 11:54 PM

Then there is the Golden Hammer pattern. I can write programs in X therefore the best solution to this problem is to write it in X. Where X is a language, framework or just a library.


 avatar

ngan hang said on 15 Jan 2010 at 3:33 AM

I found your website perfect for my needs. It contains wonderful and helpful posts.


 avatar

C# said on 27 Jan 2010 at 4:41 PM

When it comes to programming, I am a self confessed hack. I started with ColdFusion (yeah, I can hear you snickering), moved up to PHP and now currently am enjoying the fruits and labor of C#. I think the biggest issue for all of us though is the dreaded scope creep...


 avatar

Prometheus said on 27 Feb 2010 at 9:14 AM

"Fast Beats Right (FBR)"

That seems to be the principle MS has used. And look what a failure its become.


 avatar

Brendan Enrick said on 10 May 2010 at 4:22 PM

Don't forget that you can keep all of your code in the same namespace, which will save you tons of lines of code in your projects. Think of all of the using statements you will be able to remove.


 avatar

Jack Sprat said on 19 Jul 2010 at 7:23 PM

How about "Shotgun Variables", where the programmer gives the variables as wide of a scope as possible, "just in case". Why worry about making a variable private when you can give it global scope?!


Leave a Comment

Please join the discussion and share your thoughts.