Many times throughout writing larger programs I have questioned after how many copy and pastes does it make sense to put the code into a function or method and what is a good rule of thumb? I have been using a rule of thumb of four lines or greater and appearing more then twice, then I make a simple function / method containing that code. Can you think of a better practice or offer any pointers? This is more of a general design pattern question rather then a language specific question.
I use functions partly as a way to document the code. Calling a function with a meaningful name makes it easier to understand the code. In some cases even a function with a single line makes sense.
For example, in "Clean Code", Robert C. Martin gives the following example: Which one would you rather see? This:
// Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
I don't always agree with him, but in this case I do. Code should be readable, not only when you write it and you know every detail, but also at 9pm when you have to fix bugs in someone else's code. Staring at a long condition and trying to figure out all the double negatives is not recommended. If you can just put a name on it (not only conditions, but every piece of code you write), it becomes a lot simpler.
I have never regretted putting something in a function, and if you're worried about performance, then profile first.
There is a widespread misunderstanding that function calls should only be made to avoid repetitive code segments. My rule of thumb is that any logical unit of work should be made into a function, even when it's used only in a single place. This usually leads to a better readability, and allow you to write self-documenting code, where function names replaces comments and you don't need to write additional comments explaining what you're doing.
If it's used in more than one place, and
- it's likely to change, or
- it's tricky to get right
then make it a function or method. Long pieces of repeated code, in my experience, will naturally fall into one of these categories (usually the first one, but then the categories overlap a lot ;). Of course, anything that has to be in the interface is also a function/method in its own right.
Almost always, especially if each duplicate represents the same operation from a conceptual point of view. If it is performed in the same way, but on different types, make a generic implementation.
The only reason not do so that I can think of is one of maintenance: sometimes it might be more convenient to avoid creating a dependency between separate things, even at the cost of some duplication.
A search for "refactoring" will lead you to many resources for industry "best practices" for this very common process. The somewhat famous article, Once and Only Once is a great historical reference explaining what some view as "best practices" for the concerns raised by your question. Also, the even more general concept is known as Don't Repeat Yourself (DRY). For a really in-depth set of answers to your question, read Martin Fowler's great classic, Refactoring: Improving the Design of Existing Code, which covers some of the best known advice for refactoring, which is what you are intuitively trying to accomplish!
If the code is exactly repeated in more than once place and the repeated section will not change in the near future then I break it off into a function.
That depends on the nature of the cohesion of the repeated code. If the repeated section of code is performing a specific function, then it is an excellent candidate for being made into a method, partly because of the DRY principle, partly because if the function needs to be optimized or corrected, then there is only one section of code to deal with.
If the association is coincidental, it is better to repeat the code rather than make it into a method. If you need to add something to the middle of one of the code sequences to satisfy one of the uses of that snippet, if it is in a method, the change you make may affect other uses of that method.
See the Wikipedia article on the concept of code cohesion.
You have to distinguish between functions in the structured programming sense and methods of a class.
In your example, what you have shown is a method an as such should not be coded in-line.
you may have to validate a string to see if it is a number or not, in this case, you use a function and most of the preceding answers apply.
This distinction is important specially in large projects.
As much as you can, strive to separate business rules (that are methods) from computing algorithms (that are pure programming functions).