Maxim from the book SmalltalkBestPracticePatterns by KentBeck.
Bad identifier:
quicksortVector(vector & v)Good identifier:
sortVectorIntoAlphaOrder(vector & v)Bad identifier:
collateCustomerNames(vector & v)Name services after what they do, and postpone the why until the point of usage. There's a great "a-ha" when you see "collatedCustomers = sortVectorAlphabetically(customers)" in the source; the "a-ha" is lacking when you see just "collatedCustomers = collateCustomerNames(customers)". If you want to abstract the "what", you should still have sortVectorAlphabetically for code reuse, and only redefine collateCustomerNames to not use it when change comes. -- PanuKalliokoski
Discussion
Bad identifier:
sortVectorIntoAlphaOrder(vector & v)Good identifier:
collateCustomerNames(vector & v)The first recants its own internal implementation. Hint: Courageous programmers expect to replace implementation at the drop of a hat. The second advertises why you should call the function, thus promoting reuse.
[RefactorMe: Please link to & from relevant pages.]
See IntentionRevealingSelector for the original name of the pattern. IntentionRevealingNames is more general.
I think the naming above violates ModelViewController unnecessarily. sortVect(v, cmp) is the model, collateCustomers(cust) is the view. -- PanuKalliokoski 13 May 2004
Now that I've reflected a little upon this, I've come to the conclusion that not only this violates ModelViewController, it is also a major hindrance of code reuse. People seem to confuse the how vs what question with what vs why. Almost everybody agrees that you should not name things after how they do something. But the above example does not say how the vector is sorted; it is not how, but what it does. And this is a good naming principle. Naming after the why (as the "good" identifier above) makes the service unusable elsewhere, because customer collating "owns" the name.
Rather, name services after what they do, and postpone the why until the point of usage. There's a great "a-ha" when you see this in the source: collatedCustomers = sortVectorAlphabetically(customers); the "a-ha" is lacking when you see just: collatedCustomers = collateCustomerNames(customers); if you want to abstract the "what", you should still have sortVectorAlphabetically for code reuse, and only redefine collateCustomerNames to not use it when change comes. -- PanuKalliokoski 20 Jul 2004
Proclaimed Daniel Longest from the mountaintops:
> The following is probably silly but I've struggled with it. If I have a > 'pure' container, in this case a vector, that will be of fixed size and > keep things in sorted order, is fixed_sorted_vector a reasonable name or > is this too long?Name things after their intent. Do not name them after their implementation. "Ordered_Set" is the intent; "sorted_vector" is the implementation here.
Name things with complete words, not ugly acronyms, if they have a scope larger than a small block. Don't worry about typing them, or line length. Learn to copy-n-paste quickly, and I'd keep a right column limit of 130 characters these days.
> What if the intent is to be a sorted vector? Is that still also the > implementation and ordered_set is preferable?Of course you intend to implement. But you have to defend the name, outside the implementation, against the day when the implementation changes. It could change to a map<>, or a fixed_map<>. If the name reveals the intent (per Kent Beck's Smalltalk Best Practice Patterns) then those reading it know more about how they can use it. "InterfaceOrientedProgramming?" again.
Telling them the implementation hints at how they can abuse it.
--PhlIp
I worked on a C++ project where another programmer needed a new class to represent an object that had as its principal members a state (enabled or disabled) and an object name (plus a few domain-specific operations on them). Of all the names one could conceive for this class, I think "BoolStr?" is probably the worst, and naturally, what he chose...