For Programmers: Free Programming Magazines  


Home > Archive > Extreme Programming > June 2004 > When to refactor, when to "Just Do It"?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author When to refactor, when to "Just Do It"?
Robert Atkins

2004-05-23, 3:31 am

So you're sat down in front of an existing, working, running system on your
first day in a new job. You know nothing about the codebase and have a lot to
learn about the problem domain.

You are given the task of adding a new feature. As always, it needs
to be done by a certain deadline. So you go through the system to
see how it currently works and you find obvious brainfarts like abstract
classes containing all abstract methods, you find large swaths of code
duplicated between modules, you find some extremely tightly coupled bits
of code which are very difficult to decipher.

So you start trying to retrofit tests, but to do that you have to change
things -- making things interfaces so you can mock things out, changing
constructors so you can pass in the mocks, etc. Then you start to fix
some glaring style flaws and before long you've made some fairly
fundamental changes to the structure of the code but you do at least
have tests.

Then your manager sits you down and says (paraphrased), "This code is
quite important to the system and used to work fine. Stop stuffing
around and deliver some functionality!"

Yes, he's right: it did work as it was. Now that I've pulled it apart in
order to understand it, I could probably hack the new feature in to the
old code. But as soon as it was demonstrated to work I'd be tasked with
something else and not get the time to do the refactoring.

I'm thinking that the course of action to take is to back out the big
structural changes and just keep a few minor ones which make my
new feature easier. Write as much of my new stuff with tests as I can,
then sneak the bigger changes in piece-by-piece when those modules get
touched again.

What advice can people offer?

Cheers, Robert.
Phlip

2004-05-23, 7:34 am

Robert Atkins wrote:

> So you're sat down in front of an existing, working, running system on

your
> first day in a new job. You know nothing about the codebase and have a lot

to
> learn about the problem domain.


Grab a pair (or not), have a refactor party, and throw the results away.

A programmer experienced with that codebase knows what not to change. You
don't have that problem. You will rapidly expose many coupling issues.

> You are given the task of adding a new feature. As always, it needs
> to be done by a certain deadline. So you go through the system to
> see how it currently works and you find obvious brainfarts like abstract
> classes containing all abstract methods, you find large swaths of code
> duplicated between modules, you find some extremely tightly coupled bits
> of code which are very difficult to decipher.
>
> So you start trying to retrofit tests, but to do that you have to change
> things -- making things interfaces so you can mock things out, changing
> constructors so you can pass in the mocks, etc. Then you start to fix
> some glaring style flaws and before long you've made some fairly
> fundamental changes to the structure of the code but you do at least
> have tests.
>
> Then your manager sits you down and says (paraphrased), "This code is
> quite important to the system and used to work fine. Stop stuffing
> around and deliver some functionality!"


This is where the Industrial XP meta-practice of "Prequalification" becomes
useful. IXPers decline to work with bosses who cannot repeat XP jargon back
to them, and who will not empower the IXPer to enforce the XP practices in
real-time.

But that practice only facilitates the work that's now needed...

> Yes, he's right: it did work as it was. Now that I've pulled it apart in
> order to understand it, I could probably hack the new feature in to the
> old code. But as soon as it was demonstrated to work I'd be tasked with
> something else and not get the time to do the refactoring.
>
> I'm thinking that the course of action to take is to back out the big
> structural changes and just keep a few minor ones which make my
> new feature easier. Write as much of my new stuff with tests as I can,
> then sneak the bigger changes in piece-by-piece when those modules get
> touched again.
>
> What advice can people offer?


Switch to a monospaced font here (maybe copy this post to Notepad):

| b
| ****
| * *
^ | * *
| | * *c
| |****a *
e | *
f | *
f | *
o | * d
r | ** * *
t | *** ** ***
|
+-----------------------------
feature count-->

We refactor for a reason, not to party, and that reason is overwhelming to
make new test cases easier. You can't discuss one without the other.

Before the point [a], effort (and therefor risk) are very high. But most
projects operate operate up here, so they "bond" with it as part of their
comfort zone.

[a] is where you start to crowbar testability in. Mike Feather's upcoming
book, /Working Effectively with Legacy Code/ refers to potential decoupling
points as "seams". Squeezing in between two modules might let you get a test
into one of them.

[b] is where you start to break even. For each new feature, you know _how_
to find its seam and squeeze the test in. The extra risk (including
political risk) might level off. And you know the code's structure well
enough to refactor opportunistically, to leverage your recent understanding
and attention to the code where you just added a feature.

[c] is where the existing test rigs, fixtures, and decoupling finally start
to make new features almost as rapid as code-n-fix was. But the slope thru
[c] is very negative, because you are now adding test fixtures pro-actively,
enabling whole new categories of test cases, and making more code easier to
refactor.

[d] is where you finally display a velocity much faster than anyone in this
shop has ever experienced.

Incredibly, the [d] point has very high political risk! If your boss tracks
you per-feature, then the segment from [a] to [c] can generate naive
complaints. From [c] to [d] you appear to "fit in", even though you now do
things completely differently.

But if your boss simply measures your velocity from [a] to [d], it's very
low. The solution is either to sell XP (and to neatly pack your parachute
and wear it at all times), or to somehow amortize the stretch from [a] to
[d]. You can do that by lying about the per-feature times from [a] to [d].
This requires insinuating test fixtures and refactors into the system only
during off-times, and pushing the [d] point further out into the future.

Stealth XP is playing to not-lose, not playing to win. Get real.

--
Phlip
http://industrialxp.org/community/b...tUserInterfaces


Robert C. Martin

2004-05-23, 10:30 am

On 23 May 2004 06:22:07 GMT, Robert Atkins
<ratkins_usenet@yahoo.com.au> wrote:

>So you're sat down in front of an existing, working, running system on your
>first day in a new job. You know nothing about the codebase and have a lot to
>learn about the problem domain.
>
>You are given the task of adding a new feature. As always, it needs
>to be done by a certain deadline. So you go through the system to
>see how it currently works and you find obvious brainfarts like abstract
>classes containing all abstract methods, you find large swaths of code
>duplicated between modules, you find some extremely tightly coupled bits
>of code which are very difficult to decipher.
>
>So you start trying to retrofit tests, but to do that you have to change
>things -- making things interfaces so you can mock things out, changing
>constructors so you can pass in the mocks, etc. Then you start to fix
>some glaring style flaws and before long you've made some fairly
>fundamental changes to the structure of the code but you do at least
>have tests.


This is risky stuff. You don't know if your restructurings have
actually broken things or not. Nobody wants to see massive code
changes in untested code. The fact that you have added tests now is
good, but there's no guarantee that the tests actually check for the
right things.

So you want to do this very judiciously. Minimize your refactoring in
the legacy code to the narrow area that you must add the new feature
to. Don't go far afield and do massive refactorings throughout the
system.

>Then your manager sits you down and says (paraphrased), "This code is
>quite important to the system and used to work fine. Stop stuffing
>around and deliver some functionality!"


What prompted your manager to say this to you? How did he have that
kind of visibility into your own professional practices? In some
sense you should be incensed. A manager has no business defining
professionalism to you.

>Yes, he's right: it did work as it was. Now that I've pulled it apart in
>order to understand it, I could probably hack the new feature in to the
>old code. But as soon as it was demonstrated to work I'd be tasked with
>something else and not get the time to do the refactoring.


Don't demonstrate it until you are happy with the structure. Explain,
if you have to, that the code is a mess, and is getting messier every
day; that after a few more months of this everything will take twice
as long to do as it takes now. That some judicious cleaning of the
code is the only thing that might forestall this eventuality.

>I'm thinking that the course of action to take is to back out the big
>structural changes and just keep a few minor ones which make my
>new feature easier. Write as much of my new stuff with tests as I can,
>then sneak the bigger changes in piece-by-piece when those modules get
>touched again.


This is a good approach. Minimize the risk of breakage. Also, show
your team members what you have done. If they agree that the tests
are really beneficial, then you can check in a wider set of them.

Involve the team! You'll never succeed at this if you proceed
unilaterally.


-----
Robert C. Martin (Uncle Bob)
Object Mentor Inc.
unclebob @ objectmentor . com
800-338-6716

"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo
Jeff Grigg

2004-05-23, 11:36 am

--- Robert Atkins <ratkins_usenet@yahoo.com.au> wrote...
> So you're sat down in front of an existing, working, running system
> on your first day in a new job. You know nothing about the codebase
> and have a lot to learn about the problem domain.


The first thing you must do on a new job is to establish your
credibility: You have to demonstrate that you can do work, get things
done, and not screw up the entire system.

The very first change you should make should be the smallest and
simplest possible change that they have asked for that will have any
noticeable effect. Correct the spelling of a screen label, if there's
a bug report for that.

You must work your way up to bigger and more extensive changes one
step at a time. You must build trust. You must earn trust.

> You are given the task of adding a new feature. As always, it needs
> to be done by a certain deadline.


Yea, yea, yea. It's always like that. We must always run like mad
just to keep up, and so on. Be calm. Remember: "Sometimes you have
to slow down to speed up."

Tiger Woods was unhappy with his game last year. So he talked to his
coaches who advised him to change his grip. This made his game worse
-- for a while. But the new grip enabled him to improve his game even
more than was possible before.

"Sometimes you have to slow down to speed up."


> So you go through the system to see how it currently works and you
> find obvious brainfarts like abstract classes containing all abstract
> methods,


[ I have no particular problem with pure abstract classes: In C++
this is the most common idiom for an interface. ]

> you find large swaths of code duplicated between modules, you find
> some extremely tightly coupled bits of code which are very difficult
> to decipher.


[ ...which means that it will be difficult and risky to fix, too. ]


> So you start trying to retrofit tests, but to do that you have to
> change things -- making things interfaces so you can mock things
> out, changing constructors so you can pass in the mocks, etc. Then
> you start to fix some glaring style flaws and before long you've
> made some fairly fundamental changes to the structure of the code
> but you do at least have tests.


Wait. Slow down. You need to build credibility before you pull the
rug out from under them.

Start small and get bigger over time:
1. Rework comments. Delete useless ones, add new ones where the code
is weak, and reword misleading comments when you find them.
2. Start improving variable and method names. (a) local variables,
(b) parameters, (c) private member variables, (d) methods, and on up
all the way to renaming classes.
3. [overlaps with 2] Refactoring: Extract method is a good place to
start.

Somewhere in #2 or #3 above, if they're paying attention, you'll start
getting feedback from "the powers that be" on how they feel about your
changes. I was told by one manager, "The most important objective of
maintenance is to minimize the output of 'diff' [between versions]."
On another project, after renaming a very misleading method name in a
class I was making significant changes to, the project manager told
me, "The most important thing in maintenance is to ensure that the
person who originally wrote the code can most easily understand it.
In a crisis, we may have to call them in to fix things." [...instead
of calling in the person who's been making major enhancements to it
over the last year, for example?!?]

This is where you'll have the opportunity to "change your organization
or change your organization." ;->

> [...]
> I'm thinking that the course of action to take is to back out the big
> structural changes and just keep a few minor ones which make my
> new feature easier. Write as much of my new stuff with tests as I can,
> then sneak the bigger changes in piece-by-piece when those modules get
> touched again.
>
> What advice can people offer?


When working on legacy code, it's easy to spend all your time
refactoring, and no time delivering value to the customer. Worse,
refactoring without tests is risky: You *WILL* cause regression.


So I use these simple rules of thumb:

1. Do not refactor code unless you're already changing it to satisfy
some user request (to fix bugs or add functionality).

2. Never spend more than half your time refactoring/improving legacy
code. If it's bad code at the start of the w, it will still be bad
code at the end of the w. The best you can hope for is to improve
the situation a little.

In two or three months it will start to become clear (if anyone is
paying any attention ;-) that you're doing something good. That won't
give you a license to do everything you want, but you can gain the
authority to make bigger and more important improvements over time.
John Roth

2004-05-23, 2:39 pm

"Robert Atkins" <ratkins_usenet@yahoo.com.au> wrote in message
news:40b0430f$0$2303$61ce578d@news.syd.swiftdsl.com.au...
> So you're sat down in front of an existing, working, running system on

your
> first day in a new job. You know nothing about the codebase and have a lot

to
> learn about the problem domain.
>
> You are given the task of adding a new feature. As always, it needs
> to be done by a certain deadline. So you go through the system to
> see how it currently works and you find obvious brainfarts like abstract
> classes containing all abstract methods, you find large swaths of code
> duplicated between modules, you find some extremely tightly coupled bits
> of code which are very difficult to decipher.
>
> So you start trying to retrofit tests, but to do that you have to change
> things -- making things interfaces so you can mock things out, changing
> constructors so you can pass in the mocks, etc. Then you start to fix
> some glaring style flaws and before long you've made some fairly
> fundamental changes to the structure of the code but you do at least
> have tests.
>
> Then your manager sits you down and says (paraphrased), "This code is
> quite important to the system and used to work fine. Stop stuffing
> around and deliver some functionality!"
>
> Yes, he's right: it did work as it was. Now that I've pulled it apart in
> order to understand it, I could probably hack the new feature in to the
> old code. But as soon as it was demonstrated to work I'd be tasked with
> something else and not get the time to do the refactoring.
>
> I'm thinking that the course of action to take is to back out the big
> structural changes and just keep a few minor ones which make my
> new feature easier. Write as much of my new stuff with tests as I can,
> then sneak the bigger changes in piece-by-piece when those modules get
> touched again.
>
> What advice can people offer?


The first piece is a language issue: refactoring is the process of
making small, precisely defined changes to improve structure.
Restructuring is the process of making wholesale changes. It
sounds more like you were doing restructuring. There's nothing
wrong with that, but it's not refactoring.

You're being paid to get the job done. One thing I learned as a contractor
was that when I was done, the customer's people would have to deal
with what I had left behind. If they are used to this kind of mess, leave
them to it. A nice clean structure is very worthwhile to a team which is
capable of appreciating it and using it as springboard to delivering new
function quickly. It's completely worthless to developers that can't tell
the difference between good design and a big ball of mud. It's equally
worthless to developers that are used to doing something one way, and
are not familiar with some other way of doing it.

That may sound cynical, and in a sense it is. But if it's not your job
to clean up the mess, then the target is simply to clean up what is
really getting in your way and not make the rest worse.

So I'd start by finding out what kind of acceptance tests they have,
and writing tests for the new functionality. Then I'd figure out what
needed to be changed and make those changes, together with whatever
other changes would make the total job easier, and at the same time
wouldn't compromise whatever structure happened to be there.

John Roth

>
> Cheers, Robert.



Jason Nocks

2004-05-24, 7:39 am

Robert Atkins wrote:

> So you're sat down in front of an existing, working, running system on your
> first day in a new job. You know nothing about the codebase and have a lot to
> learn about the problem domain.
>
> You are given the task of adding a new feature. As always, it needs
> to be done by a certain deadline. So you go through the system to
> see how it currently works and you find obvious brainfarts like abstract
> classes containing all abstract methods, you find large swaths of code
> duplicated between modules, you find some extremely tightly coupled bits
> of code which are very difficult to decipher.
>
> So you start trying to retrofit tests, but to do that you have to change
> things -- making things interfaces so you can mock things out, changing
> constructors so you can pass in the mocks, etc. Then you start to fix
> some glaring style flaws and before long you've made some fairly
> fundamental changes to the structure of the code but you do at least
> have tests.


Breaking code simply to be able to start adding tests sounds like you've
ventured a bit out of the well defined TDD area. Perhaps you aren't
really Refactoring any more.

From refactoring.com:

"Refactoring is a disciplined technique for restructuring an existing
body of code, altering its internal structure without changing its
external behavior. Its heart is a series of small behavior preserving
transformations."

If you've broken existing functionality, you've ventured further towards
rewriting. If, however, you are getting bogged down, it sounds like you
are doing too much restructuring. Sounds like maybe a bit of both.

Rewriting is not necessarily a bad thing, but is not generally what is
recommended as part of TDD. For example, if the existing code was very
buggy, then rewriting might be the simpler, quicker, and least costly
option. This doesn't appear to be an easy out for you here, though.

Think very very small steps. Particularly when you have no automated
tests. Think really hard about how to make sure you aren't changing the
behavior of the code. And, only restructure what is immediately in your
way. Think about how to write tests for the existing functionality that
you need to restructure. Tests you have to write for existing
functionality may start out larger than you'd like. You'll want to make
sure you refactor these tests along the way as well. Refactoring messy
existing code that has no automated tests is a bit expensive at first.
Over time, it will get easier, though.

> Then your manager sits you down and says (paraphrased), "This code is
> quite important to the system and used to work fine. Stop stuffing
> around and deliver some functionality!"
>
> Yes, he's right: it did work as it was. Now that I've pulled it apart in
> order to understand it, I could probably hack the new feature in to the
> old code. But as soon as it was demonstrated to work I'd be tasked with
> something else and not get the time to do the refactoring.


With TDD, you want to put a broken test in for your code, then implement
your code (quickly at first), then clean it up. There should not be a
delay between getting your test to pass and cleaning up the code you
just added.

> I'm thinking that the course of action to take is to back out the big
> structural changes and just keep a few minor ones which make my


Big structural changes are at best *unsafe* refactorings. Safe
refactorings (the recommended approach) are a series of very small
restructurings. If you don't have an automated refactoring browser, and
you don't have automated tests, then you want to go in really painfully
small steps at first. Particularly without a pair, and in unfamiliar
territory.

> new feature easier. Write as much of my new stuff with tests as I can,
> then sneak the bigger changes in piece-by-piece when those modules get
> touched again.


Yes, sounds like you are now headed in the right direction. Possibly a
painful learning experience. I hope that you find things easier going
soon. Are there any examples that you could or would like to discuss?

I would recommend *trying* to write tests first for *all* of your new
code. But, start with only refactoring the worst offenses that make it
really difficult to write your tests and/or code. Let the pain involved
with writing new tests and new code be your indicator of design smells.
Tackle the most offensive ones first, but again try to work in really
small steps. Leave comments where you'd like to refactor, but can't
because of time and/or fear of breaking existing functionality.

Sooner or later you'll need to have discussions with the rest of the
team about adding tests, simplifying the design (iteratively would be
recommended above wholesale), and refactoring. Perhaps you could start
pairing with one of the team-members who is more familiar with the code
and more open to tiny refactorings.

> What advice can people offer?


See above.

Sounds like a political "ball of mud" to a certain extent. Worst case
scenario, just keep writing tests and fixing code that's immediately in
your way. Over time, people will start to notice that code you've worked
on is easier to change, is easier to read, and has less defects. They
might then come up to you and start asking what you've been doing
differently. Or, they might notice this bed of automated tests growing
and growing.

> Cheers, Robert.


Cheers,
Jason Nocks
SourceXtreme, Inc.
http://www.sourcextreme.com/
Robert Atkins

2004-05-24, 8:31 am

In article <lg%rc.19848$9G5.3908@newssvr31.news.prodigy.com>, Phlip wrote:
> Robert Atkins wrote:
> your
> to
>
> Grab a pair (or not), have a refactor party, and throw the results away.


Interesting. This is sort-of what I have done. I have been trying to do
the above adding of tests and refactoring with a pair, the other new
guy. This is good because it helps me stay focused, but bad because he
is as unfamiliar with the codebase as I.

> A programmer experienced with that codebase knows what not to change. You
> don't have that problem. You will rapidly expose many coupling issues.


Indeed.

> This is where the Industrial XP meta-practice of "Prequalification" becomes
> useful. IXPers decline to work with bosses who cannot repeat XP jargon back
> to them, and who will not empower the IXPer to enforce the XP practices in
> real-time.


This is practical where there are infinite jobs. There almost are, but
the market in Sydney wasn't quite there when I accepted this one a month
ago.

> [d] is where you finally display a velocity much faster than anyone in this
> shop has ever experienced.


I don't want to sound like I'm selling these guys short. I have at least
one more senior "XP ally" whose modules are much better tested, but he
isn't the one who originally wrote the code I'm adding to now and he has
been quite busy recently with implementation issues.

> Stealth XP is playing to not-lose, not playing to win. Get real.


Understood. I'm not in complete stealth mode, but as a post downthread
says, I'm still at the stage when I need to earn respect so I need some
runs on the board before I can push hard for more XP.

Cheers, Robert.
Robert Atkins

2004-05-24, 8:31 am

In article <7b91b0t6hb2ajn3t2tg1hji553hcqball6@4ax.com>, Robert C Martin wrote:
> On 23 May 2004 06:22:07 GMT, Robert Atkins
><ratkins_usenet@yahoo.com.au> wrote:
>
> This is risky stuff. You don't know if your restructurings have
> actually broken things or not. Nobody wants to see massive code
> changes in untested code. The fact that you have added tests now is
> good, but there's no guarantee that the tests actually check for the
> right things.


This is what I'm worried about. Myself and my pair are enthusiastic, but
inexpert users of JUnit too. We haven't had the opportunity yet to pair
with a more senior member of the team who is much more experienced.

>
> What prompted your manager to say this to you? How did he have that
> kind of visibility into your own professional practices? In some


It's a small shop and we're all in one room so maybe he overheard my
pair and I having difficulty with some multithreading stuff, or (more
likely) the original code's author (who was listening to us having
difficulties) had a word in his ear.

>
> Don't demonstrate it until you are happy with the structure. Explain,


Yes, but I have to "prove" my changes -- that they don't break anything
that used to work. So in some sense I have to "demonstrate" the code
to the others in the team who may pass on their nervousness to
management.

Cheers, Robert.
Robert Atkins

2004-05-24, 8:31 am

In article <c794c0fd.0405230611.30d54654@posting.google.com>, Jeff Grigg wrote:
> --- Robert Atkins <ratkins_usenet@yahoo.com.au> wrote...
>
> The first thing you must do on a new job is to establish your
> credibility: You have to demonstrate that you can do work, get things
> done, and not screw up the entire system.


Yes, I agree.

> The very first change you should make should be the smallest and
> simplest possible change that they have asked for that will have any
> noticeable effect. Correct the spelling of a screen label, if there's
> a bug report for that.


Not really my choice. I was given a big chunk of work straight off.

>
> [ I have no particular problem with pure abstract classes: In C++
> this is the most common idiom for an interface. ]


Yeah, Java *has* interfaces so you should probably use an interface
where you mean to write an interface. In any case, this was just an
example of one of the obvious bits of poor style I came across.

> Wait. Slow down. You need to build credibility before you pull the
> rug out from under them.


Yes, agreed.

> Start small and get bigger over time:
> 1. Rework comments. Delete useless ones, add new ones where the code
> is weak, and reword misleading comments when you find them.


Comments? Hrmph. Good luck *finding* comments. IntelliJ's "Goto...
Declaration" is a poor substitute for Javadoc but when it's the only one
you've got...

> 2. Start improving variable and method names. (a) local variables,
> (b) parameters, (c) private member variables, (d) methods, and on up
> all the way to renaming classes.


We've done all of these. Another biggie is that we're working on our own
branch in CVS -- so when our branch of "little changes" gets merged back
in, even if we did make them one parameter name at a time, it's still
going to look like a bucketload of stuff at once.

> So I use these simple rules of thumb:
>
> 1. Do not refactor code unless you're already changing it to satisfy
> some user request (to fix bugs or add functionality).


That's what I've been doing. I've just scared myself a little with the
*breadth* of changes I've needed to make in the course of adding a
feature.

> 2. Never spend more than half your time refactoring/improving legacy
> code. If it's bad code at the start of the w, it will still be bad


This is a good one. I've also stuck a post-it to the front of my monitor
bearing the legend, "How will this get me closer to my goal?".

> In two or three months it will start to become clear (if anyone is
> paying any attention ;-) that you're doing something good. That won't


Hope so. When I've mentioned what I'm doing to some of the other
developers none of them have said they think what I'm doing is a *bad*
thing, but competitive pressure intervenes...

Cheers, Robert.
Phlip

2004-05-24, 9:39 am

Robert Atkins wrote:

> Interesting. This is sort-of what I have done. I have been trying to do
> the above adding of tests and refactoring with a pair, the other new
> guy. This is good because it helps me stay focused, but bad because he
> is as unfamiliar with the codebase as I.


Did you declare up front you'd throw the changes away? did you "deliver"?

Code abuse, while pairing with someone who knows what "not" to change, is a
great way to learn the code's topology by watching them squirm.

becomes[color=darkred]
back[color=darkred]
in[color=darkred]
>
> This is practical where there are infinite jobs. There almost are, but
> the market in Sydney wasn't quite there when I accepted this one a month
> ago.


Agreed. In this market, going with a doomed project, and keeping how doomed
it is a secret, is perfectly justified to get a paycheck. They can afford my
loyalty, but not my honesty. ;-)

> It's a small shop and we're all in one room so maybe he overheard my
> pair and I having difficulty with some multithreading stuff, or (more
> likely) the original code's author (who was listening to us having
> difficulties) had a word in his ear.


Threads?? AAAARRRGGGGHH!!

> Yes, but I have to "prove" my changes -- that they don't break anything
> that used to work. So in some sense I have to "demonstrate" the code
> to the others in the team who may pass on their nervousness to
> management.


Don't link the success of "refactoring" to your success with this
programmer-hostile code. Just learn about this code, and what minor
improvements it can accept. When you find duplication but can't fold it,
just refactor in tiny tweaks to make the similar code as parallel as
possible.

Then, when someone says, "okay, prove refactoring works", you find all your
TODO statements, merge all the code that you got ready to merge, the line
count drops, and you can then demonstrate the new flexibilities you exposed.

--
Phlip
http://industrialxp.org/community/b...tUserInterfaces


Michael Feathers

2004-06-03, 7:08 pm


"Robert Atkins" <ratkins_usenet@yahoo.com.au> wrote in message
news:40b1dbc2$0$2303$61ce578d@news.syd.swiftdsl.com.au...
> In article <7b91b0t6hb2ajn3t2tg1hji553hcqball6@4ax.com>, Robert C Martin

wrote:
>
> This is what I'm worried about. Myself and my pair are enthusiastic, but
> inexpert users of JUnit too. We haven't had the opportunity yet to pair
> with a more senior member of the team who is much more experienced.


Hi. I've just finished up my book on this topic (Working Effectively with
Legacy Code). In it, I have a whole slew of refactorings that you can do
without tests, to enable testing; more than I can get into here, but here
are some guidelines:

- You are in Java, so use a refactoring tool.
- Test your refactoring tool to verify that it does extract method
correctly.
- Lean on 'extract method' (EM) in the tool to break dependencies well
enough to get tests in place. If you know EM is safe, the only thing that
can go wrong is the editing that you do before and after EMs. Avoid doing
anything else, don't change the order of statements, move code, etc.
- Have your pair partner challenge you to do one thing at a time when you
are working, do the same for him/her.
- Take small steps

Michael Feathers
www.objectmentor.com



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com