问题
Is it clearer to sleep near a function call in a loop or in the function call itself? Personally I lean toward sleeping near the call rather than in the call, because there is nothing about "getApple()" that implies that it should sleep for some amount of time before returning the apple. I think it would be clearer to have:
for ( int i = 0; i < 10; ++i ) { getApple(); sleep() }
than...
for ( int i = 0; i < 10; ++i ) { getApple(); } Apple getApple() { sleep(1); return new Apple(); }
Of course, this would be different if the method were getAppleSlowly() or something.
Please let me know what you think.
Some additional information (also in comments below, see comments):
The wait is not required to get an apple. The wait is to avoid a rate limit on queries per minute to an API, but it is not necessary to sleep if you're only getting one apple. The sleep-in-get way makes it impossible to get an apple without sleeping, even if it is unnecessary. However, it has the benefit of making sure that no matter what, methods can call it without worrying about going over the rate limit. But that seems like an argument for renaming to getAppleSlowly().
回答1:
I would not put the sleep
into the function itself as long as the function name does not suggest that there will be a delay.
There might be other callers to the function in the future who do not expect it to sleep.
回答2:
The ideal is for one method to do one thing. Since getting apples and sleeping are two different things, I agree with you that it'd be better to have them be two different methods.
回答3:
I think this is a fair question, and it's very bad to put a sleep inside of a method where you might not know it's there (imagine trying to debug the slowness of your application in a few months when you have forgotten what you have done. The sleep should be only where you understand why it's sleeping (and presumably you have a good reason for that).
回答4:
This is a very interesting question and I think that both of your solutions are somewhat flawed. The "getApple(); sleep();" solution suffers from forcing each getApple() to pause before processing even if we will never again do a getApple(). The "sleep(); return new Apple();" solution has a similar overhead on the first Apple we get. The optimal solution is something like.
for ( int i = 0; i < 10; ++i ) {
getApple();
}
Apple getApple() {
long sleepTime = needToSleep();
if ( sleepTime > 0 ) {
sleep(sleepTime);
}
return new Apple();
}
/**
* Checks if last query was made less than THRESHOLD ago and
* returns the difference in millis that we need to sleep.
*/
long needToSleep() {
return ( lastQueryInMillis + THRESHOLD ) - System.currentTimeInMillis();
}
I would be inclined to get the whole "how long do I sleep to avoid the API throttle" thing behind some interface and make some other class wholly responsible for enforcing it.
来源:https://stackoverflow.com/questions/8660787/is-it-clearer-to-sleep-near-a-function-call-in-a-loop-or-in-the-function-call-it