views:

515

answers:

11

Is it better to write many small methods (or functions), or to simply write the logic/code of those small processes right into the place where you would have called the small method? What about breaking off code into a small function even if for the time being it is only called from one spot?

If one's choice depends on some criteria, what are they; how should a programmer make a good judgement call?

I'm hoping the answer can be applied generally across many languages, but if necessary, answers given can be specific to a language or languages. In particular, I'm thinking of SQL (functions, rules and stored procedures), Perl, PHP, Javascript and Ruby.

+14  A: 

I always break long methods up into logical chunks and try to make smaller methods out of them. I don't normally turn a few lines into a separate method until I need it in two different places, but sometimes I do just to help readability, or if I want to test it in isolation.

Fowler's Refactoring is all about this topic, and I highly recommend it.

Here's a handy rule of thumb that I use from Refactoring. If a section of code has a comment that I could re-word into a method name, pull it out and make it a method.

Bill the Lizard
+5  A: 

As always you can say: it depends. It's more a question of naming and defining the task of a method. Every method should do one (not more) well defined task and should do them completely. The name of the method should indicate the task. If your method is named DoAandB() it may be better to have separate methods DoA() and DoB(). If you need methods like setupTask, executeTask, FinishTask, it may be useful to combine them.

Some points that indicate, that a merge of different methods may be useful:

  • A method cannot be used alone, without the use of other methods.
  • You have to be careful to call some dependent methods in the right order.

Some points that indicate, that a splitup of the method could be useful:

  • Some lines of the existing method have clear independent task.
  • Unit-testing of the big method gets problematic. If tests are easier to write for independent methods, then split the big method up.

As an explanation to the unit-test-argument: I wrote a method, that did some things including IO. The IO-part was very hard to test, so I thought about it. I came to the conclusion, that my method did 5 logical and independent steps, and only one of them involved the IO. So I split up my method into 5 smaller ones, four of them were easy to test.

Mnementh
+1  A: 

Some rules of thumb:

  • Functions should not be longer than what can be displayed on screen
  • Break functions into smaller ones if it makes the code more readable.
JesperE
Your first comment would work in most cases, but I have a 30 inch screen. Also, I saw a coworker with his monitor turned vertically. So I think a new rule of thumb is needed.
daub815
A: 

Personally, I lean significantly in the direction of preferring more, smaller methods, but not to the point of religiously aiming for a maximum line count. My primary criterion or goal is to keep my code DRY. The minute I have a code block which is duplicated (whether in spirit or actually by the text), even if it might be 2 or 4 lines long, I DRY up that code into a separate method. Sometimes I will do so in advance if I think there's a good chance it will be used again in the future.

On the flip side, I have also heard it argued that if your break-off method is too small, in the context of a team of developers, a teammate is likely not to know about your method, and will either write inline, or write his own small method that does the same thing. This is admittedly a bad situation.

Some also try to argue that it is more readable to keep things inline, so a reader can just read top-down, instead of having to jump around method definitions, possibly across multiple files. Personally, I think the existence of a stack trace makes this not much of an issue.

Pistos
+1  A: 

The bigger the method, the harder to test and maintain. I find its much easier to understand how a large process works when its broken down into atomic steps. Also, doing this is a great first step to make your classes extensible. You can mark those individual steps as virtual (for inheritance), or move them into other objects (composition), making your application's behavior easier to customize.

Will
+1  A: 

I make each function do one thing, and one thing only, and I try not to nest too many levels of logic. Once you start breaking your code down into well named functions, it becomes a lot easier to read, and practically self-documenting.

JamShady
+5  A: 

The size of the method is directly linked to its cyclomatic complexity.

The main advantages to keep the size of the method small (which means dividing a big method into several small methods) are:

  • better unit testing (due to low cyclomatic complexity)
  • better debugging due to a more explicit stack trace (instead of one error within one giant method)
VonC
+1  A: 

I find that having many small methods makes code easier to read, maintain and debug.

When I'm reading through a unit that implements some business logic, I can better follow the flow if I see a series of method calls that describe the process. If I care about how the method is implemented, I can go look in the code.

It feels like more work but it ultimately saves time.

There is an art, I think, to knowing what to encapsulate. Everyone has some slight difference of opinion. If I could put it in words I'd say that each method should do one thing that can be described as a complete task.

TrickyNixon
+1  A: 

I usually go for splitting functions into smaller functions that each perform a single, atomic task, but only if that function is complex enough to warrent it.

This way, I don't end up with multiple functions for simple tasks, and the functions I do extract can typically be used elsewhere as they don't try to achieve too much. This also aids unit testing as each function (as a logical, atomic action) can then be tested individually.

Mr. Matt
+4  A: 

Small methods every time.

They are self documenting (er, if well named)

They break down the problem into manageable parts - you are KeepingItSimple.

You can use OO techniques to more easily (and obviously) plug in behaviour. The large method is by definition more procedural and so less flexible.

They are unit testable. This is the killer, you simply can’t unit test some huge method that performs a load of tasks

Chris Brooks
+1 for simplicity and ease of testing. Add reusable and you've got a job. :-)
Adam Liss
+1  A: 

Something I learnt from The Code Complete book:

  • Write methods/functions so that it implement one chunk(or unit or task) of logic. If that requires breakdown into sub tasks, then write a seperate method/function for them and call them.
  • If I find that the method/function name is getting long then I try to examine the method to see it it can be broken down into two methods.

Hope this helps

omermuhammed