• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

methods

 
Ranch Hand
Posts: 4716
9
Scala Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
quote from "object oriented problem solving java, java, jaava" by ralph morelli


a method that gets longer than 20 to 25 lines is probably trying to do too much and should be divided into seperate methods, each with a clearly defined subtask.


although im much more object oriented than i used to be, i want to play devils advocate here. while the program will perhaps (or perhaps not) be easier to read, i would like to hear any other reasons it would be better.
 
Sheriff
Posts: 7023
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let's bump this over to the OO, UML, and Refactoring forum, where they just love to talk about this stuff...
 
author
Posts: 799
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Some of us really love to talk about this stuff. It can also be a very contentious topic.
Even 20 to 25 lines is a bit long. There are many reasons that your average method size should be considerably smaller. One to twelve lines is a better goal.
Some benefits (these are a few off the top of my head):
  • Maintenance costs. The longer a method, the more it will take you to figure out what it does, and where your modifications need to go.
  • Code readability. After the initial learning curve, smaller methods make it far easier to understand what a class does.
  • Reuse potential. If you break down methods into smaller components, you can start to recognize common abstractions in your code. You can minimize the overall amount of code dramatically by reusing these common methods.
  • Subclassing potential. The longer a method is, the more difficult it will be to create effective subclasses that use the method.
  • Naming. It's easier to come up with appropriate names for smaller methods that do one thing.
  • Performance profiling. If you have performance issues, a system with composed methods makes it easier to spot the performance bottlenecks.
  • Flexibility. Smaller methods make it easier to refactor (and to recognize design flaws, such as feature envy).
  • Coding quality. It's easier to spot dumb mistakes if you break larger methods into smaller ones.
  • Minimizes the need for comments. While comments can be valuable, most are unnecessary and can be eliminated by prudent renaming and restructuring. Comments that restate what the code says are unnecessary.


  • Downsides (maybe):
  • Initially it's harder to work with code with lots of methods. Over time, however, you will see well-composed code as having greater clarity.


  • Myths:
  • Performance. You rarely create performance problems with more methods. If you do, it's very easy to inline methods. The rule of performance is always: make it run, make it right (e.g. small methods), make it fast (optimize).


  • Caveats:
  • It's difficult to do, but you can go too far. Make sure each method has a valid reason for existing; otherwise inline it.


  • This is all, of course, debatable.
    -Jeff L.-
    [ January 19, 2004: Message edited by: Jeff Langr ]
     
    (instanceof Sidekick)
    Posts: 8791
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Google on "coding by intention". There are some neat discussions of making the code explain itself. And if it bothers you to have a lot of little methods in a class, maybe ask yourself if there should be more classes?
     
    author
    Posts: 14112
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I wholeheartedly agree with Jeff and Stan. Actually, most of my methods tend to be two to four lines long. Having a good code browser (like the one of Eclipse) helps very much understanding such code, though.
     
    Ranch Hand
    Posts: 45
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Flexibility. Smaller methods make it easier to refactor (and to recognize design flaws, such as feature envy).


    What is "feature envy"?
     
    Ranch Hand
    Posts: 5093
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    performance: not a myth (at least doesn't have to be).
    Each method call takes time, and loads of them take loads of time.
    In an extreme case (I admit) I once shaved 30% off the runtime of an application by unrolling a single functioncall.
    Admittedly this was an extremely simple function (with only 2 short lines of code) which was called in only 2 places (both of which were inside short loops with extremely high (but variable) numbers of passes, but it can happen.
    Application runtime from this action alone was reduced from 36 hours to 26 or so, which went a long way towards the goal of having it complete within a day (other actions like unrolling some loops reduced the total runtime to 16 hours which was acceptable with room for growth).
    There's a lot of times when there is no way to reduce the size of a function to 25 lines or so.
    Just consider JDBC, JNDI and reflection. These produce stacks of Exceptions which have to be handled, leading to reams of code for that alone (in one example in a book there were 32 lines of exception handling code for 5 lines of application code, I'm sure we've all seen similar things many times).
    There's no way such occurrances can be simply changed to reduce the number of lines within a method except extremely contrived procedures or simply passing all Exceptions up the chain of events until they hammer the end user.
     
    Jeff Langr
    author
    Posts: 799
    5
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Greg Reinl:

    What is "feature envy"?


    Feature envy is when a method is more interested in a class other than the one it's in. You've reached feature envy when you send more messages to some other object than yourself. It's a "code smell" (see Fowler's Refactoring book) that indicates it's time to move the method to another class.
    -Jeff L.-
     
    Jeff Langr
    author
    Posts: 799
    5
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Jeroen Wenting:
    performance: not a myth (at least doesn't have to be).
    Each method call takes time, and loads of them take loads of time.


    Correct, but the key word is "loads." Most performance problems are caused by something else (IO operations, network latency, poor choice of algorithm). The same rule still applies: write code for optimal design first, and then optimize where necessary.



    There's a lot of times when there is no way to reduce the size of a function to 25 lines or so.
    Just consider JDBC, JNDI and reflection. These produce stacks of Exceptions which have to be handled, leading to reams of code for that alone (in one example in a book there were 32 lines of exception handling code for 5 lines of application code, I'm sure we've all seen similar things many times).
    There's no way such occurrances can be simply changed to reduce the number of lines within a method except extremely contrived procedures or simply passing all Exceptions up the chain of events until they hammer the end user.


    Putting the whole checked-vs-unchecked exceptions discussion aside, if you're putting 32 lines of exception handling code in every catch block, you've got some bad code redundancy.
    If you have methods that are regularly 25 lines long, you have serious duplication problems. With respect to JDBC, there are so many common things that you can extract to make for more reasonable length methods. Look at database interaction as an abstraction layer. Why should you have JDBC specific code in virtually every data access class? It begs for a better design, one where if you had to, you could replace Oracle SQL with MySQL overnight (done that), or even replace SQL with something else (done that in the opposite direction). The unoptimized JDBC-heavy app with embedded SQL statements, with Oracle-specific date functions, does not make it so easy.
    You are correct, there are always exceptions to every rule about method size. But one way to look at things is to look at smaller methods as a goal to strive for, not a hard number. Instead of debating whether 25 lines, 12 lines or 200 lines is acceptable, see what you can do to reduce method length in code that you would've otherwise not touched. You'll be surprised at how much code you can eliminate. Few people would promote pushing hard in the other direction.
    As far as the contention that there are "a lot of times when there is no way to reduce the size of a function to 25 lines or so," I've worked on mid-sized systems (500,000-1,000,000 lines?) where there were few methods longer than a dozen lines in the entire application. It's almost always possible.
    Regards,
    Jeff
    [ January 20, 2004: Message edited by: Jeff Langr ]
     
    Stan James
    (instanceof Sidekick)
    Posts: 8791
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    ... stacks of exceptions ...


    Just curious, do you really do anything DIFFERENT for each one? Or just
    catch( ExceptionX x ) { log "Exception X occurred"; }
    I've almost never found much reason to do different handling of every possible exception, and usually let a single catch Exception or throws Exception do the job.
     
    Ilja Preuss
    author
    Posts: 14112
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Jeroen Wenting:
    Each method call takes time


    That's actually wrong, as the Hotspot Engine can decide to inline a method call.


    In an extreme case (I admit) I once shaved 30% off the runtime of an application by unrolling a single functioncall.
    Admittedly this was an extremely simple function (with only 2 short lines of code) which was called in only 2 places (both of which were inside short loops with extremely high (but variable) numbers of passes, but it can happen.


    Interesting. Which JRE were you using?


    Application runtime from this action alone was reduced from 36 hours to 26 or so


    Mhh, I don't think that's very much. In the *typical* case, you will get much better improvements by improving your datastructures and/or algorithms.
    Of course *there are* situations where manually inlining a method is the reasonable thing to do - the one you quote probably one of them. The point is, it's much more often the wrong thing to do. So often, that it's almost always the wrong thing to do without a proof (by some actual experiments) that it solves a current problem.

    There's a lot of times when there is no way to reduce the size of a function to 25 lines or so.


    Mhh, that's quite contrary to my experience...

    Just consider JDBC, JNDI and reflection. These produce stacks of Exceptions which have to be handled, leading to reams of code for that alone (in one example in a book there were 32 lines of exception handling code for 5 lines of application code, I'm sure we've all seen similar things many times).


    I've seen it many times. I've always thought of as in need of refactoring.

    There's no way such occurrances can be simply changed to reduce the number of lines within a method except extremely contrived procedures or simply passing all Exceptions up the chain of events until they hammer the end user.


    Can you provide an example of such a method? I would be interested in seeing wether I really can't find a way to reduce the we all can agree on doesn't result in "extremely contrived procedures". We would probably all learn something along the way...
     
    author and iconoclast
    Posts: 24207
    46
    Mac OS X Eclipse IDE Chrome
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Jeff Langr:

    Some benefits (these are a few off the top of my head):


    You forgot one of my favorites: testability. More small methods means that it's easier to test individual bits of functionality in isolation, and easier to subclass a class to create a test-specific stub.
     
    Jeff Langr
    author
    Posts: 799
    5
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Ernest Friedman-Hill:

    You forgot one of my favorites: testability. More small methods means that it's easier to test individual bits of functionality in isolation, and easier to subclass a class to create a test-specific stub.


    That's a great addition, although my mindset is a bit different: since I'm always writing tests first, testability isn't a benefit, it's a requirement. However, your point still applies--it's easier to create mocks/stubs if the implementation is broken into smaller methods.
    Also (stating the same thing as you but slightly differently), writing smaller methods will help you figure out an appropriate test method to write in advance.
    -Jeff
     
    Randall Twede
    Ranch Hand
    Posts: 4716
    9
    Scala Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    thanks jeff (and everyone else),
    i now understand why the author said that. i see now that there really are valid, practical reasons. just kind of wanted to see some listed. i guess having a background that started in the late 70's i wanted to know why make a method (subroutine) if it is only used in one place.
    [ January 21, 2004: Message edited by: Randall Twede ]
     
    reply
      Bookmark Topic Watch Topic
    • New Topic