July 24th, 2024

API naming principle: If there is no direct object, then the direct object is the source object

It is a common practice that method names begin with a verb: widget.Toggle(), widget.Set­Color(), widget.Get­Associated­Doodad().

Often, the verb is followed by a direct object: widget.Set­Color(), widget.Get­Associated­Doodad(). The direct object is the thing that the verb operates on or produces. In the case of Set­Color, it is setting the color. In the case of Get­Associated­Doodad it is getting the associated doodad.

Sometimes, the verb is not followed by a direct object at all, such as the widget.Toggle() method above. In that case, the direct object is the source object: The widget. In the above example, widget.Toggle() toggles the widget.

All of this may sound obvious, but it’s easy to lose sight of this principle.

For example, a team proposed an API with a Widget­Notification and a method widget­Notification.Delete(). As written, it sounds like this deletes the widget notification itself, but the intention was for this to delete a notification listener. The methods for creating and deleting listeners should be named something like widget­Notification.Create­Listener() and widget­Notification.Delete­Listener().

As another example, the name of the Application­Data­Manager.Create­For­Package­Family method doesn’t say what it’s creating, so the assumption is that it creates an Application­Data­Manager. But that’s not what it creates. It actually creates an Application­Data object. The method should more properly be named Application­Data­Manager.Create­Data­For­Package­Family.

An exception to this rule is factory objects. The purpose of factory objects is to create things, so a Widget­Factory.Create() method is assumed to create a widget. But I wouldn’t complain if you called your method Widget­Factory.Create­Widget(), just to be clear about it.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

7 comments

Discussion is closed. Login to edit/delete existing comments.

  • Henke37

    Of course, if your factory creates many different kinds of objects, then you should probably have the methods state what they create.

  • Joe Beans

    MFC was really annoying about this. Class members would use full names that copied the API function names they wrapped, so you would end up with CWnd::MoveWindow() and whatnot.

  • Ray Koopa

    What I don’t like is boolean getters starting with “Get”. Like “Stuff::GetFrobnicating”. It sounds confusing compared to “IsFrobnicating” but that breaks starting getters with “Get” and get/set pairs in case you also have a “SetFrobnicating” (and “Get/SetIsFrobnicating” is not much better…).

    • Ian Boyd

      In COM you could mark certain methods as a "getter" or a "setter". The idea being that if you were in a language where an object supports properties you would then create a property based on the of the getter and setter names:

      - getIsFrobnicating
      - setIsFrobnicating

      which then gives you a property you can project into your langauge:

      <code>

      Or in Delphi:

      <code>

      So i would argue that IsFrobnicating should be a property. And if your language doesn't support properties, then you should be stuck with getIsFrobnicating.

      Read more
    • Antonio Rodríguez

      I think the difference is whether we are getting a property of the object or querying the status. For example, in an object that represents and article in a store or in an inventory, GetDiscountable() tells us about a (mostly) immutable property (the article admits discounts), while IsInStock() tells us about a volatile status (the article is in stock right now). Or, in a canvas, we could have GetObjectCount() (the number of objects in the canvas, which only changes when they get added or removed) and IsBusy() (which indicates that the canvas is redrawing itself at the moment).

  • Billy O'Neal

    Just as long as we aren’t making a `WidgetFactoryFactory` we’re all good.

    • Antonio Rodríguez

      Certain coffee-named language would one-up you with WidgetFactoryFactoryCreator.