OOP Principles – Best Practices for Method Names

object-oriented

class Boxer:

    def punch(self, punching_bag, strength):
        punching_bag.punch(strength)


class PunchingBag:

    def punch(self, strength):
        print "Punching bag punched with strength", strength

boxer = Boxer()
punching_bag = PunchingBag()

boxer.punch(punching_bag, 2)

No doubts that punch is a good method name in case of a boxer.
But is name punch also good for the method of punching bag?
In both cases I mean punch as a command (i.e. do punch).

Best Answer

A good rule of thumb is that method names should be verbs or predicates such that the object you call them on (self in standard Python convention, this in most other languages) becomes the subject.

By this rule, file.close is kind of wrong, unless you go with the mental model that the file closes itself, or that the file object doesn't represent the file itself, but rather a file handle or some sort of proxy object.

A punching bag never punches itself though, so punchingBag.punch() is wrong either way. be_punched() is technically correct, but ugly. receive_punch() might work, or handle_punch(). Another approach, quite popular in JavaScript, is to treat such method calls as events, and the convention there is to go with the event name, prefixed with 'on', so that would be on_punched() or on_hit(). Alternatively, you could adopt the convention that past participles indicate passive voice, and by that convention, the method name would be just punched().

Another aspect to consider is whether the punching bag actually knows what hit it: does it make a difference whether you punch it, beat it with a stick, or run into it with a truck? If so, what is the difference? Can you boil the difference down to an argument, or do you need different methods for different kinds of received punishment? A single method with a generic parameter is probably the most elegant solution, because it keeps the degree coupling low, and such a method shouldn't be called punched() or handle_punch(), but rather something more generic like receive_hit(). With such a method in place, you can implement all sorts of actors that can hit punching bags, without changing the punching bag itself.

Related Topic