views:

427

answers:

13

I'm looking to see how other programmers find anti-patterns, "code-smells", etc.

In particular, what things start setting you off when you're looking at code that tells you, something has gone wrong here?

I'm not looking for a list of different patterns like this post. I want to know how you've found such things in code bases you've worked on in the past.

+1  A: 

I think it pretty much boils down to experience and intuition.

Christopher
Agreed. "I know it when I see it"
Matthew Flaschen
+8  A: 

Actually, the first and most clear warning sign that there is something severely wrong is not at all in the code; it's in the organization. Organizations that display clearly toxic or bizarre traits tend to have codebases that show antipatterns. It's uncertain as to whether the codebase being messed up is the result of the antipattern, or the organization being messed up is the result of the codebase being messed up, but the upshot is that the easiest way to notice an antipattern is to see something going horribly wrong in the organization.

Sometimes, it can be a while before you get deep enough into the codebase to determine that the codebase is complete spaghetti; usually before that, though, you'll find a coworker who explains with a wry comment that "you don't want to open Pandora's box by trying to change anything". Long work hours can be another indicator of antipatterns at work; so can "guru syndrome" ("Bob's the guru; he's the only one who understands the system"). These things all show up as organizational problems far before you end up seeing them in code.

Since there seems to be a desire to get some metrics as to what a dysfunctional organization is, here are a few indicators (by no means exhaustive):

  • Massively disgruntled workers
  • Timekeeping obsessed management
  • Shoehorning ("Golden hammer" antipattern)
  • High turnover rate among engineers
  • Bad ratio of dev / test (either too high or too low is an indicator)

These aren't really metrics; they're just really warning signs. It really comes down to personal experience to know what constitutes "massively disgruntled" versus "mildly disgruntled", etc.

McWafflestix
+1 Nice one, I would definitely concur that bad organization is a good indicator.
Joseph
What are the metrics of bad organization?
altCognito
@altCognito: very good question; very hard to determine. seriously out of the scope here, but it's a good question.
McWafflestix
Since very few organizations exist solely to create code (there are some, but most places do something else and they need software to make the whole enterprise go), a dysfunctional organization probably leads to bad code more than bad code leads to a dysfunctional organization.
Michael Kohne
@Joseph and @altCognito: I'll add to the answer.
McWafflestix
Nice list of organizational anti-patterns. Doesn't answer the question directly. Instead it provides some kinds of leading-indicators.
S.Lott
+3  A: 

Anti-patterns are identifiable the same way patterns are; they're both descriptions of a general technique that "smells" the same no matter where you find it. So when you see a class that imports most of the available namespace, has 30 000 lines, and has more commits than the rest of the codebase combined, chances are you're looking at a God Object.

The important thing to note, I think, is that (as McWafflestix and Christopher point out) bad code is like obscenity. You know it when you see it.

DDaviesBrackett
+1: It's a pattern when it repeats. A repeated code smell is an anti-pattern.
S.Lott
A pattern that stinks. You see it and go "uh oh". A pattern not to repeat. A pattern to avoid.
bobobobo
+4  A: 

One of the things I notice fairly quickly is the amount of historical comments and commented out code. This is typical of developers that don't use or don't trust source control.

Otávio Décio
+1 For poor use of source control.
Joseph
+7  A: 

Here's the giveaways:

  • Lots of side effects
  • Lots of regressive bugs
  • Very difficult to test
  • Doesn't fit in with other libraries
  • Difficult to refactor
  • Difficult to extend.

Come to think of it, this is pretty much any bad code.

altCognito
+1 Nice list. I particularly like the difficult to test bullet point. Refactor and extend are great indicators as well I think.
Joseph
+1  A: 
Richard Watson
+1 For hard to rewrite and brittle.
Joseph
+2  A: 

-Whenever asking about a section of code/module produces a response of "Oh, XXX did that."

-Whenever changing a section of code produces a reaction of "Yikes, I can't believe you changed that."

GWLlosa
+1 For bringing in the social aspect of things =)
Joseph
+5  A: 

I ran the Eclipse Metrics plugin.

When you have many, MANY methods with cyclomatic complexity scores of well over 20 (one was 66...) and regularly see methods with dozens of parameters or hundreds of lines of code, you know something has gone wrong.

It doesn't tell you everything (metrics never do), but when you start seeing numbers like that, it gives you a place to start looking.

Adam Jaskiewicz
+1 For cyclomatic complexity.
Joseph
Nice, I've never tried this plugin, but I'm sure I will now.
altCognito
+1  A: 

My personal pet peeve in this regard is a large number of "dummy" or "mockup" forms. Wherein someone creates a mockup of the form, then creates a new mockup when the requirements change, then creates a third mockup when they stabilize, and then, finally, makes the real form. At the end, you wind up with file names like

-frmAddUserWizard
-frmAddUserWizardv2
-frmAddUserWizard_MOCKUP
-frmAddUserWizard_OLD

And ALL of these forms are accessible from the application, because we need to display them to take a screenshot to show the user! At a glance, its impossible to tell which of the forms is the real one (tip: in the above example, its the second entry). But nobody wants to delete the old code, because they represent work that they put in, and they don't want to part with it.

edit: This can also happen when forms get re-used in the application, and "copypasta" inheritence is used.

GWLlosa
Or they aren't using version control and are scared of breaking something permanently via deletion.
Wyatt Barnett
Or even worse, something with the comment of "John 01/08/03: Delete this as it's not used anymore".. It's 6 years old, do I remove it? do I not?.. Chances are it'll just stay there and rot. Of course, any testing framework or version control in this instance would just be wishful thinking.
gridzbi
+2  A: 

When the comments have the word "trick" in them, as in "A trick for figuring out which customer to return when we don't know which one we are supposed to use.

Seriously, I think it's like obscenity: You'll know it when you see (smell) it.

  • code with lots of bugs logged against it, but the code itself has not been updated in 3 years or more.
  • database structures with comma-delimited values within a single column
  • code with no comment, no meaningful names, and and lots of numbers
  • code where there's only one guy or gal who is allowed to maintain it.
Karen Lopez
+3  A: 

McWafflestix has a lot of good points at the organizational level. A dysfunctional software engineering organization will make it nearly impossible to produce good code, if only for simple pragmatic reasons such as lacking decent tools and automation.

Even with a functional organization and good tools, however, anti-patterns can grow on you. Some characteristics I look for are below, with the rules of thumb I use in parentheses.

Some signs:

  • In OOP, extremely deep object hierarchies (more than 3 levels)
  • Copy-and-paste code that appears multiple times (more than 3) OR code in multiple locations that performs substantially the same function
  • Copy-and-paste code with minor/subtle changes that cannot be easily/sensibly parameterized

I also tend to look for areas in the code which are not intuitive, readable, (insert favorite adjective here). This speaks less to code quality and more to your team's ability to work together effectively. Over time, a team's codebase usually picks up a dialect - common semantics and vocabulary for method and variable names, informal conventions about ordering methods or operations, etc.

Ensuring the consistency of that dialect can help significantly, especially when one team member has to work on a segment of code that had, until that moment, been maintained by another person. When code begins drifting substantially enough off the common dialect, that can be a sign that a design anti-pattern is emerging.

Winky
@Winky When you say "deep object hierarchies" I assume you're referring to your own code base? Just to clarify.
Joseph
Typically yes, that kicks in when designing your own object hierarchies. It can occasionally kick in when extending another library as well (if you find yourself writing 2-3 levels of subclasses to customize some piece of behavior).
Winky
A: 

Sorry to add to this late - I just wanted to contribute that in my experience a lot of cruft in the main codebase seems to indicate that no-one has really cared for it. For instance you have classes that seem to do something but you find they have been superseded by other development and are never called, having investigated at length.

callcopse
Bear in mind that some may be used under special circumstances, such as with an old file. Keeping cruft around because it's used is one thing; keeping it around when it isn't used is another thing entirely.
David Thornley
A: 

Conflicting Styles.

When you read through the code, you quickly figure out who wrote it- Joe always uses state machines, John always uses event driven callbacks, and Fred is Mr Two-line-function.

If their style reflects the needs of that part of the program, great, but when it reflects dueling architectural ideas, with no one in particular winning, then you know the code really smells.

kmarsh