Related
As a student in computer engineering I have been pressured to type up very detailed comments for everything I do. I can see this being very useful for group projects or in the work place but when you work on your own projects do you spend as much time commenting?
As a personal project I am working on grows more and more complicated I sometimes feel as though I should be commenting more but I also feel as though it's a waste of time since I will probably be the only one working on it. Is it worth the time and cluttered code?
Thoughts?
EDIT: This has given me a lot to think about. Thanks for all your input! I never expected this large of a response.
Well considered comments illuminate when the code cannot. Well considered function and variable names eliminate the need for copious comments. If you find it necessary to comment everything, consider simplifying your code.
If you ever look at code you wrote 6 months before, you will be wondering why you did not comment better.
If the code is well written, with short methods (see Composed Method pattern) and meaningful names, then the code needs very little comments. Only comments which explain the "why" are useful - the comments explaining "what" should be replaced by improving the code so much that it's obvious what it does. Comments should not be used as an excuse for writing bad code.
Public APIs, especially in closed-source apps, are perhaps the only place where thorough javadocs are recommended - and then you need to take the effort to maintain them and keep them always accurate and up-to-date. A misleading or outdated comment is worse than no comment. It's better to document what the code does by writing tests for it and using good names for the tests.
The book Clean Code has a good chapter about comments.
Unit tests and the like are the best forms of code documentation. Some testing frameworks write out a spec of what the class under test should do, giving people a great introduction to how a piece of code works in pure english while also providing very clean way to implement the tests itself.
Examples of that are Scala's ScalaTest or RSpec for Ruby.
I find that unless some weird hacky thing is required by the code in question, it is usually not beneficial to comment it. Also, it adds a lot of overhead because you have to maintain the comments... and maintaining the code and tests is already enough work.
Remember, code with out-of-date comments is worse than no comments at all!
A lot of the time, comments just says what the code does anyway, which is a waste of human effort. And if it doesn't, your code probably sucks and you should refactor it.
Just use testing frameworks.
Comment -- or better yet, recode -- anything that is non-obvious now. Later it will be completely non-obvious. You might think, "but it's going to be me," but if your way of thinking (and ways of coding) changes as you grow what's obvious to you now might not be obvious to you later.
Have you read Code Complete yet? Recommended as a very good read, and a great way to figure out some of the things CS profs drill down your throat.
Code comments come in two variety:
Comments to explain logic, making
sure that the code matches the
intent. Often people will write high
level pseudocode and will use that
in comment form to fill in the
actual code of what the module will
do. Then they leave the comments as
a read-along which can be used
during later review.
Comments to
explain usage of a module. Think
javadocs. Your intent here is for
the consumers to understand why your
code is important. One use of
javadocs is in the Visual Studio
Intellisense (since I don't use
Eclipse idk). It shows the comments
from the javadoc in the intellisense
hover. Becomes VERY handy later on.
When professors ask you to document everything in your code, I have found the usage of psuedocode translated to actual code to be sufficient. However, in practice I've not found that many devs need it, as usually the code is sufficient to explain itself (when simple, well written, not relying on tricks, and when using descriptive variable names).
But I still put in comments about intent if I think it's the least bit unclear. This is just a bit of best practice.
But I definitely say read that book. ;)
If you ever decide to open-source your personal project, people will thank you for your comments (unless they're terrible). If you hit upon a spectacularly great idea and your personal project turns into a business, then you'll be hiring more developers, and again your comments will be valuable. If you suffer a mild head injury, then when you return to work you'll be thankful for your comments.
Some people treat comments as a code smell, a sign that the code could use more descriptive names and a better structure. They will fix the code so it does not need comments.
This works in a lot of cases. However one type of comment that is useful is 'why' something is being done. Sometimes fixes are made for obscure reasons that would not be obvious when reviewing the code later. The comments should not express what the code does (that should be covered by naming) or how it does that (again, the code tells you that), so save your comments for 'why'.
I find that nothing serves as better documentation as to how something works then unit tests.
Whenever i'm doing something that isn't self-documenting, i'll put a comment. I will forget what i was doing unless i do. But i prefer to write code that's so obvious that comments don't help much. Wherever possible, the code should be clear enough that thousands of lines of comments would be unnecessary.
Whatever you do, do NOT write comments like this...
// add 1 to i
++i;
That's noise. You're actually worse off with comments like that than with none at all.
A hard-core stance is: "if you have to write a comment for your code, your code is broken". Rather than writing explanatory comments, refactor your code so that the comments become less necessary. This applies especially to function names (including their parameters), since they tend to be modified the most, and the comments seldom are updated to match.
Instead of:
// Compute average for the two times
int a = t1 + (t2 - t1) / 2;
write
int averageTime = AverageOfTimes(t1, t2);
int AverageOfTimes(int t1, int t2) {
return t1 + (t2-t1);
}
Stale comments are one of the leading causes of WTF's when I'm reading other people's code.
Overcommenting has been cited as a "code smell" by several authors, including the authors of "Clean Code".
Personally, I write an explanatory comment for each class (I code in C# and C++ mostly), and occasionally when I am using an algorithm I want to refer to.
To be honest, if code is clear its not necessary, but comments are best when a specific logic breaks given certain data (which may not be obvious). Leaving comments of issues that may occur is a great way to help prevent accidental bugs due to misunderstandings of what data to expect (or specifically not).
I used to be in the exact same situation as you. When I first started I never commented anything because everything was extremely small and I always knew how it worked. But as I continued to expand my code and everything started pointing to each other, I found myself not knowing what certain things did anymore and got lost. I had to rewrite a lot of things so I knew what they did again, and I started commenting everything so I knew exactly how it worked and how to use it in the future. You may think you know how everything works now, but in the future you'll look back at something and say 'HUH?' It's better to comment things now and save yourself the trouble later.
The way I comment things:
Always add this at the top of any function, so you know what it does.
/**
* What the function is supposed to do, a brief description of it.
*
* #param paramter_name Object-type A description of it, do for each parameter.
*
* #return Object-type - A brief description of what is being returned.
**/
Then throughout your code make sure you comment things that look complicated. When you run checks, put a quick comment like 'make sure this is valid'. For any long lines of code or large blocks of code, add a comment of what that specific section does, to easily find it later on.
Commenting is useful for individual project as well as group projects especially when you will need to maintain or enhance the code over an extended period of time. This scenario may not be applicable for school projects, but in the workplace it is definitely applicable. If you have ever had to look at code that you wrote 6 months in the past then it might as well have been written by somebody else.
I have found that--as everyone will tell you--if you are coming back to code after several months you will have forgotten everything. That said, I hardly comment my own code except for comments like // ew.. hacked because X-beyond-my-control doesn't do Y correctly. But this is because the code itself is written very cleanly and is very easy to read. For instance, all variable and function names are completely descriptive. I don't use abbreviations except for rather long words which are obvious such as 'info'. All functions are extremely brief. All functions do one thing if possible. Nesting is avoided if possible. Logically related functions are grouped via classes or modules.
When I read other people's code, I don't read the comments. I read the code. And the difference between clear and well written code and spaghetti is far more important than any comments. Usually I don't care what their intent is/was; I want to change the code. And to do that it easily it needs to be well organized. So the comments are peripheral. But perhaps this is just me.
Technically speaking the code is perfectly self documenting. I like to comment anything that is non-obvious or especially complex. I tend to like to have at minimum summary on a class, and maybe a short blurb for each member. When you have to write a huge amount of doc on a very large and complex method that is usually a good sign that it needs to be looked at for a refactor.
foreach(var a in b.Items) //Enumerate the items in "b"
{
if(a.FirstName == "Jones") //See if first name is Jones
....
You want something in the middle of the above and no commenting whatsoever.
commenting is always useful!And I dont thik that commenting is a waste of time!It helps other developeres understand your code and it helps you when you haven't work on a project for months.
University software courses often push people towards excessive commenting as a way of forcing students to think twice about what they have typed. A nasty rule-of-thumb that was put my way when I was marking undergrad coursework a few years ago suggested a comment every 5-10 lines. Think most Java courses tell you to limit methods to circa 30 lines, so lots of comments within a function is a sign you should break it up.
My personal preference is to limit comments to documenting function purpose/inputs/outputs and data structures. Otherwise comments ought to be limited to things that require particular attention (eg things that looks out of place, perhaps bugs, at first glance).
The first comments are the variables and methods names. A lot of attention shall be paid to choose them. Do not hesitate to rename them if you can think of a better name.
Consistency and convention also help. Try to avoid NumberOfStuff, ThingCount, FooSize, always use the same form, possibly something in line with the language (does it have Array.length, or Vector.size). Always name similar things with similar names.
"Code never lies. Comments sometimes do". One day or the other, someone will modify the code and not the associated comment. Better spenf more time writing self-explanatory code complemented with some clever comment, than splitting out code and then explaining things with a lot of comments.
Rule #1
Comments should indicate WHY not 'what' (the code already tells you 'what' is happening)
Rule #2
After writing the comment - rewrite your code to read like the comment (then remove the comment)
While good variable and function names etc. may lessen the need for comments, any sufficiently complex program is going to be hard to understand merely by looking at the code alone, no matter how carefully it was written.
In general, the larger the body of code and the longer you expect it to be in use, the more important it will be to write detailed comments. It is perfectly reasonable for teachers to demand detailed comments because they don't want to have to spend a lot of time trying to understand large amounts of code from different students, but you don't necessarily have to maintain that same standard outside the classroom.
Regarding commenting functions & classes and the like, I find that only the most trivial functions are so self explanatory that a comment won't save the reader some time. Also, when you are using a smart IDE for a language such as Java or Curl writing properly formatted documentation comments will allow developers to see documentation for functions and methods simply by hovering over a call signature. This can save you a lot of time when working with large systems.
I'm not sure if it's possible to give general advice on this topic, but please try. It's hard to explain my case because it's too complex to explain. And that's exactly the problem.
I seem to constantly stumble on a situation where I try to design some part of my project, but it has so many things to take into consideration that I'm unable to get a grasp of it.
Are there any general tips or advice on how to look at my system in smaller pieces at a time? How to find smaller portions that could be designed separately on their own?
Create a glossary.
In other words, identify the terms that are meaningful to the project domain — not from the programmer's point of view, but from a user's, who is familiar with the subject matter.
Then define the terms as precisely and discretely as you can. A good definition in this form can serve as a kind of pseudocode.
Since you have not identified even the domain of your problem, I'll choose a random example. In a civilian personnel system, you might have terms like:
billet: a term of service (from start date to end date) at a particular grade and step
employee: a series of billets associated with a particular SSN
grade and step: row and column in the federal general schedule
And so on. This isn't to identify functional units, as it sounds like you are trying to do, but it's a good preparatory step before doing so, so that you can express your functional steps in well-defined terms.
Your key goals are:
High cohesion: Code (methods, fields, classes) within one piece/module/partition should interact intensively; it should make sense for these elements to know about each other. If you find that some of them don't interact much with the rest, they probably belong somwhere else or should form their own partition. If you find code outside interacting intensively with the partition and knowing too much about its inner workings, it probably belongs inside. The typical example is found in OO code written in procedural style, with "dumb" data objects and "manager" code that operates on them but should really be part of the data objects.
Loose coupling: Interaction between pieces/modules/partitions should only happen through narrow, well-defined, well-documented APIs. Try to identify such APIs and see what code is needed to implement them and what code will use them.
It's useful to approach problem decomposition both top-down and bottom-up.
If you're having trouble splitting a big problem into two or more smaller problems, try to think of the smallest possible problems that will need to be solved. Once those are handled, you may start to see ways to combine them into larger problems as you approach your original large problem.
When I find myself copying and pasting chunks of code with minimal adjustments I realize that's a "partition" and then create a class, method, function, or whatever.
Actually, the whole object oriented approach is what it's all about. Try thinking of your application as tangible things that do stuff. Write pseudo code describing what the things are and what they do, I find lots of "partitions" this way.
Here's a try, kind of wild guess.
People usually underestimate how long it will take them to do the work. If your project is large, then most likely you'll need several people to work on it, so you can try planning with that in mind. Now a person can be expected to hold just one area in the head, so you'll need to explain to him exactly what kind of task he's supposed to do.
So I'd say you should try to write a job description that should encompass as much as possible for one person to seriously concentrate on. Repeat, until you have broken your project into parts you wanted to. As a benefit, you're ready to assemble your team. But if you find out the parts are small, maybe you'll still be able to do it yourself.
Long methods are evil on several grounds:
They're hard to understand
They're hard to change
They're hard to reuse
They're hard to test
They have low cohesion
They may have high coupling
They tend to be overly complex
How to convince your fellow developer to write short methods? (weapons are forbidden =)
question from agiledeveloper
Ask them to write unit tests for the methods.
That depends on your definitions of "short" and "long".
When I hear someone say "write short methods", I immediately react badly because I've encountered too much spaghetti written by people who think the ideal method is two lines long: One line to do the tiniest possible unit of work followed by one line to call another method. (You say long methods are evil because "they're hard to understand"? Try walking into a project where every trivial action generates a call stack 50 methods deep and trying to figure out which of those 50 layers is the one you need to change...)
On the other hand, if, by "short", you mean "self-contained and limited to a single conceptual function", then I'm all for it. But remember that this can't be measured simply by lines of code.
And, as tydok pointed out, you catch more flies with honey than vinegar. Try telling them why your way is good instead of why their way is bad. If you can do this without making any overt comparisons or references to them or their practices (unless they specifically ask how your ideas would relate to something they're doing), it'll work even better.
You made a list of drawbacks. Try to make a list of what you'll gain by using short methods. Concrete examples. Then try to convince him again.
I read this quote from somewhere:
Write your code as if the person who has to maintain it is a violent psycho, who knows where you live.
In my experience the best way to convince a peer in these cases is by example. Just find opportunities to show them your code and discuss with them the benefits of short functions vs. long functions. Eventually they'll realize what's better spontaneously, without the need to make them feel "bad" programmers.
Code Reviews!
I suggest you try and get some code reviews going. This way you could have a little workshop on best practices and whatever formatting your company adhers to. This adds the context that short methods is a way to make code more readable and easier to understand and also compliant with the SRP.
If you've tried to explain good design and people just aren't getting it, or are just refusing to get it, then stop trying. It's not worth the effort. All you'll get is a bad rep for yourself. Some people are just hopeless.
Basically what it comes down to is that some programmers just aren't cut out for development. They can understand code that's already written, but they can't create it on their own.
These folks should be steered toward a support role, but they shouldn't be allowed to work on anything new. Support is a good place to see lots of different code, so maybe after a few years they'll come to see the benefits of good design.
I do like the idea of Code Reviews that someone else suggested. These sloppy programmers should not only have their own code reviewed, they should sit in on reviews of good code as well. That will give them a chance to see what good code is. Possibly they've just never seen good code.
To expand upon rvanider's answer, performing the cyclomatic complexity analysis on the code did wonders to get attention to the large method issue; getting people to change was still in the works when I left (too much momentum towards big methods).
The tipping point was when we started linking the cyclomatic complexity to the bug database. A CC of over 20 that wasn't a factory was guaranteed to have several entries in the bug database and oftentimes those bugs had a "bloodline" (fix to Bug A caused Bug B; fix to Bug B caused Bug C; etc). We actually had three CC's over 100 (max of 275) and those methods accounted for 40% of the cases in our bug database -- "you know, maybe that 5000 line function isn't such a good idea..."
It was more evident in the project I led when I started there. The goal was to keep CC as low as possible (97% were under 10) and the end result was a product that I basically stopped supporting because the 20 bugs I had weren't worth fixing.
Bug-free software isn't going to happen because of short methods (and this may be an argument you'll have to address) but the bug fixes are very quick and are often free of side-effects when you are working with short, concise methods.
Though writing unit tests would probably cure them of long methods, your company probably doesn't use unit tests. Rhetoric only goes so far and rarely works on developers who are stuck in their ways; show them numbers about how those methods are creating more work and buggy software.
Finding the right blend between function length and simplicity can be complex. Try to apply a metric such as Cyclomatic Complexity to demonstrate the difficulty in maintaining the code in its present form. Nothing beats a non-personal measurement that is based on testing factors such as branch and decision counts.
Not sure where this great quote comes from, but:
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it"
Force him to read Code Complete by Steve McConnell. Say that every good developer has to read this.
Get him drunk? :-)
The serious point to this answer is the question, "why do I consistently write short functions, and hate myself when I don't?"
The reason is that I have difficulty understanding complex code, be that long functions, things that maintain and manipulate a lot of state, or that sort of thing. I noticed many years ago that there are a fair number of people out there that are significantly better at dealing with this sort of complexity than I am. Ironically enough, it's probably because of that that I tend to be a better programmer than many of them: my own limitations force me to confront and clean up that sort of code.
I'm sorry I can't really provide a real answer here, but perhaps this can provide some insight to help lead us to an answer.
Force them to read the book "Clean Code", there are many others but this one is new, good and an easy read.
Asking them to write Unit tests for the complex code is a good avenue to take. This person needs to see for himself what that debt that complexity brings when performing maintenance or analysis.
The question I always ask my team is: "It's 11 pm and you have to read this code - can you? Do you understand under pressure? Can you, over the phone, no remote login, lead them to the section where they can fix an error?" If the answer is no, the follow up is "Can you isolate some of the complexity?"
If you get an argument in return, it's a lost cause. Throw something then.
I would give them 100 lines of code all under 1 method and then another 100 lines of code divided up between several methods and ask them to write down an explanation of what each does.
Time how long it takes to write both paragraphs and then show them the result.
...Make sure to pick code that will take twice or three times as long to understand if it were all under one method - Main() -
Nothing is better than learning by example.
short or long are terms that can be interpreted differently. For one short is a 2 line method while some else will think that method with no more than 100 lines of code are pretty short.
I think it would be better to state that a single method should not do more than one thing at the same time, meaning it should only have one responsibility.
Maybe you could let your fellow developers read something about how to practice the SOLID principles.
I'd normally show them older projects which have well written methods. I would then step through these methods while explaining the reasons behind why we developed them that way.
Hopefully when looking at the bigger picture, they would understand the reasons behind this.
ps. Also, this exercise could be used in conjuction as a mini knowledge transfer on older projects.
Show him how much easier it is to test short methods. Prove that writing short methods will make it easier and faster for him to write the tests for his methods (he is testing these methods, right?)
Bring it up when you are reviewing his code. "This method is rather long, complicated, and seems to be doing four distinct things. Extract method here, here, and here."
Long methods usually mean that the object model is flawed, i.e. one class has too many responsibilities. Chances are that you don't want just more functions, each one shorter, in the same class, but those responsibilies properly assigned to different classes.
No use teaching a pig to sing. It wastes your time and annoys the pig.
Just outshine someone.
When it comes time to fix a bug in the 5000 line routine, then you'll have a ten-line routine and a 4990-line routine. Do this slowly, and nobody notices a sudden change except that things start working better and slowly the big ball of mud evaporates.
You might want to tell them that he might have a really good memory, but you don't. Some people are able to handle much longer methods than others. If you both have to be able to maintain the code, it can only be done if the methods are smaller.
Only do this if he doesn't have a superiority complex
[edit]
why is this collecting negative scores?
You could start refactoring every single method they wrote into multiple methods, even when they're currently working on them. Assign extra time to your schedule for "refactoring other's methods to make the code maintanable". Do it like you think it should be done, and - here comes the educational part - when they complain, tell them you wouldn't have to refactor the methods if they would have made it right the first time. This way, your boss learns that you have to correct other's lazyness, and your co-workers learn that they should make it different.
That's at least some theory.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
When writing a mathematical proof, one goal is to continue compressing the proof. The proof gets more elegant but not necessarily more readable. Compression translates to better understanding, as you weed out unnecessary characters and verbosity.
I often hear developers say you should make your code foot print as small as possible. This can very quickly yield unreadable code. In mathematics, it isn't such an issue since the exercise is purely academic. However, in production code where time is money, having people try to figure out what some very concise code is doing doesn't seem to make much sense. For a little more verbose code, you get readability and savings.
At what point do you stop compressing software code?
I try to reach a level of verbosity where my program statements read like a sentence any programmer could understand. This does mean heavily refactoring my code such that it's all short pieces of a story, so each action would be described in a separate method (an even further level might be to another class).
Meaning I would not reduce my number of characters just because it can be expressed in fewer. That's what code-golf competitions are for.
My rule is say what you mean. One common way I see people go wrong is "strength reduction." Basically, they replace the concept they are thinking with something that seems to skip steps. Unfortunately, they are leaving concepts out of their code, making it harder to read.
For example, changing
for (int i = 0; i < n; i++)
foo[i] = ...
to
int * p = foo, q = foo+n;
while ( *p++ = ... < q );
is an example of a strength reduction that seems to save steps, but it leaves out the fact that foo is an array, making it harder to read.
Another common one is using bool instead of an enum.
enum {
MouseDown,
MouseUp
};
Having this be
bool IsMouseDown;
leaves out the fact that this is a state machine, making the code harder to maintain.
So my rule of thumb would be, in your implementation, don't dig down to a lower level than the concepts you are trying to express.
You can make code smaller by seeing redundancy and eliminating it, or by being clever. Do the former and not the latter.
Here's a good article by Steve McConnell - Best Practices http://www.stevemcconnell.com/ieeesoftware/bp06.htm
I think short/concise are two results from well written code. There are many aspects to make code good and many results from well written code, realize the two are different. You don't plan for a small foot print, you plan for a function that is concise and does a single thing extremely well - this SHOULD lead to a small foot print (but may not). Here's a short list of what I would focus on when writing code:
single focused functions - a function should do only one thing, a simple delivery, multi featured functions are buggy and not easily reusable
loosely coupled - don't reach out from inside one function to global data and don't rely heavily on other functions
precise naming - use meaningful precise variable names, cryptic names are just that
keep the code simple and not complex - don't over use language specific technical wow's, good for impressing others, difficult to easily understand and maintain - if you do add something 'special' comment it so at least people can appreciate it prior to cursing you out
evenly comment - to many comments will be ignored and outdated to few have no meaning
formatting - take pride in how the code looks, properly indented code helps
work with the mind of a code maintenance person - think what it would be like to maintain the code you're writting
do be afraid or to lazy to refactor - nothing is perfect the first time, clean up your own mess
One way to find a balance is to seek for readability and not concise-ness. Programmers are constantly scanning code visually to see what is being done, and so the code should as much as possible flow nicely.
If the programmer is scanning code and hits a section that is hard to understand, or takes some effort to visually parse and understand, it is a bad thing. Using common well understood constructs is important, stay away from the vague and infrequently used unless necessary.
Humans are not compilers. Compilers can eat the stuff and keep moving on. Obscure code is not mentally consumed by humans as quickly as clearly understood code.
At times it is very hard to produce readable code in a complicated algorithm, but for the most part, human readability is what we should look for, and not cleverness. I don't think length of code is really a measure of clearness either, because sometimes a more verbose method is more readable than a concise method, and sometimes a concise method is more readable than a long one.
Also, comments should only supplement, and should not describe your code, your code should describe itself. If you have to comment a line because it isn't obvious what is done, that is bad. It takes longer for most experienced programmers to read an English explanation than it does to read the code itself. I think the book Code Complete hammers this one home.
As far as object names go, the thinking on this has gone through an evolution with the introduction of new programming languages.
If you take the "curly brace" languages, starting with C, brevity was considered the soul of wit. So, you would have a variable to hold a loan value named "lv", for instance. The idea was that you were typing a lot of code, so keep the keystrokes to a minimum.
Then along came the Microsoft-sanctioned "Hungarian notation", where the first letters of a variable name were meant to indicate its underlying type. One might use "fLV", or some such, to indicate that the loan value was represented by a float variable.
With Java, and then C#, the paradigm has become one of clarity. A good name for a loan value variable would be "loanValue". I believe part of the reason for this is the command-completion feature in most modern editors. Since its not necessary to type an entire name anymore, you might as well use as many characters as is needed to be descriptive.
This is a good trend. Code needs to be intelligible. Comments are often added as an afterthought, if at all. They are also not updated as code is updated, so they become out of date. Descriptive, well-chosen, variable names are the first, best and easiest way to let others know what you were coding about.
I had a computer science professor who said "As engineers, we are constantly creating types of things that never existed before. The names that we give them will stick, so we should be careful to name things meaningfully."
There needs to be a balance between short sweet source code and performance. If it is nice source and runs the fastest, then good, but for the sake of nice source it runs like a dog, then bad.
Strive to refactor until the code itself reads well. You'll discover your own mistakes in the process, the code will be easier to grok for the "next guy", and you won't be burdened by maintaining (and later forgetting to change) in comments what you're already expressed in code.
When that fails... sure, leave me a comment.
And don't tell me "what" in the comment (that's what the code is for), tell me "why".
As opposed to long/rambling? Sure!
But it gets to the point where it's so short and so concise that it's hard to understand, then you've gone too far.
Yes. Always.
DRY: Don't Repeat Yourself. That will give you a code that is both concise and secure. Writing the same code several times is a good way to make it hard to maintain.
Now that does not mean you should make a function of any blocks of code looking remotely alike.
A very common error (horror ?) for instance is factorizing code doing nearly the same thing, and to handle the differences between occurences by adding a flag to function API. This may look inocuous at first, but generates code flow hard to understand and bug prone, and even harder to refactor.
If you follow common refactoring rules (looking about code smells) your code will become more and more concise as a side effect as many code smells are about detecting redundancy.
On the other hand, if you try to make the code as short as possible not following any meaningfull guidelines, at some point you will have to stop because you just won't see any more how to reduce code.
Just imagine if the first step is removing all useless whitespaces... after that step code in most programming languages will become so hard to read you won't have much chance to find any other possible enhancement.
The example above is quite caricatural, but not so far from what you get when trying to optimise for size without following any sensible guideline.
There's no exact line that can be drawn to distinguish between code that is glib and code that is flowery. Use your best judgment. Have others look at your code and see how easily they can understand it. But remember, correctness is the number 1 goal.
The need for small code footprints is a throwback from the days of assembly language and the first slightly high level languages... there small code footprints where a real and pressing need. These days though, its not so much of a necessity.
That said, I hate verbose code. Where I work, we write code that reads as much as possible like a natural language, without any extra grammar or words. And we don't abbreviate anything unless its a very common abbreviation.
Company.get_by_name("ABC")
makeHeaderTable()
is about as terse as we go.
In general, I make things obvious and easy to work with. If concision/shortness serves me in that end, all the better. Often short answers are the clearest, so shortness is a byproduct of obvious.
There are a couple points to my mind that determine when to stop optimizing:
Worth of spending time performing optimizations. If you have people spending weeks and not finding anything, are there better uses of those resources?
What is the order of optimization priority. There are a few different factors that one could care about when it comes to code: Execution time, execution space(both running and just the compiled code), scalability, stability, how many features are implemented, etc. Part of this is the trade off of time and space, but it can also be where does some code go, e.g. can middleware execute ad hoc SQL commands or should those be routed through stored procedures to improve performance?
I think the main point is that there is a moderation that most good solutions will have.
The code optimizations have little to do with the coding style. The fact that the file contains x spaces or new lines less than at the beginning does not make it better or faster, at least at the execution stage - you format the code with white characters that are unsually ignored by the compiler. It even makes the code worse, because it becomes unreadable for the other programmers and yourself.
It is much more important for the code to be short and clean in its logical structure, such as testing conditions, control flow, assumptions, error handling or the overall programming interface. Of course, I would also include here smart and useful comments + the documentation.
There is not necessarily a correlation between concise code and performance. This is a myth. In mature languages like C/C++ the compilers are capable of optimizing the code very effectively. There is cause need in such languages to assume that the more concise code is the better performing code. Newer, less performance-optimized languages like Ruby lack the compiler optimization features of C/C++ compilers, but there is still little reason to believe that concise code is better performing. The reality is that we never know how well code will perform in production until it gets into production and is profiled. Simple, innocuous, functions can be huge performance bottlenecks if called from enough locations within the code. In highly concurrent systems the biggest bottlenecks are generally caused by poor concurrency algorithms or excessive locking. These issues are rarely solved by writing "concise" code.
The bottom line is this: Code that performs poorly can always be refactored once profiling determines it is the bottleneck. Code can only be effectively refactored if it is easy to understand. Code that is written to be "concise" or "clever" is often more difficult to refactor and maintain.
Write your code for human readability then refactor for performance when necessary.
My two cents...
Code should be short, concrete, and concentrated. You can always explain your ideas with many words in the comments.
You can make your code as short or compact as you like as long as you comment it. This way your code can be optimized but still make sence. I tend to stay in the middle somewhere with descriptive variables and methods and sparce comments if it is still unclear.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
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.
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.
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)
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.
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
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
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.
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.
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.
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.
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.
It depends a bit ... on mindset. Still, this is not an opinionated question.
The answer rather actually depends on the language context.
In a Java/C#/C++ world, where people are following the "Clean Code" school, as preached by Robert Martin, then: many small methods are the way to go.
A method has a clear name, and does one thing. One level of nesting, that's it. That limits its length to 3, 5, max 10 lines.
And honestly: I find this way of coding absolutely superior to any other "style".
The only downside of this approach is that you end up with many small methods, so ordering within a file/class can become an issue. But the answer to that is to use a decent IDE that allows to easily navigate forth and back.
So, the only "legit" reason to use the "all stuff goes into one method/function" is when your whole team works like that, and prefers that style. Or when you can't use decent tooling (but then navigating that big ugly function won't work either).
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.