views:

2874

answers:

65

I have been working on a list for a while that helps me share the why of programming approach and thought as much as how to do something.

For this, I wanted to build a list of things that are:

  • best practice,
  • best thought,
  • best approach...

that help a programmers ability to analyze, think, approach, solve and implement in the most effective way.

I have seen dozens of incredibly valuable comments in questions throughout SO but I couldn't find a place where we keep them together. There is the most controversial opinion on SO, however I'm just looking for sagely insights that can be shared and help my team and I approach and solve problems better through better programming.

Hopefully this can be one place to gather the one or two liners that are concise, profound and easy to share, repeat, review. If we keep it to one rule per answer it might be easiest to vote up/down.

I'll start with the first.

DRY - Don't Repeat Yourself - In code, comments or documentation.

EDIT: This is now a community wiki. Appreciate the flood of answers!

+6  A: 

Publish Early, Publish Often

Jens Roland
Wow, zero upvotes for this principle? Are there *no* web developers or Agile programmers out there?
Jens Roland
Ahh, that's more like it :P
Jens Roland
+52  A: 

Always leave the code a little better than when you found it.

Torsten Marek
Agreed. I wrote about this exact topic with some examples at http://www.moserware.com/2008/10/boy-scout-check-ins.html
Jeff Moser
Subjective! [Closed]!
Chris S
Dangerous, without unit tests!
Steven A. Lowe
Who doesn't:) I mean, this rule also doesn't apply when you have to maintain the Windows code base or the on-board software of a plane.
Torsten Marek
+5  A: 

Convention over Configuration

Especially where conventions are strong and some flexibility can be sacrificed

Jens Roland
+44  A: 

Code does not exist until entered into a versioning system

Jens Roland
+2  A: 

Design patterns are your friends

Make sure to keep a copy of the Gang Of Four book lying around somewhere as a reference.

Jens Roland
+26  A: 

Someone else won't fix it.

If a problem comes to your attention, take ownership long enough to ensure it will be taken care of one way or another.

Rex M
here, here. also required, _time_ to do the above
jskulski
Also: _You_ won't fix it later, do it now.
pi
You might not remember what needs to be done to *fix it* when/if you come back to it later.
Chris Ballance
+5  A: 

Build Breaker Buys Lunch

Webjedi
But it's not really fair cuz I'm a team of one.
Webjedi
@Webjedi Buying yourself lunch, whats wrong with that?
Nathan W
It gets expensive...I think I need to hire some very junior programmers so I can save some money. :-)
Webjedi
I can see our recruitment policy changing...
James Ogden
Seems like a good way of promoting a blame culture, voting this down
willcodejavaforfood
@webjedi: ok, so the days you break the build dont buy lunch :)
if you break the build, you get to stay late and fix it
Steven A. Lowe
+14  A: 

Test Driven Development (TDD) makes coders sleep better at night

Just to clarify: Some people seem to think TDD is just an incompetent coder's way of limping from A to B without borking everything up too much, and that if you know what you're doing, that means there is no need for (unit) testing methodologies. That completely misses the point of Test Driven Development. TDD is about three (update: apparently four) things:

  1. Refactoring magic. Having a full set of tests means you can make otherwise insane refactoring stunts, juggling the entire structure of your application without missing even one of the two hundred crazy subtle side effects that result from it. Even the best programmers are reluctant to refactor their core classes and interfaces without good (unit) test coverage, because it's damn near impossible to track down all the little 'ripple effects' it causes without them.

  2. Detecting pitfalls early. If you are writing tests the right way, it means forcing yourself to consider all the fringe cases. Often, this leads to better design choices once the actual development begins, because the coder has already considered some of the trickier situations that may call for a different inheritance structure or a more flexible design pattern. The need for these changes is often not apparent - or intuitive - during initial planning and analysis, but those exact changes can make the application much easier to extend and maintain down the line.

  3. Ensuring that tests get written. TDD requires you to write the tests before writing the code. Sure, that can be a pain in the ass, since writing tests is tedious compared to writing actual code - and often takes longer, too. However, doing so is the only way to make sure the tests will be written at all. If you think you'll remember to write the tests once the code is done, you're almost always wrong.

  4. Forcing you to write better code. Since TDD forces all code to be testable (you don't write code before there is a test for it), it requires you write more decoupled code so that you can test the components in isolation. So TDD forces you to write better code. (Thanks, Esko)

Jens Roland
I would also add, that since TDD forces all code to be testable (you don't write code before there is a test for it), it requires you write more decoupled code so that you can test the components in isolation. So TDD forces you to write better code.
Esko Luontola
+28  A: 

Don't reinvent the wheel

If there ought to be a function for it in the core library - there probably is

Jens Roland
And in the case of Java: if it *isn't* in the core library, it's probably in Apache Commons.
Moss Collum
Good point :) And in the case of PHP, if it isn't in the core library, it's in a PEAR or Zend extension
Jens Roland
And even if it oughtn't be in the core library, it's probably in CPAN.
Dave Sherohman
Or ... the Internet.
strager
And if it's not in the .NET Framework, there's probably something you can download (MVC, AJAX, etc.)
Richard Gadsden
hmm I don't think it works the same way for MS. It's more like: if it's not in the .net framework they are probably promising it for next version.
grega g
+22  A: 

How hard can it be?
Don't let any problem intimidate you.

dw.mackie
If its an NP-Complete problem then VERY hard! Just don't apply this blindly. There's no need to feel intimidated, but you need to know what problems can be solved in reasonable time and what problems (currently) can't.
Ash
The Halting Problem - how hard can it be? ;)
Philip Morton
haha. seriously, though. how often do folks have to work on an NP-complete problem?
dw.mackie
+22  A: 

Don't optimize unless there's a demonstrable problem.
Most of the time when people try to optimize code before it's been proved necessary, they'll spend a lot of resources, make the code harder to read and maintain, and achieve no noticeable effect. Sometimes they'll even make it worse.

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."
- Donald Knuth

Whatsit
no, Lack of proper planning is the Root of all Evil. With proper planning there is no premature optimization.
WolfmanDragon
+13  A: 

Less code is better than more, as long as it makes more sense than lots of code.

Jas Panesar
+1: Less code is better -- no code is best (i.e., don't reinvent the wheel).
S.Lott
But nearly no code is not always the best answer (ie if there's a function that nearly does what you want, it's not always best to work around the one flaw)
Richard Gadsden
+2  A: 

Plan First, Design Second, Code Third, Test Always.

WolfmanDragon
+27  A: 

Maintainability is important.

Write code as if the person who will end up maintaining it is crazy and knows where you live.

lillq
I have a button that says that in my office
dj_segfault
Unfortunately the maintainers never leave my code in a maintainable state. (The expression should be "crazy and knows where your code lives")
paperhorse
+29  A: 

Don't be afraid to admit "I don't know" and ask.

10 minutes asking someone could save a day pulling your hair out!

nzpcmad
Just so long as you learn from the answer rather than saying 'please fix this' and switching off until it's fixed.
James Ogden
And nasty bugs being produced as well
Kezzer
+16  A: 

Follow the SOLID principles:

Single Responsibility Principle (SRP)

There should never be more than one reason for a class to change.

Open-Closed Principle (OCP)

Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

Liskov Substitution Principle (LSP)

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

Interface Segregation Principle (ISP)

Clients should not be forced to depend upon interfaces that they do not use.

Dependency Inversion Principle (DIP)

A. High level modules should not depend upon low level modules. Both should depend upon abstractions.

B. Abstractions should not depend upon details. Details should depend upon abstractions.

Esko Luontola
<nitpicking>You have I and D switched there</nitpicking>
Jens Roland
I wonder why they didn't call it SRPOCPLSPISPDIP principles...
Torsten Marek
i wish i could vote up comments :)
Darko Z
Listen to Robert Martin (aka Uncle Bob) discuss SOLID principles on Hanselminutes http://www.hanselminutes.com/default.aspx?showID=163 and then Joel Spolsky debunk it on the Stackoverflow podcast http://www.joelonsoftware.com/items/2009/01/31.html
Chris Latta
and I just found Bob Martin's reply to the Stackoverflow podcast here http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel
Chris Latta
+1  A: 

Declare everything. Never nest 15 functions into 1 variable.

WolfmanDragon
not everything .. somethings are better left without declaration (avoid temporary useless variables, they create additional state to maintain), but I agree that nesting 15 functions into one variable is a bad idea, but who does that anyway?
hasen j
All rules have exceptions. Anonymous Inner Classes are by default.
WolfmanDragon
Who does it? The same guys who play Perl golf. or PhP golf.
WolfmanDragon
Rules have no exceptions, by definition! If you think you've found one, you didn't define the rule correctly, or what you defined was a trend not a rule.
Peter Boughton
Even Einsteins Theory of Relativity has exceptions. Like inside of a Singularity. All rules have exceptions. The law of the excluded middle works only in theory, never in practice.
WolfmanDragon
+5  A: 

Build it correct first Make it fast second

gbrandt
Building it correct should mean it runs fast enough for the forseeable future.
Jas Panesar
Also, in many (not all) cases, the simplest code *will* actually run faster, since the compiler will be able to optimize it. (assuming, of course, that the guys who wrote the compiler are smarter than you -- which they usually are)
Jens Roland
+5  A: 

Anything that could affect how the application runs should be treated as code, and that means putting it in version control. Especially build scripts and database schema and data (.sql) files.

dj_segfault
Please, please, convince our database guy to do it! I tried and failed...
Treb
+1  A: 

Instead of being someone who says "I don't know", be someone who says "I want to know". It changes your approach from avoiding/reacting, to proactive discovery and growth.

Jas Panesar
Let me add to that: Don't be someone who uses words like 'proactive' when talking to coders, unless you are hosting a game of bullshit bingo
Jens Roland
Haha, well said.. either you have a general curiosity about all things, or you don't.
Jas Panesar
+1  A: 

Red, Green, Refactor!

TDD or Test Driven Development.

  1. Write your tests for the piece of functionality you want to develop, ensuring that they fail since you have yet to write any code.

  2. Write the least amount of code that you need to to make the test pass.

  3. Refactor as needed for things such as efficiency or clarity.

  4. After refactoring, ensure you tests still pass.

Chris Ballance
I think he's referring to unit testing, but it's not entirely clear
Jens Roland
A: 

Understand the intent of the SOLID principles (or any other set of principles or methodology).

MSN
+10  A: 

Be a Catalyst for Change

You can't force change on people. Instead, show them how the future might be and help them participate in creating it.

via The Pragmatic Programmer

Aaron Wagner
This applies everywhere, not just in programming :)
+9  A: 

It's Both What You Say and the Way You Say It

There's no point in having great ideas if you don't communicate them effectively.

via The Pragmatic Programmer

Aaron Wagner
+20  A: 

Don't Gather Requirements -- Dig for Them

Requirements rarely lie on the surface. They're buried deep beneath layers of assumptions, misconceptions, and politics

via The Pragmatic Programmer

Aaron Wagner
+29  A: 

KISS - Keep it simple, stupid.
Pick the simplest solution that works.
Don't make things (too) complicated before they need to be.
Just because everyone else is using some complicated framework to solve their problem, doesn't mean you have to.

dw.mackie
IT is rarely simple, and if you're stupid please do not become a programmer.
Steven A. Lowe
+4  A: 

Think! About Your Work

Turn off the autopilot and take control. Constantly critique and appraise your work.

via The Pragmatic Programmer

Aaron Wagner
A: 

Some Things Are Better Done than Described

Don't fall into the specification spiral---at some point you need to start coding.

via The Pragmatic Programmer

Aaron Wagner
+12  A: 

I think almost everything that is listed under "The Zen of Python" applies for every "Rules of Programming Mindset" list. Start with 'python -c "import this"':

The Zen of Python, by Tim Peters

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

Special cases aren't special enough to break the rules.

Although practicality beats purity.

Errors should never pass silently.

Unless explicitly silenced.

In the face of ambiguity, refuse the temptation to guess.

There should be one-- and preferably only one --obvious way to do it.

Although that way may not be obvious at first unless you're Dutch.

Now is better than never.

Although never is often better than right now.

If the implementation is hard to explain, it's a bad idea.

If the implementation is easy to explain, it may be a good idea.

Namespaces are one honking great idea -- let's do more of those!

jfsantos
+1 - I read this a while ago and forgot about it, Great share!
Jas Panesar
+9  A: 

Don't Panic When Debugging

Take a deep breath and THINK! about what could be causing the bug.

via The Pragmatic Programmer

Aaron Wagner
+3  A: 
  1. Audience - everything we build is for an audience, it'll be used by end users as well as other coders. Ensure it's usable by both.

  2. Simplicity - if you find yourself implementing something complex and convoluted, you're probably missing a more effective, simple solution.

  3. Quality, not perfection - keep your mind on what's important - delivering quality within a timeframe. if you double the estimate, delivering perfection won't save your ass.

nailitdown
+1. +2 if I could.
DanSingerman
+11  A: 

Habits of the lazy coder

The first time you are asked to do something, do it (right).

The second time you are asked to do it, make a tool that does it automatically.

And the third time, if the tool doesn't cut it, design a domain specific language for generating more tools.

(not to be taken too seriously)

Jens Roland
+9  A: 

You may copy and paste to get it working, but you may not leave it that way.

Duplicated code is an intermediate step, not a final product.

Kyralessa
+2  A: 

It doesn't have to be art, but it has to be on time

An old rule from journalism that I've had to learn the hard way.

Jens Roland
A: 

strive to find solutions that require the least amount of code

Scott Evernden
This is what lead to Golfing... =]
strager
+5  A: 

Take part in open source development

If you are using open source code in your projects, remember to post your bugfixes and improvements back to the community. It's not a development best practice per se, but it's definitely a programmer mindset to strive for.

Jens Roland
A: 

Creating software is like.. building a house.

You can try building it without a blueprint, a plan, experience, an architect or qualified tradespeople.

As a result it will almost always cost more, take longer, and be full of future, ongoing surprises that need your time and money.

Just because someone can build a shed without a blueprint doesn't mean they should.

Jas Panesar
A: 
LarryF
why no tabs in source files?
nailitdown
You didn't hear? Chr(9) is the mark of the beast...(Just kidding... In our case, none of the developers like tabs because it's not an ASCII printable char. and in some text editors can play havoc with formatting, etc.)
LarryF
If you use a decent editor it will be able to handle either line ending (unix or windows) seamlessly, unless you're a notepad developer. Then you should be drawn and quartered.
Lolindrath
IF.. SHOULD.. Not everyone did. And everyone has his or her favorite editor, but, if you are in a bind, and need to look at a source file real quick, on a machine other than your dev box, you may only have notepad...
LarryF
+4  A: 

Think of your work as a craft, not as a duty.

Eric King
A: 

Shouldnt your team already know these things ?

Its a bit of a worry they need to be told what values they already know from past experience. Its a bit like running a courier company and telling your drivers to know they shouldnt have accidents. If they need to be told this because they didnt already know this - i would be seriously worried tha tthey are the right choices for my team.

mP
+1  A: 

This comes from Steve McConnell

"Every new line of code should be single stepped through the debugger"

Chui Tey
+15  A: 

Best Practice: Use your brain
Don't follow any trend/principle/pattern without thinking about it

Ludwig Wensauer
Except this one.
Greg
+7  A: 

Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.

From: Coding Horror

Ludwig Wensauer
A: 

Don't try to make things simpler than they are.

Knowing what you are doing is preferable to unit tests.

Understanding the technology is preferable to test driven development.

Why would you want to waste your life with trial and error methodologies?

+14  A: 

Google before you will ask your colleague and interrupt his coding.

Michal Dymel
+1- I have a similar rule, if I can google an answer or approach in 30 seconds it means you have to learn to search as well as I do.
Jas Panesar
+3  A: 

Take a step back and look at the whole picture

Every once in a while, you should step back from your code and think about what you are doing in abstract terms. If you don't, you will overlook something that will come back to bite you a few days from now.

I love to dive deep into the code, but from time to time I need to return to the surface and get some air...

Treb
+1  A: 

It is never as easy as you think

This is in response to another answer, but does not contradict it! Both are valuable principles that should be followed.

Treb
+2  A: 

Always build a prototype. Nine times out of ten it will be worth the day/week/month that it takes. Corollary: the length of time spent on a prototype should be proportional to the length/size of the main project.

endian
A: 

"I just can't see how it can fail" is just "It can fail, I just can't see how" with the words rearranged. TEST EVERYTHING!

Peter Morris
+3  A: 

If you're stuck, talk about it (even if you only talk to a rubber duck)

Steve Bosman
Jas Panesar
+5  A: 

Understand the tools you use

Don't use a pattern until you've understood why you're using it; don't use a tool without knowing why; don't rely on your framework or language designer always being right for your situation, but also don't assume they're wrong until proven to be!

Richard Gadsden
A: 
  1. Understand/walkthrough application code that is good, bad and ugly. You will be better placed at understanding what works and what doesn't.

  2. Talk to people (both IT AND Business) and don't be afraid to ask questions. This works for you in two ways:-

    a) You become more approachable as you seem more human than just that nerd who doesn't speak

    b) Your approach to coding/designing an application is based on real answers - not just on documentation/emails, that could be obsolete.

Ferdeen
+2  A: 

YAGNI

You Ain't Gonna Need It

Be critical of what you do aka Think!

pirho
+1  A: 

For databases...

Normalise as far as you can. Then normalise again.

Having a good database (in both structure and data) is critical for making programming less stressful.

Peter Boughton
+6  A: 

Frequently conduct code reviews

Code review and consequently refactoring is an ongoing task. Here is a few goodies about code review in my opinion: 1. It improves code quality. 2. It helps refactor reusable codes into reusable libraries. 3. It helps you learn from your felow developers. 4. It helps you learn from your mistakes and refresh your memory about a genious code you have written before.

+1  A: 

Your code should be so simple that anyone who looks at it can understand what it does without reading any documentation.

But don't forget to document everything anyway.

If your API is not braindead-simple to use, there is something wrong with the API. Refactor it until it takes no effort to use correctly.

Before you write any code, research first to find out if the framework already has built-in support or extensible interfaces for what you're trying to do.

davogones
Very simple, but such a great piece of advice.
Jens Roland
+1  A: 

Catch bugs early:

  • Use statically typed language so that compiler and static analysis can help you.
  • Unit Test (first or last)
  • Code review
  • Continuous integration
  • Finally, thing that matters the most - Continuous learning.
A: 

Always write documentation for your code! In half a year you won't remember about how it works. So don't write any code without documentation!

Alexander
+2  A: 

Quantity Always Trumps Quality

Coding more (even if it isn't great) will give you a better feel of what good code should look like.

Lolindrath
A: 

It's never easy the first time. It will be a snap to do every time after. It's like trying to find a short cut the first time you're driving somewhere. Before GPS.

Jas Panesar
A: 

Code without unit tests is, by definition, broken.

Self-explanatory.

Ali A
+2  A: 

Never tell business everything!

Refactoring is part of your job and not something that is up for discussion. If you allways add a little "estimated" time to be able to do necessary refactoring there won't be any complaints about it!

mhenrixon
Also, don't tell sales anything, because they'll sell it right away.
Torsten Marek
A: 

People that know just a little about something (process/software) are the most dangerous people in the world.

Jas Panesar
A: 

Write self-explanatory code (and then still document it), which includes

  • meaningful names avoiding abbreviations and especially consonant clusters
  • functions that are just introduced to make real code read like pseudo-code
  • keeping the level of abstraction constant inside one code unit etc. etc.
Johannes Stiehler