views:

785

answers:

10

Ever since I started using .NET, I've just been creating Helper classes or Partial classes to keep code located and contained in their own little containers, etc.

What I'm looking to know is the best practices for making ones code as clean and polished as it possibly could be.

Obviously clean code is subjective, but I'm talking about when to use things (not how to use them) such as polymorphism, inheritance, interfaces, classes and how to design classes more appropriately (to make them more useful, not just say 'DatabaseHelper', as some considered this bad practice in the code smells wiki).

Are there any resources out there that could possibly help with this kind of decision making?

Bare in mind that I haven't even started a CS or software engineering course, and that a teaching resource is fairly limited in real-life.

+2  A: 

Check out Martin Fowler's comments and book on Refactoring

Shane MacLaughlin
+4  A: 

Here is a review on slash dot of a book called Clean Code.

The book is apparently a little dry but very good.

Omar Kooheji
Hey - that's my review! The challenge with the book is that it is focused at times on Java. But, in general, Uncle Bob knows what he is talking about, and has been doing this for a long time.
Cory Foy
@Cory Foy Good review I'm seriously considdering buying the book on the basis of it. However I'm trying to get my company to buy it for me first :)
Omar Kooheji
+17  A: 
Andre Bossard
I love that book!
Bob King
Will do, thanks!
RodgerB
Possible typo: "there", don't you mean "their"?
Spoike
+6  A: 

Jeff Atwood made a nice blog post on refactoring and code smells, you might want to check that out.

Refactoring code in .NET takes some time to grok. You need to know some object-oriented design principles (or design techniques) in order to refactor effectively and mercilessly.

In short, you refactor code in order to remove code smells and make changes easier to do. Also, don't overdo it.

Spoike
Interesting blog post, thanks.
RodgerB
+2  A: 
  • Re-factor you code when it is causing problems. Any problems will do: performance, scallabillity, integration, maintainance - anything which makes you spend more time on it when you should. It it is not broken do not fix it even if you do not believe it is clean or is up to the modern standards.
  • Don't spend too much time making the code perfect. You will never achieve perfection but you could spend lots of time trying to do so. Remember the law of diminishing returns.
  • Inside a project only re-factor the code when you are actually working on the functionality which depends on it. I.e. if you have a user story for the iteration calls for a "change the upload mechanism" or "fixing the bug in the file upload" you could re-factor the file uploading code. However if your user story is about "facelifting the file upload UI design" do not go into the business logic.
Ilya Kochetov
+1  A: 

I'd recommend Domain Driven Design. I think both YAGNI and AlwaysRefactor principles are two simplistic. The age old question on the issue is do i refactor "if(someArgument == someValue)" into a function or leave it inline?

There is no yes or no answer. DDD advises to refactor it if the test represents a buisiness rule. The refactoring is not (only) about reuse but about making the intentions clear.

Goran
+1  A: 

Working Effectively with Legacy Code is one of the best books I have seen on this subject.

Don't be put off the title of the book - Rather than treating Refactoring as a formal concept (which has its place), this book has lots and lots of simple "why didn't I think of that" tips. Things like "go through a class and remove any methods not directly realted to that class and put them in a different one".

e.g. You have a grid and some code to persist the layout of that grid to file. You can probably safely move the layout persisting code out to a different class.

Gus Paul
A: 

I just got a copy of Code Complete, and found that there was a section on this.

Although I will still be reading the accepted answer's book, what Code Complete has taught me has dramatically improved the way I think about designing classes.

Before today, I didn't know what an ADT was (abstract data type), and now I know how to develop classes adhering to the encapsulation.

RodgerB
A: 

There's a web page dedicated to refactoring at http://www.refactoring.com/. It features many references to further resources on the topic of refactoring code as well as a mailing list to discuss refactoring-related issues.

Last but not least, there's a big (and still growing) catalog of refactorings available which extends well beyond what's written in the (very much recommended) Refactoring book by Martin Fowler.

Frerich Raabe
+1  A: 

My rule of thumb is to leave the code in no worse shape than you found it.

The idea is to work towards the better, without trying to achieve the perfect result, or go all the way.

Individual refactorings sometimes have a questionable benefit, and - as an extreme example - it might indeed be argued if m_Pi is a better name than m_PI. However, most often one choice is more consistent, and less surprising even if not obviously "better".

One situation where I regulary find myself refactoring automatically is before implementing a featureon a piece of code.

There are often a few TODO's waiting to be fed, some inconsistencies or sometimes custom functionality that has lately acquired better library support. Doing these changes before I implement the actual feature request gives me some understanding of the code, and I verify the "before" functionality.

Another point is after fixing bugs. After, so the before-repro isn't affected, and the bug fix and the refactoring are two separate commits.

peterchen