Should functions be specific or generic [duplicate]
Possible Duplicate:
Specific functions vs many Arguments vs context dependent
So I've been developing for 3-4 years now, know a wide range of languages, know some impressive (to the small minded :P ) stuff.
But something I've always wondered; when I make a function should it be for a specific purpose, or should it be moulded to be re-usable, even if开发者_如何学编程 I have no need for it to be?
E.G:
//JS, but could be any language really
//specific
function HAL(){
alert("I'm afraid I can't let you do that, " + document.getElementById("Name").value + ".");
}
//generic
function HAL(nme){
alert("I'm afraid I can't let you do that, " + nme + ".");
}
//more generic
function HAL(msg, nme){
alert(msg + " " + nme + ".");
}
Yes, very simple example, but conveys the point I want to make. If we take this example, would I ever use it outside of the first? Probably not, so I'd be tempted to make it this way, but then common sense would (now) convince me to make it the second, yet I can't see any benefit of this way, if I know it's not going to be used in any other way, i.e. It's always going to use the input's value (Yes I would put that into a global variable normally).
Is it just a case of whatever I feel makes the most sense at the time, or should I follow the 2nd pattern as best I can?
In that particular case, I would write the first function for now (YAGNI, right?), and probably never need to change it. Then, if it turned out I did need to support alternate names, I'd make the current behavior the default, but allow an optional parameter to specify a name. Likewise with the message.
# In Ruby, but like you say, could be in anything:
// specific
def hal()
puts "I'm afraid I can't let you do that, #{fetch_name}."
end
// genericized refactoring
def hal( name = fetch_name )
puts "I'm afraid I can't let you do that, #{name}."
end
Typically, that's the approach I prefer to take: create functions at whatever is the most convenient degree of specificity for my current needs, but leave the door open for a more generalized approach later.
It helps that I use languages like Ruby that make this easy, but you can take the same approach to some extent even in Java or C. For example, in Java you might make a specific method with no parameters first, and then later refactor to a more generalized method with a "name" parameter and a no-parameter wrapper that filled in the default name.
A rule of thumb is that a function should have minimal side effects.
So, really, it would look something like this:
//By the way - don't call functions nouns. functions are verbs. data are nouns
void HAL(string s)
{
voicetype_t vt = voice.type();
voice.type(VOICE_OF_DOOM);
voice.say(s);
voice.type(vt);
}
A function shouldn't be just a series of statements to call them in some other context. It should be a unit of functionality that you want to abstract. Making a function to be specific is good, but making it context sensitive is bad. What you should do, is to use the generic way(last one) presented in your post, but provide the messages as constants. The language you use has some way to declare constants right?
In your example, I wouldn't make it generic. If a functionality can be used in many cases, make it generic so you can use it all the time without "copy, paste, make minor change, repeat". But telling the user he can't do that and adressing it as [contents of certain input field] is useful for only one case. Plus, the last shot is pointless.
However, I generally prefer my code to be as generic as feasible. Well, as long as the odds are I will need it one day... let's not violate YANGI too hard. But if it can be generic without hassle, why not?
In my opinion, functions should be genericized only to the extent that their purposes need to be. In other words, you should concede to the fact that, although we want to think differently, not everything is reusable, and thus, you shouldn't go out of your way to implement everything to be like that. Programmers should be conscious of the scope (and possibly the future development) of the product, so ultimately one should use their intuition as to how far to take generalizations of functions.
As for your examples, #3 is completely worthless as it only affixes a space between two strings and appends a period at the end--why would someone do this with a special function? I know that's only an example, but if we're talking about how far to generalize a method, something like that's taking it too far--almost to the point where it's just wasted LOC, and that is never something to sacrifice for the sake of generalizing.
精彩评论