TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Are short methods actually worse?

51 点作者 pdubroy大约 16 年前

25 条评论

calambrac大约 16 年前
Something that's important to remember about Code Complete (which is great, I'm absolutely not knocking it at all) is that it's written with languages like C, C++, and Java in mind. In C and C++ particularly, 'shorter function' might be a euphemism for 'clever function', hence the higher defect rate and increased difficulty to comprehend.<p>More expressive languages (by definition) shouldn't have the same length; if you're writing a 200 line Python method, you are most definitely Doing It Wrong.<p>Here are some of my rules of thumb for breaking things up (absolutely not independently arrived at, by any means):<p>- Loop bodies are good candidates for standalone functions.<p>- Everything in a function body stays at one tier of abstraction. If I find myself doing something at a lower level than the rest of the function, it's time to break things out.<p>- If I find myself using the word 'and' to describe what a function does, and it isn't pretty high up the abstraction ladder and primarily just driving calls out to other functions, it probably needs to get broken up.<p>- I'm not formal about it, but my mental metric for my code is to minimize 'total loc + total indentation * some constant', meaning I'm willing to trade loc to reduce nesting, to a point.<p>- I like functions to be no longer than a screenful. That's a max; most of mine are shorter than that.
ams6110大约 16 年前
I've seen many routines (functions, methods, procedures .. whatever) that are needlessly long due to overzealous use of the copy/paste technique. But once you eliminate that kind of stuff, I do agree that you can get to a point where you've abstracted too much -- and the actual thing you are trying to accomplish with your code becomes obscured.<p>I have not read these studies, but to me it seems that the defect rate could rise because it's no longer apparent what's interacting with what, and in what order. If I have to hop around to numerous different 5 line methods (often in numerous different source code files) it becomes very hard to intuit whether the code is "correct" or even have any idea what it's doing.
评论 #510102 未加载
评论 #510446 未加载
评论 #510404 未加载
评论 #510142 未加载
huherto大约 16 年前
It is not so much about the length of the method. But every method should do just one thing and it should be clear what it is. That makes code more understandable and reusable. Probably as a consequence methods are shorter.
评论 #510178 未加载
评论 #510157 未加载
评论 #510340 未加载
neilk大约 16 年前
I wonder if the same stats apply to stateful versus stateless languages.<p>I'm working a lot with PHP these days (not my favorite language) and for historical reasons we even avoid the use of objects. I've noticed that even experienced practitioners in the PHP world write super-long functions. Forget 200 lines, more like 1000 or even 2000. When I try to refactor these, I usually find that I start causing worse problems, passing values around all over the place, using globals and so on.<p>It seems to me that if your language is relatively underpowered, a long method can help contain the messiness.
评论 #510331 未加载
评论 #511373 未加载
nickh大约 16 年前
In my experience, there's a "sweet spot" for how much functionality a method "should" have.<p>If a method is "too short", it: * may result in methodA calling methodB calling etc., increasing complexity; * may not be readily apparent how it fits in to the problem that's being solved.<p>If a method is "too long", its: * complexity increases; * ease of testing decreases; * frequency of reuse decreases.<p>Obviously, some methods have little functionality, and thus require very few lines. For the majority of the other methods, though, I tend to keep them below 25 lines. If a method grows past 15 lines, I examine it to see if there's any functionality that feels like it should be broken out into a separate method.
curtis大约 16 年前
I think focusing on method length is focusing on the wrong thing. Some of the worst long methods I've seen weren't bad because they were long, they were bad because they had about eight or nine levels of nesting. When a method ends with<p><pre><code> } } } } } } } } </code></pre> you know you've got a problem. Breaking such a method up into smaller methods would make each shorter, but the big win would come from eliminating the deep nesting.
评论 #510398 未加载
russell大约 16 年前
I have two perspectives. Back in the 80's, I and two others developed a word processor. We aggressively refactored the code do that the average function length was less than 10 lines. The code was smaller, faster, and supported more users than any of out competitors. The key was there were only 3 of us, who knew the code thoroughly.<p>Fast forward 20 years and I an flying solo on a vast JBoss/Spring?Struts/Hibernate project. I just added a feature with 6 lines of functional code, along with another similar piece in a DAO to get the data out of a database. Essentially, I was mapping a key to an inventory item to a key to a document. The feature was about 80 lines because of Java baggage and Spring injections. In addition I had to modify another 10 files of interfaces, implementations, struts actions, DAO's, a jsp, struts xml, and spring xml.<p>Another place where there is a functionless proliferation of small routines is caused by the java method overloading model. A common case is to have a method with several parameters, most of which have common defaults. You often end up with 4 signatures, but can easily end up with more if you support, say, the name of an object as well as the object itself.
geebee大约 16 年前
I haven't read the studies referenced here, but I'd be concerned about mistaking correlation for causation here. Long methods may or may not be bad, but the temptation to write them usually arises when the programming task is already complex. The error rate may reflect the complexity of the task, rather than the approach (long methods vs short ones).
评论 #510090 未加载
评论 #510078 未加载
10ren大约 16 年前
I was also struck by seeing actual studies cited, in the usually fashionable, religious and cliquey schoolyard of software development.<p>I wonder why there aren't any studies more recent than 1991. That's 18 years ago! Before Java, before C#, before Ruby, before JavaScript, before PHP (C++, Perl and Python had already started).<p>Perhaps because everyone involved has a barrow to push (including academia), no one has an interest in undertaking impartial and objective research - after all, it might give the wrong answers.
chollida1大约 16 年前
One idea I have about why 200 was chosen is that back then the languages that were commonly used weren't as expressive.<p>You can often say the same thing in Python or Ruby in fewer lines than you can in Cobol, Fortran or C.<p>Or put another way, of those 200 lines of Cobol maybe 1/2 to 3/4 are setup code that the language makes you write inorder to be able to do what you want vs say a Python where a smaller percentage of the code is overhead vs doing what you set out to do.
评论 #510300 未加载
tel大约 16 年前
Attributed to Einstein:<p>"Everything should be made as simple as possible, but not simpler."<p>(Also, is it just me or does a result like "long methods had to be changed least" seem both rather spun and probably two-edged?)
评论 #510239 未加载
njharman大约 16 年前
I try hard to stick to these "rules" for determining method/function size.<p>1) Keep methods/functions shorter than one "screenfull".<p>2) If I code the same or substantially the same logic twice, it gets extracted to it's own method/function. [I also do the opposite, if method/function is used once I remove it and inline logic.]<p>3) Logic extraneous to the problem at hand gets extracted into method/function/language feature such as macro's or decorators if it takes more than a couple lines. (logging, safely opening a file, wrapping in a try/catch, etc)<p>Less often:<p>1) Logic that needs it's own unit test gets extracted.<p>2) If a comment precedes a block of code saying what it does. extract the code, name method/function after the comment, delete the comment.<p><pre><code> # load the exception records from exception file bla bla bla for 10 lines... exceptions = load_exception_records_from_file(fh)</code></pre>
sofal大约 16 年前
If the methods have a clear purpose with well-defined inputs and outputs and no side effects, then I think the trade-off is generally in favor of smaller methods. Once you introduce side effects, longer methods then have the advantage of showing you all the side effects in one place.
评论 #510236 未加载
jderick大约 16 年前
I think these results may be misleading -- most the methods I know of that are &#62;200 lines are implementing some kind of large case statement. Often, these are auto-generated files, not hand-coded ones. So it may not be a fair comparision.
评论 #510162 未加载
silentbicycle大约 16 年前
This depends a great deal on the language used.<p>Breaking a large function apart into several smaller pieces makes testing them easier, and (even more importantly) lets one <i>name</i> them. A well-named function is generally better than a block of code in a function with a one-line comment before it, IMHO. (Of course, there's nothing stopping you from giving all of functions names like doThatStuff() besides the eternal scorn of your peers.)<p>It can be annoying in languages that require a lot of type annotations just to declare a function and have poor support for nested functions, though.
djahng大约 16 年前
I wonder why shorter methods would be inversely correlate with errors. Maybe it's, to some extent, similar to why so many people get confused by pointers: they lose track of where they are in the program.
stewiecat大约 16 年前
One aspect this piece doesn't mention are unit tests. I've found that writing short to-the-point methods helps with testability(?). I just wrote some unit tests the other day for a 100+ LOC java method. 300+ lines of test code to setup the massive amount of dependencies and go through all of the if- and for- statements. Would've been a lot easier if it was broken apart into smaller discreet units.
code_devil大约 16 年前
Methods should do ONLY ONE thing.<p>Example: A program to withdraw money from a Bank Account.<p>getBalance() // Does One Thing<p>if(getBalance &#62; withdrawAmount) {<p><pre><code> subMoney() // Does One Thing </code></pre> } else<p>{<p>Print ("Insufficient Funds");<p>}<p>Other thing, I would like to point is that if you are making the code of your function visible, then it should be properly documented and readable. The compilers do a really great job of Optimizing the code, so there is no need to make the code look smart and have no one understand it. The only place I would put real smart code is when I am coding in assembly. In that situation, there should be really good documentation explaining the reason of your smartness.<p>Example:<p>A = 4<p>B = A X 2<p>[Smart Code: Right Shift A, but it's not always obvious that you are trying to multiply by 2 here, unless you have an explicit comment]
jimrandomh大约 16 年前
The correct size for functions is as short as possible without adding unneeded complexity, and no shorter. A piece of code deserves to be a function if you can coherently explain what it does using only terminology from the problem domain, or if having it significantly simplifies other code. Otherwise, leave it inline.
maurycy大约 16 年前
It depends on a programming language.<p>In more dynamic programming languages it is easy to create a method that deals with abstract objects, eg iterative ones, and does not have to hold too much knowledge.<p>To say nothing about easiness to test a short method that does only one thing.
awt大约 16 年前
I find long methods hard to read, especially if they have a lot of conditional logic. Recently, I encountered some long methods that had very generic names, such as "processData." One of the advantages of smaller functions/methods is that you can give them better, more accurate names since their scope is more limited. If one is unfamiliar with the code, this is a tremendous help. There are few things as daunting as 100 lines of code with 10-20 different variables all in the same scope. In such cases, I have to load it all into my head and break it into smaller pieces to understand it anyways.
keefe大约 16 年前
Short answer? No.... each method should have a clearly defined concern separated from the concerns of other methods with an obvious, documented and tested contract
gord大约 16 年前
The classic counterexample is not using 'i' in for loops, vis -<p>for(int nInnerLoopCounter; nInnerLoopCounter&#60;nMaxInterations; nInnerLoopCounter++) ...<p>Seriously, had this in a formal coding standard, you never want to work in those places - so make sure you go straight from university to a {lisp|ruby|python|linux|YC}startup.
psranga大约 16 年前
Forcing yourself to write short methods forces you to design your solution cleanly. I wasn't a fan of short methods, until I observed a master programmer's (who was also a co-worker) work for a while. After I adopted this style, I've found my own code improving. Ymmv.
time_management大约 16 年前
I prefer small-function programming, but I think there are needed caveats.<p>Code reuse and easy testability are obvious upsides of small-function programming but, most importantly, interactive development is easier and more fun. You can test and play with the code while you write.<p>One downside on the human-readable end of things is that small-function code can easily devolve into spaghetti code if it's not done right. You actually have to think about <i>where</i> your functions are in the physical file, and have them logically organized, in order to have legible code.<p>Appropriate line length of a function varies wildly by programming language. In Lisp or Haskell, a 25-line function is usually considered a "monster" and should, if possible, be broken up, since a lot is happening in those 25 lines. Whereas a 25-line Java function is nothing unusual.