Using one method with constants as parameters versus several methods
In Kent Beck's Implementation Patterns, one can read
"A common use of constants is to commun开发者_运维百科icate variations of a message in an interface. For example, to center text you could invoke
setJustification(Justification.CENTERED)
. One advantage of this style of API is that you can add new variants of existing methods by adding new constants without breaking implementors. However, these messages don't communicate as well as having a separate method for each variation. In this style, the message above would bejustifyCentered()
. An interface where all invocations of a method have literal constants as arguments can be improved by giving it separate methods for each constant value."
Why is this? Generally when I'm coding and I notice that I have a couple of similar parameterless methods that could be reduced to just one, with an argument, like in the following example,
void justifyRight()
void justifyLeft()
void justifyCentered()
I'd generally do just the opposite of what Kent advices, which would be to group it into
setJustification(Justification justification)
How do you usually handle this situation? Is this totally subjective or there is really a very strong reason that I can't see in favour of Kent's view of this matter?
Thanks
File access methods usually have parameters regarding read/write mode, whether to create non-existing files, security attributes, locking modes and so on. Imagine the amount of methods you'd have if you'd create a separate method for each valid combination of parameters!
I've highlighted the biggest argument in favor of separate methods; it's fail-safe because you have strict control over the API. The caller cannot pass in invalid arguments, or invalid combinations of parameters, if you don't expose such parameters. This also implies less complex parameter validation.
However, I'm not in favor of this practice. API's should be well-designed and should change as little as possible. Kent Beck on breaking API changes:
One advantage of [parameterized methods] is that you can add new variants of existing methods by adding new constants without breaking implementors.
His argument in favor of separate methods is:
However, [parameterized methods] don't communicate as well as having a separate method for each variation.
I disagree. Method parameters can be just as readable. Especially in combination with named parameters, a feature which is supported by several languages. Besides, separate methods would result in a cluttered API.
I suppose it's subjective. Some may argue that justifyLeft is clearer than justify(Justification.LEFT) Collapsing it all into one method may result in a nicer API - less clutter - and the mode can be stored in a variable and simply feeding it to the single setXY method (with different methods for each, you'd have to decide which to call depending on the value manually). Therefore I usually prefer this way way. Though it's usually just:
void justify(Justification justification) {
switch(justification) {
Justification.RIGHT: this.justifyRight();
Justification.LEFT: this.justifyLeft();
Justification.CENTERED: this.justifyCenter();
}
}
Of course this is only advisable when all these methods are very closely related.
精彩评论