Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Refactoring guidelines

 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello ranchers,

I would really appreciate your input on this one.

I've been assigned to maintain a somewhat large project. As fantastic as that is, my predecessors left me practically no comments and big (huge?) files and methods to maintain. Files span 4k+ lines, with methods ranging up to few hundred lines. After about a month of work and 723 cups of coffee, files are mostly under 3k and methods are almost readable.

Now I've started to wonder what is the 'optimal' number of lines for a method (I know there is no exact number ...). Does it make sense to put larger blocks of code in own methods even if that method only gets called in one place? I'm talking of big if blocks, nested loops etc.

I'm thinking that on one hand it must be as bothersome to be jumping up and down the file just to figure out what an if statement does. On the other hand, if that method is properly documented and has a good, self explaining name it might save some time and coffee from extinction.

Please share any experience you might have in such issues and if possible, point me to some literature.

Thank you!


p.s. if anyone cares, I've switched to green tea.
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Under a dozen lines whenever possible (and it's not always possible).

The number of moving parts is the same whether it's local or not, and holding deeply-nested structure, or remembering what happened 50 lines previous to the line you're on is unacceptable cognitive overhead (at least for me).

It's not just about the thought process though--the longer a method is the more difficult it is to test, because there's too much going on and it's difficult or impossible to test intermediate stages. A method should do one thing, do it well, and do it completely.
 
Somnath Mallick
Ranch Hand
Posts: 483
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Although i am not sure on this... I would say not to make parts of code which are used only once into methods.

Smaller methods are better. But breaking them down into smaller fragments does make understanding the code flow very difficult. I have faced this issue a lot. I had faced this issue while going through a big application, Pressing F3 to read the methods and soon I found myself in a pile of classes and when I came back to my original class, i had forgot what had happened in between!!!
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I could not disagree more.
Somnath Mallick wrote:I would say not to make parts of code which are used only once into methods.

I disagree, for the reason I already gave: untestable.
But breaking them down into smaller fragments does make understanding the code flow very difficult.

Not really. If methods are named properly what's happening should be clear.

A five-hundred line method is essentially untestable. You have to hold nearly the same amount of information in your head--but you lose the navigability provided by the IDE. You can no longer jump immediately to where functionality is implemented, because it's unnamed--just another random chunk of code inside a 500-line method.

You also lose *any* hope of reusability, both because identifying reusable code is made substantially more difficult when it's not in isolation, and because people are less likely to reuse deeply-embedded code; the ROI isn't good enough.
 
Somnath Mallick
Ranch Hand
Posts: 483
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Although i am not sure on this... I would say not to make parts of code which are used only once into methods.


That's why i said i am not sure on this coding practice... Thanks for the clarification
 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I guess it's all very subjective.

Right now I have problems testing intermediate stages of a method, just like David Newton said in his post. And all I have to do is a minor change in functionality and test it. But recently I've had the pleasure of F3-ing my way trough a class, finding only one occurrence of a method and it can be overwhelming.

It comes down to whether you prefer your long methods in one of these ways



... a lot has been said while I was typing this post
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'd argue it's *not* just a matter of preference, though.
 
Martin Vanyavchich
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't get me wrong, I prefer smaller, well named, well comented, manageable methods. I'm a big fan of those, especially after the month of work I had to put into something that could have been done in a week (possibly a few days).

I'll try your 'Under a dozen' rule and see how that works out.

Thank you all for your input
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Pie
Posts: 15439
41
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are some good books about refactoring and working with legacy code:

  • Refactoring: Improving the Design of Existing Code by Martin Fowler
  • Working Effectively with Legacy Code
  •  
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic