Naming Things is Hard: Keeping Context in Mind

Well, look at this naming stuff turning into a series Smile

Nothing that you name in coding exists in a vacuum. It will all be used and referenced in a certain way, and this should inform the names you choose. Here's some examples:

Boolean Members

Boolean members on classes should usually be given names starting with 'Is' or 'Has' to indicate their boolean-ness, but boolean helper methods within a class should not. So for example:

if (CustomerIsEntitledToAMassiveDiscount(customer)) { // Do something } // ...

private bool CustomerIsEntitledToAMassiveDiscount(Customer customer) {
// Figure it out…
}

CustomerIsEntitledToAMassiveDiscount here encapsulates the logic which makes that decision. This makes the purpose of the if statement clear and provides an English-language description for the blob of logic which makes the determination. As a helper method of that type (which is the 'Encapsulate Conditionals' type from Clean Code, by the way), it will always be called by an if statement, and as such should be named in a way appropriate to that context, i.e. the context of being presented as the body of a readable sentence which starts with the word 'if'.

Alternatively, how would we name a property on Customer which encapsulated the same logic? The context is again informative; our property will still be used in if statements, but always via a member of a variable [probably] named 'customer'. That means it doesn't need the word 'Customer' in it. Which gives us…? customer.IsEntitledToAMassiveDiscount. Again, note that that makes a readable English-language statement when used as the body of a sentence beginning with the word 'if'.

'Parenting'

What's wrong with this picture?

public interface ICustomerService { IEnumerable<BankAccountDetails> GetCustomerBankAccountDetails(int customerId);

Address GetCustomerDefaultDeliveryAddress(int customerId);

IEnumerable<Address\> GetCustomerAddresses(int customerId);

int GetCustomerInsideLegMeasurementInCm(int customerId);

}

...or this one?

namespace LetteringRendering { public interface ILetterRenderingLetterRenderer { Letter RenderLetter(LetterRenderingData letterRenderingData); } }

Both examples have redundant qualifiers. Implementations of the interface in the first example will provide information (some of it quite personal) about Customers; they will be used via a variable named [probably] 'customerService'. The service therefore establishes the context of the operations as that of the 'Customer', and we don't need the word 'Customer' in every method.

The namespace and interface names in the second example establish their contexts as related to letter rendering; the interface name therefore doesn't need 'LetterRendering' in it. The interface method will be used via implementations named (can you guess?) 'letterRenderer' or 'renderer' or similar, and will be used to assign a variable named something like 'letter' or 'renderedLetter'; it therefore doesn't need the word 'Letter' in it - what else is an ILetterRenderer going to render if not a Letter? Similarly, I don't think the parameter name needs 'letterRendering' in it - it can simply be named 'data'; the context established by the method to which it belongs already tells us that it's related to letter rendering.

What about the LetterRenderingData type? I shall leave that to you to discuss with yourself - if you reach a conclusion let me know what you think with a comment Smile

This article is part of the GWB Archives. Original Author: Steve Wilkes

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.