views:

793

answers:

19

I'm trying to find out if there is a consensus on when we should create a new method in our code. For example should we only create a new method/function if we are going to be using the code again (therefore we obviously cut down on the lines used) or is it common to do it just to avoid code clutter as well. I've been programming for a long time now but I've really just gone in and decided in rather random fashion.

Are there any design patterns or books that deal with this? A related question would be if we should only set parameters in an object using getter and setter methods. This would create a lot more code obviously but would make things more manageable? Any consensus on that?

Thanks

EDIT: Thanks everyone, tons of great answers. Definitely very helpful

+24  A: 

I think there are no specific design guidelines for this. But some of the design principles do talk about method creation.

DRY ( don't repeat yourself) is a guiding principle when comes to method creation. You group similar logic in a single method so that you don't duplicate them all over your code and thus make maintenance a nightmare.

Single Responsibility Principle is another. It says that your class, or method should do only one thing. This is to make the method size small.

Ngu Soon Hui
Also, if a method becomes very long and complex, it helps to break it down in smaller functions just to make it more manageable, even though the pieces won't be reused.
Vilx-
*Won't be reused. Yet
Earlz
+1, though the single responsibility principle really only pertains to classes.
Jeff Sternal
SRP is a good principle to follow but make sure you treat it as a guideline, lots of times it make sense to group methods in classes that make sense even if it would violate SRP. DRY however is a convention that is much closer to a law in programming. Code duplication is fundamentally insidious and should be avoided as much as possible.
Chris Marisic
One more side to this is that methods have names, and names can be very descriptive, and serve to document the code. Therefore, refactoring a block of code into a method with a descriptive name can be a step towards more self-documenting code. I've used, and seen it used, for this specific purpose many times, and find it a very useful tool in a quest for readable and maintainable code.
Pavel Minaev
to sum up: only one thing should do one thing.
geowa4
+1 for DRY principle.
Avatar
+2  A: 

I think that this is a very subjective question with no real answer. Different situations demand different solutions, and there will not be a single recipe of "when to create a new method". It depends.

Vilx-
Agreed... it's a definite candidate for the "It Depends" pattern ;)
Lazarus
+1  A: 

Check out Clean Code by Robert Martin which covers this (among other things)

ChrisF
@Chris Thanks a lot for that suggestion. I have gotten into Robert Martin's work per your suggestion and I am amazed at how great his code is. It's really a work of hard. Less than 8 lines is my new answer
John Baker
A: 

Most methods should accomplish one task.

controlfreak123
All methods accomplish one task only.
+1  A: 

getters and setters OOP aren't, and more often than not just double the size of the code for no good.

as for the books: Design Patterns (Gamma, Vlissides, Johnson, Helm), Fowler's books (Refactoring, Patterns of Enterprise Application Architecture), Beck's books (Test-Driven Development By Example, Implementation Patterns), etc.

just somebody
Syntax Error in "getters and setters OOP aren't"
Laurence Gonsalves
it was an attempt at a variation of a meme, sorry for the confusion.
just somebody
+6  A: 

If your methods are very long, it makes sense to re-factor them into smaller chunks, even if these chunks are not used anywhere else. This will increase maintainability and testability. Also, with this approach, you allow other developers to extend your code more easily in case they want to change certain responsibilities of a method, e.g. by overloading it.

As for getters and setters, it somewhat depends on the language you use. In some languages this can be quite verbose. Personally, I only provide getters and setters for public properties and/or if changing a property involves logic beyond simply setting/getting the property.

Gordon
+2  A: 

You might want to extract a method if:

  • there is a comment block for a chunk
  • you can name the intent of a chunk
wowest
+16  A: 

I regard programming as an art. As such I split methods when it feels right to split them, or to write a new one.

That said, there are some thumb rules (which does not overrule my instincts).

  1. If you need to scroll the screen to read one method, you need to split it
  2. IF you have deja vue (the code you write seems familiar) you are probably repeating yourself, which means you should us an existing function/method and not write a new one.

  3. No more than two constructs deep

    for(...) for(...) for(...) BAD

  4. No more than one loop in a row (one after the other).

  5. If you need to return more then one type of data (a null/false version is not) then you need to split something.
  6. If you get confused when reading your method - split it
  7. A method/function should be responsible for one task.
  8. The most obvious - when writing new functionality :-)
Itay Moav
+1 for using instinct
whatnick
Nice, that's a good list of concrete guidelines, instantly made me think of some of my messages, especially the "If you need to return more than one type of data" one.
Tchalvak
+9  A: 

An interesting point, albeit unrelated to object oriented programming, is made in linux's coding style guide:

Chapter 4: Functions

Functions should be short and sweet, and do just one thing. They should fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24, as we all know), and do one thing and do that well.

The maximum length of a function is inversely proportional to the complexity and indentation level of that function. So, if you have a conceptually simple function that is just one long (but simple) case- statement, where you have to do lots of small things for a lot of different cases, it's OK to have a longer function.

However, if you have a complex function, and you suspect that a less- than-gifted first-year high-school student might not even understand what the function is all about, you should adhere to the maximum limits all the more closely. Use helper functions with descriptive names (you can ask the compiler to in-line them if you think it's performance-critical, and it will probably do a better job of it that you would have done).

Another measure of the function is the number of local variables. They shouldn't exceed 5-10, or you're doing something wrong. Re-think the function, and split it into smaller pieces. A human brain can generally easily keep track of about 7 different things, anything more and it gets confused. You know you're brilliant, but maybe you'd like to understand what you did 2 weeks from now.

lorenzog
+1 a bit derivative but interesting.
whatnick
+1  A: 

A method should do one thing, and do it well. It should do nothing more or less than what its name implies. A CustomerSave method should not also normalize the customer's address.

A method should be concerned with only one "level" of functionality. If more than one line of code appears in a CustomerSave method for each of the following: opening the database, logging changes, checking security, etc., then the code is operating at the wrong level, and new methods should be created for dealing with these things at the proper granularity.

A method should typically be very short. Only in special circumstances should a method spill over more than one screen. If a method is a hundred lines long, then something is very, very wrong.

Code should not be repetitive. Duplicate functionality should be placed in a method.

Methods should be designed so that typical kinds of changes can be made easily. If a small change needs to be made in dozens of places, then that signals repetitive code that should have been placed in a single method.

Jeffrey L Whitledge
+2  A: 

In addition to the excellent answer by Ngu Soon Hui, I recommend another rule of thumb to decide when to create a new method:

Whenever you feel inclined to write a comment for a piece of code, move that code into a dedicated function instead. Give a descriptive name for the function.

Frerich Raabe
A: 

I once heard someone say that if a method/function becomes too big to fit on a single screen without scrolling then it should be refactored down into seperate methods.

It doesn't always hold true and there is no value in refractoring for refactorings sake, but does often help to keep things in perspective.

Matt Joslin
How big is your screen :)
whatnick
haha - thats made me smile!
Matt Joslin
A: 

Create a method to accomplish a specific task. If the method grows in size, that means it has some sub tasks, so separate out (refactor) the sub-tasks in to a new method.

ring bearer
A: 

When you start putting double spaces between blocks of code to signify different responsibilities.

Josh Ribakoff
A: 

Ultimately you don't want to repeat yourself, according to the DRY principle (which you and a few other people already mentioned). It also depends on the language you're using. A lot of object oriented languages make all of there methods public (e.g. Objective-C) and so you would only want to create functions that are intended to be called by other objects. On the other hand many languages like Java provide private functions which support the concept of grouping blocks of code into private functions that aren't really meant to be used outside of the class itself.

Adam
A: 

Practice unit-testing of your code, and split methods up so that you can unit-test one task per time. This is a great way to make the whole issue less subjective, by having a real outside constraint of being able to unit-test every task.

Christian
A: 

You should almost always create a new method when you're repeating code.

It removes the repeated code, and it's self-documenting if you choose a good name.

The same single line of code occurring in two places isn't too short to make a method out of unless the line is trivial and its intent is screamingly obvious.

Kyralessa
A: 

You introduce new methods even if only called once in order to limit maximum cyclomatic complexity

Off the top of my head I can list lots of reasons to extract methods and few if any to combine them.

  • The obvious one, DRY, aka DIE. I followed this philosophy before it grew cool acronyms. I don't think one should ever, for any reason, duplicate or copy-and-paste code, no matter how short it is. If you do, you are brewing up a nightmare.
  • To limit cyclomatic complexity. It's much better to have 3 understandable methods than one confusing method. This rule and others apply even if the new extracted method is only called once
  • To pull out a unit of functionality for unit testing
  • To keep all methods visible in editors without scrolling

BTW, I might suggest a change in language. "Creating a new method" sounds like adding something to the code and making it bigger and more complex. But "extracting a method" is what really happens when you refactor to a hopefully superior design. Assumming you have to have that functionality anyway, that method was always there, it was just buried inside another...

DigitalRoss
A: 

SLAP and DRY are the good principles. Refer this link http://tv.devexpress.com/SLAPrule.movie very nice talk by Mr.Julian. [Seems like the video site is down for a while. Please check later]

Avatar