views:

2792

answers:

26

By favorite I mean the one that gets your goat the most, not the one you enjoy using the most.

I'm fairly new to the concept of anti patterns and I'd like a list of do not do's. An explanation of why it's an antipattern and what problems it causes would be good too.

+26  A: 

The "Daddy" of them all. The Big Ball of Mud. Possibly because every project I've ever worked on, or seen, has ended up using this pattern to some extent or other.

This one is the most important Anti-Pattern as all others are encompassed by it. Its the pattern that tells you how you write code over time. How the best designs end up dissolving as you add extra features, quickly fix bugs, and how those spiral into more and more unmaintainable code. Once you understand how these things happen, you can reduce their impact for the rest of your career, to some extent.

It also gives suggestions for resolving the problems that you end up with. That's very useful too.

gbjbaanb
+13  A: 

My favorite anti-pattern is called Singleton. Typically it is mis-used to ensure that there is a single instance of a given object, rather than refactoring to ensure that only a single instance is created. It makes testing difficult, and can be hard to implement correctly.

Another name for the Singleton anti pattern is "global variables". The name Singleton is often used because it sounds better than calling something a global variable. Global variables have been widely recognised as a bad thing and generally something to be avoided for nearly as long as software development has existed.

References:

1800 INFORMATION
I wouldn't consider a Singleton an anti-pattern at all. It's a very useful construct especially for "helper" or utility objects such as loggers. It is even more important when developing in environments where there are multiple asynchronous requests to process.
iAn
It is also useful with the registry pattern. Although that pattern should be used with caution - many applications call for a small set of "top-level" objects. Also, you can use it for factories.
nlaq
I would hav thought the singleton was a design pattern rather than an antipattern...
Omar Kooheji
Lots of people down on singletons, but I haven't personally seen them abused yet. Not that I don't think its possible....
Will
Any use of the Singleton pattern is an abuse
1800 INFORMATION
The Singleton anti-pattern does not refer simply to having a single instance of an object, which is perfectly fine and exactly what you want for many objects. It refers to the specific method of creating and accessing them, which is often misused for extremely tight coupling.
ColinD
@Colin - Just what I wanted to say, but lacked the words
1800 INFORMATION
+23  A: 

Overuse of design patterns! :)

NeARAZ
Ironic, funny, and true all at once.
Daddy Warbox
I know this as the "Gold-plating" or "Golden hammer" anti-pattern :)
cwap
+3  A: 

In PHP; using php files to execute a SQL query. I have seen this frequently, it will either make me laugh or cry (depending on if I am the one responsible for maintaining it). Here is an example:

**insert_product.php**
$sql = "INSERT INTO products (product_name ...) VALUES ('$product_name', ...)"
mysql_query($sql);

(note: this is the whole file. I've seen them in the hundreds of lines of code, as every field name and value where on a separate line)

Then, to use this awesomely reusable gem of code:

$product_name = "test";
include("insert_product.php");

One time I even say an instance of where the guy was using register_globals to insert the value of a POST form directly into the un-quoted VALUES section of a insert statement...

nlaq
Not exactly an anti-pattern; but close enough. People use this "technique" over and over again in their code thinking they are being clever. So I would assume it counts :)
nlaq
Oh my, I had never seen this. MY EYES!!!
Vinko Vrsalovic
+21  A: 

God object is one of the most common and probably one of the worst anti-pattern you could found, especially in legacy code or large codebases. It just a testability/maintainability killer, which you can't easily refactor (cause it is a 84500 LOC class which is business critical, and you don't have 6 months to spend on this task)

Romain Verdier
Yeech. I've got a potential god object in my project. I need to keep an eye on it.
Will
This could describe pretty much every badly designed database I've ever had the misfortune to work with. We have one table right now that has over 100 foreign keys - any suggestions to changes to that table are met with deadly force. "We can't change that, no time to test everything affected."
HLGEM
6 months isn't enough anyway.
Guge
+8  A: 

Magic Pushbutton is everywhere in web apps, especially since javascript has taken off yet programming ability has remained the same in some webshops ;) It's like the arch nemesis of MVC

Paul Shannon
+2  A: 

I guess I would call it spaghetti-code; but it's much more then that.

In PHP projects, it's very common to see page logic split like:

Index.php:

<html><head>...</head><body><?php include("body.php"); ?></body></html>

Body.php:

switch ($page)
{
   case: "default": include ("bodies/default.php"); break;
   ....
}

Default.php:

include("table_top.php");
print "<tr><td>";
print "Welcome to our site!";

$user = $_SESSION["user"];
if ($user)
{
    include("get_user_info.php");
    print "welcome " . $user_first_name;
}
print "</td></tr>";
include("table_bottom.php");

get_user_info.php:

$user = "root";
$pass = "1234";
include ("db_connect.php")
$sql = "SELECT user_first_name, user_last_name FROM users WHERE user_id = " $user;
$res = mysql_query($sql);
list($user_first_name, $user_last_name) = mysql_fetch_row($res);

It is easy for inexperienced develops to get caught up in this madness. Pretty soon they are repeating functionality, or attempting to change the markup but cant because it is all buried in all this mess. Also, the use of globals when applying this pattern can get very confusing and cause many untraceable bugs.

Most... learn very quickly; but it is a nasty design that you should always stay away with. Prefer MVC; or maybe just having a more consolidated library.

nlaq
+1  A: 

The Magic pushbutton is very common in ASP.NET applications. It leads to poor testability and code duplication among other bad things.

Petter Wigle
+14  A: 
  • Big Ball of Mud: A system without structure or design. This usually happens to systems that been around for a long time, and maintained by lots of individuals who's come and gone. The end result is a system where you have no idea how to digest it.
  • Hard Code: Do I need to elaborate this?
  • God Object: Objects that has too much functionality. Usually happens when the designer of the class has poor understanding of OO.
  • Poltergeist: Objects used only for passing information.

My favorite book on antipatterns is AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis by William Brown. I had a blast reading it!

magius
+3  A: 

This has been asked before.

Blorgbeard
not to be pedantic but that one was commonly used antipatterns, this question is trying to discern what the most irritating ones are.
Omar Kooheji
Well, I suppose that's true - but the questions are very similar, so I think it's helpful to have a link to the other one here.
Blorgbeard
Whatever is old is new again. Human turnover should be accommodated with social online services from time to time.Consider that a new design pattern.
Daddy Warbox
+2  A: 

Death march project. In this pattern managers throwing lots of resources to save a doomed project. Unreasonable working hours or too many developers are partial list of of the results.

It is usually caused by a miss estimation.

Pini Reznik
Someone should fire her...
jTresidder
+6  A: 

I'm suprises that no-one has mentioned: "Yet Another Useless Layer" maybe it'a bit too strong but just make the fun out of to finda certain implementation in gcc and/or the libc from Linux. I can not make myself to believe that it can be good to wade through at least 3 levels of Macros and another five levels of function calls....

I would phrase it differently, there is a "too much levels of indirection".

Another example are OO Frameworks which do use inhertance way to much. E.g for "mimic" functional abstraction.....

Regards Friedrich

Friedrich
Sadly, the levels of macros in glibc are there for a very good reason. The lack of inheritance at the library level (as well as the language level) requires quite a bit of magic to handle both generic algorithms and platform specific accessors. Other systems (such as the soft-fp system) are there to allow both flexibility and speed.
jkerian
Well I'm not sure about that. I cannot see what you mean with the gneric algorithsm in this context. So IMHO there could be one header adopting all the macros for one platform and it does not have to be cluttered all over whatever header they found.
Friedrich
+9  A: 

What I would call "sweeping exceptions under the rug".

In Delphi:

try {do stuff...} except end;

In C++:

try /* do stuff ... */ catch (...) {}

The latter even catches (and ignores) access violations and other win32 exceptions in older versions of VC++, and of course the Delphi version does likewise.

If you're expecting your code to throw a particular exception, by all means catch it and handle it - even doing nothing can be ok, for a particular exception. But ignoring all exceptions, even ones you weren't expecting... it just hides problems and makes bugs more obscure by delaying their effects and throwing away information the original exception would provide.

Hugh Allen
I prefer the Basic name for this one: On Error Resume Next
jfs
It's also called "swallowing exceptions"
Andrei Rinea
@jfs: using On Error Resume Next isn't necessarily ignoring errors - you can test whether an error occurred with Err.Number, Err.Description etc, and the handling code can be right after the error-raising code, which can be nicer and more readable than the usual "On Error Goto" error handler routine.
Hugh Allen
+3  A: 

I usually get anoyed by hardcoded magic numbers and large switch-case-enum-constructions.

EricSchaefer
+1  A: 

I don't know whether it has some official name, but I call it DDD: "Debug driven development". That is when you end up with debugger whatever you do: refactor code, fix bugs or develop new features. I think it would be kind of methodological anti-pattern that appears as a consequence of interactions of many other anti-patterns.

Rorick
I agree largely with your closing statement, that it is a consequence of interactions of many other anti-patterns. Maybe it's a smell!
Guge
+1  A: 

Not sure if this is the same as Nelson's answer (I don't PHP moonspeak) but I've seen this before and it makes me want to vomit:

string userName = UserNameTextbox.Text;
string password = PasswordTextbox.Text;
string sql = "select * where username = " + userName + " and password = " + password;
//etc more bad code

How many antipatterns can you see in that example above?

Will
This is a lack of sanitizing of database inputs. A good gate for SQL Injections... see http://www.safnet.com/writing/tech/archives/2007/10/sanitize_your_d.html
Andrei Rinea
and use of select * is bad as well (never return more columns than you need). And of course you aren't actually referencing a table. Most selects really do need a from clause.
HLGEM
+10  A: 

Copy/Paste

Seeing the same code pop up all over the place, doing the exact same thing. Then having to fix a bug in that code.

QBziZ
Didn't I already fix this bug... six times... last month... in four environments?
Kevin Panko
A: 

My vote would be Lava Flow http://en.wikipedia.org/wiki/Lava_flow_(programming)

Code is added but once a version is shipped to a Customer that part of the code can not be changed. Instead new code that does the same in a slightly better way is added with a flag to enable it or not.

Do that again and again and again to get to a untestable mess.

James Dean
A: 

Anti-Pattern from .Net, that's my favorite one

Ngu Soon Hui
-1 It is not a .Net antipattern, it is a Microsoft Office antipattern.
Guge
@Guge, it is an anti-pattern in VSTO, which is the .Net framework for writing programmatic access to Microsoft Office. It **is** definitely .Net
Ngu Soon Hui
@Ngu Soon Hui, the VSTO is written for use with .Net, but it is not part of the .Net Framework. The office developers could have done a better job by putting all the 2003 interfaces in a separate file and included that in later versions with implementation, ensuring forward compatibility. But .Net itself is not the problem here. IMHO it is misleading to call it an "anti-pattern from .Net". This antipattern can be produced in any technology. VSTO is not .Net, it is .Net applied to Office. If I follow your logic, it is an Intel antipattern, because Intel wrote the microcode in the CPU!
Guge
+5  A: 

I don't know if this one has a name. But I've seen some programmers use Dictionary<string, object> or HashTable where they should have used classes. I think I would call it Misplaced Dynamicity or something.

And putting the keys in constants that are named what they contain does not make it better. Like const string Field23="Field23";

I came across a lot of code like this when taking over a VB.Net application. I started replacing the HashTables with classes. It made to code so much easier to read! In the process I also found some pretty awful bugs, that would have been very hard to find through testing.

I have decided that quote signs are a smell. The compiler does not look at stuff between quotes, so there is no type safety there. For example:

class Foo
{
  public string Bar;
}

Foo f=new Foo();
f.Bar = "content";

Is better than

HashTable Foo=new HashTable();
Foo.Add("Bar", "content");

Because the compiler will catch you saing f.bar in the first example, but not Foo["bar"] in the second.

Guge
+1  A: 

A sub-type of the Gas-Factory I like to call the "Class-Factory."

A module that implements prime-number factorization should not take six classes to do so, and it's bad if it has them anyway because it's "good OOP."

J.T. Hurley
+1  A: 

Mine is clearly Interpreter.

This anti-pattern is also known as Greenspun's tenth rule:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

;-)

Jonas Kölker
+1  A: 

Actually, I'd like to answer the "one you like to use the most" question. It's more fun. For contrarians, at least.

My favorite is SELECT *, because I'm a fan of ORM mechanics where you have an entire coherent row object packaged up together that can be retrieved and then interacted with as one likes. (Of course, the SELECT * is buried deep in the framework. No reason for front-line-developer code to use them; if you're doing something interesting enough that you have to write your own query in the first place, SELECT * would probably be nonsensical.)

I also violate the Law of Demeter like it's going out of style, but since I consider that brain-damaged "law" an anti-pattern in itself, the applicability is debatable.

chaos
+1  A: 

Assembling a team of lazy developers who don't care about continually learning

JuanZe
+1  A: 

Methods calling other methods in the same program by using the GUI.

I'm porting a business line application. It uses the GUI to perform navigation! To pull up the customer view for another customer it sets the focus to the search box, puts the customer id in same, and then fires a keyboard event to simulate a function key press. This function key does not map to a command button, it maps to setting focus to a different text box, because the search and subsequent navigation happens on the lost focus event of the search box! Which view should be presented with the selected customer is of course handled in a global variable.

I hope this isn't a pattern outside of this application, but it is here!

Guge
A: 

I'm building a new user interface on top of the business logic from a poorly layered business application. So when I call the business logic to get some kind of list, and the result is empty, there is one row in the result with a text saying "The list is empty".

It is annoying, because the business logic should just return an empty list. It is for the GUI code to present a text explaining that the list is empty, if that is what the design calls for.

So, to sum up, poor division of application layers is one of my favourite anti patterns.

Guge