Naming Things is Hard: Method-Naming Patterns

Here's a few of the method-naming patterns I've come across / developed / adopted.

Indicating the Result of a Failure

If this method didn't find any customers, what would you expect it to return?

public IEnumerable<Customer> GetCustomers()

If you said 'an empty enumerable', we'd expect the same thing - an empty enumerable has become a standard kind of NullObject return value for these sorts of cases.

What about this method? If it didn't find a customer, what would you expect it to return?

public Customer GetCustomer(int customerId)

Hmm. I've not come across a standard return value for these cases, so that's not so simple, is it? Might it return null? An empty Customer? Might it throw an exception? We'd have to look at the method body or run tests to find out.

To clear up this ambiguity I've taken to naming these sorts of methods like this:

public Customer GetCustomerOrNull(int customerId)

public Customer GetCustomerOrThrow(int customerId)

…appending an indication of what will happen in a failure condition to the end of the method name. In the absence of checked exceptions the latter example also declares that it might throw an exception… of some sort.

Maybe It'll Work, Maybe It Won't

If you've ever had an operation which may or may not succeed and which yields a value if it does, you've very likely seen the Try[Something] pattern before:

Enum.TryParse("Registered", out customerType);

int.TryParse("265", out age);

DateTime.TryParse("2014/12/31", out dateOccurred);

I've adopted this naming convention for similar circumstances. For example:

User currentUser;

if (TryGetCurrentUserDetails(HttpContext, out currentUser))
{
    // Do something
}

// ...

private static bool TryGetCurrentUserDetails(HttpContext currentHttpContext, out User user)

This being a common pattern in the base class libraries lends it a familiarity which I think out-weighs concerns over using out parameters - recognising the pattern in the method name tells you how to use the method and what its true / false return values mean.

Involving the First Parameter

Straight to some examples:

SayHelloTo(customer);
SayHelloTo(currentUser);

// ...

public void SayHelloTo(Customer customer)

public void SayHelloTo(User user)

The pattern names a method in such a way that a combination of the method name and the first parameter passed to the method form a simple statement of what the method does. This works particularly well with overloads (as in the example) where the difference between the methods is the parameters. Note the aid to readability - I find SayHelloTo(customer) reads much easier than SayHelloToCustomer(customer). I've seen this pattern used in various places, e.g.  factory methods like user = User.For(userData), and like it a lot.

Print | posted @ Wednesday, December 31, 2014 9:00 AM

Comments on this entry:

Gravatar # re: Naming Things is Hard: Method-Naming Patterns
by Johannes at 12/31/2014 12:46 PM

Great article, thanks. I really like your naming conventions.
I just want to add a concern on using out parameters: You can't use them in `async` methods.
This may become a problem as more and more methods in the BCL are available `async`-only.
Gravatar # re: Naming Things is Hard: Method-Naming Patterns
by Steve at 1/1/2015 2:09 PM

Thanks Johannes, that's definitely worth keeping in mind :)
Gravatar # re: Naming Things is Hard: Method-Naming Patterns
by Richard Hill at 1/1/2015 6:24 PM

There's another problem with out parameters: they prevent the interface being fluent.

"Maybe It'll Work, Maybe It Won't". There is a actually a concept in functional programming called a "maybe type". This post suggests an implementation in C#: http://twistedoakstudios.com/blog/Post1130_when-null-is-not-enough-an-option-type-for-c.
Gravatar # re: Naming Things is Hard: Method-Naming Patterns
by Steve at 1/1/2015 6:40 PM

If I've understood what you mean by 'fluent' correctly Rich, I don't think out parameters *prevent* a fluent interface, but they certainly do make it a lot more awkward to use.

Jon Skeet wrote a blog not too long ago (which I now can't find) on the TryBlah(out value) pattern, with a different solution using something like the Maybe Type. I really only use it in situations like the example - where I have a series of checks to do which yield values and I want to bail out of the method early if the checks fail.

Good to hear from you - happy new year! :)
Gravatar # re: Naming Things is Hard: Method-Naming Patterns
by Enzi at 1/4/2015 12:38 PM

I'm really fond of ReSharper's Code Annotations: http://www.jetbrains.com/resharper/webhelp80/Code_Analysis__Code_Annotations.html

Instead of calling a method GetCustomerOrNull I just annotate it with [CanBeNull]. Callers that do not null-check the result will get a compiler warning (or hint) that the object might be null.
Gravatar # re: Naming Things is Hard: Method-Naming Patterns
by Steve at 1/4/2015 5:21 PM

ReSharper's annotations are certainly a useful tool for enforcing null-awareness, but for me the naming convention is simpler and more immediate, as well as being language-, tool- and environment-agnostic, so I wouldn't use [CanBeNull] instead.
Post A Comment
Title:
Name:
Email:
Comment:
Verification: