2

On page 242 of Code Complete 2, Steve McConnell touts The Principle of Proximity.
Put simply, Mr. McConnell advises programmers to keep related actions together.

In my case, the applicable emphasis is:

  • It's important to initialize and set variables (and objects) close to where they are being used.

It's usually easy to abide by 'The Principle of Proximity' when you're working within a single code block or method body; but what if you're working with legacy code and an object at the top of the stack is set or mutated deep within the stack? To make things more complicated, what if that object is set, mutated, or referenced multiple times within the stack?

So here's my question:

What is the Most Expedient Way to Make Legacy Code Conform to 'The Principle of Proximity'?

Incidentally, I'm working with Visual Studio 2010 and Resharper 5.
Are there any IDE tricks that could help me out?

3 Answers 3

2

You ask a very general question. There are lots of techniques. You say (correctly) it's easy "when you're working within a single code block or method body" - and that's the direction you want to steer your code. To start with, highlight a variable (I'm assuming VS will highlight all occurrences, and hoping it will show you not just the variable in code but also markers alongside so you have a good sense of where all occurrences are). Are the occurrences clustered? Is the code really using the value assigned at the end of one cluster, in the next cluster - or is it reassigning the value, just re-using a variable out of sloppiness? If it's the latter, use a new variable in each cluster, declaring and initializing it only where it is needed.

Look for names like "temp" and "tmpXxx" - they're good candidates for this kind of treatment, as some developers seem to think there is a savings to be had in re-purposing variables in this fashion. They're wrong.

Extract Method is your friend. If you can't extract a method (maybe because multiple locals get assigned), fall back on Convert Local Variable to Field. It may turn out to be an interim conversion, executed to facilitate Extract Method and then undone afterwards. Or it may turn out that the variable really should be a field and your class is cleaner that way.

Sprout Class is also good, for large & small sections of code alike. Anywhere (borrowing from Feathers' terminology) you can introduce a seam - between methods, between classes, etc. - is a good place to help improve locality.

5

The most efficient way would probably be to go buy the book Working Effectively with Legacy Code and read the relevant chapter. It's one of the most useful programming books I have read. I can't recommend it enough.

2
  • OK - But could you possibly extract some useful principles from that book to help me out here?
    – Jim G.
    Apr 21, 2011 at 16:06
  • 1
    My ability to suggest the layout of the solution space is proportional to my understanding of the problem space. In other words, you've asked a very general question and I have responded with a very general answer (which nevertheless readily unpacks into many specific and detailed answers). Apr 21, 2011 at 17:15
1

It's worth checking out UncleBob's recent video blog about large functions being where classes go to hide linky where he talks about a large function having chunks of functionality and variable scope communicating between them, and how that's pretty much the definition of a class. I think that there is more about it in the functions episode on his new clean coders site

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.