What's In A Name?
In Object Oriented Programming it's considered to be good practice to write methods that only do one major job. One strategy you can use to ensure that your methods follow this practice is to write method names that describe what the method does. "Clean Code" by Robert C. Martin shares the following old but sound advice: "Functions should do one thing. They should do it well. They should do it only."
Sometimes it can be hard to tell whether the method only does one thing; it's at those times that I turn to the name for assistance. Can I write a descriptive name without the use of "and" or "or"? If the answer is no, it's possible that the method has multiple things going on, but a yes answer means I'm safe (or not being descriptive enough in my naming). It's okay if method names are long - Martin states that "A long descriptive name is better than a short enigmatic name." It's also good convention to use similar verbage for actions taken or abstract concepts such as get whenever retrieving a value, set whenever setting a value, or write whenever writing something to a file.
A few examples of good descriptive method names:
- WriteToOrderXmlFile()
- CreateNewCustomer()
- CreateDeduplicatedListOfShippingContacts()
- GetListOfPartProductsNotInSalesforce()
- CreateNewPartProduct()
Whatever you do, don't make the mistake of using a method name like DoStuff() to get started, then forget to go back and update it! If you can't think of a descriptive name, you just need to do a little more conceptualization first.
Don't be afraid to use multiple words to get your point across because a descriptive name can act as a replacement for a long descriptive comment (and won't require extra documentation updates if the method changes!) It should be clear to future you and any developers who come after you what each method does before they've even inspected it. Once they have gone to the method, it should do everything they would have expected from the name.
Class and variable names won't necessarily be as long, but they are no less important for clarity and readability. These names should be nouns such as Customer() or ShippedPartProduct(), and string partIdCSV or int customerAge. I usually choose to make List and Array names longer so I can better describe whatever set of data it's holding such as partProductsRetrievedFromSalesforce or itemIdsFromThisShipment.
Variable and class names that are unacceptable:
- int x = 42;
- bool trueFalse = false;
- var object = "xyz";
- HelperClass()
- myStrings;
Strategies To Help
I have developed a few strategies that help me with both good naming and ensuring my methods are all short and perform only one major function.
The first strategy seems like a no-brainer, but it took me awhile to actually figure it out:
Don't break out code into new methods until a full portion of code has you satisfied
By holding off on breaking out code until you've completed one or several portions, you allow yourself to essentially finish your thought process before moving on to the next thing. Much like you might refine an article after you've written your first draft, you can get your ideas out there and refine them into more suitably-formed sentences and paragraphs (e.g. methods) before releasing it into the wild. You also open yourself up to seeing the whole picture which means you have the opportunity to see where the most optimal splits can be instead of trying to conceptualize the splits as you're working through how to solve the issue.
Typically I will start with one method and have it named according to what it should do. I'll write all of the supporting code within this method, even though it isn't part of its job, and run my tests and whatnot. Once I'm satisfied with the results, I will look at each portion of the code I've written and break it apart into its bite-sized method portions. These will either be called by the method I wrote them in, or I'll move them out to be called from a position before or after the method I originally wrote the code in. Then I will run through my tests again, just to make sure the changes didn't break anything unexpectedly.
Consider whether you have multiple similar data sources
Are you using a database and another source of data such as Salesforce within your application? I like to indicate source of data in my variables because it's not uncommon that I'll be using an ItemID from our Item table as well as the ItemID from a Salesforce object. These two variables could have very different values, so it's important to keep them straight. A great example from my current code base would be partProductSerialNumbersFromSalesforce and partProductSerialNumbersFromDB. These lists will hold two different sets of potentially the same stored values - I compare them to determine whether a specific part in our database already exists in Salesforce to avoid creating duplicates.
I don't know whether this strategy is a best practice, but I will also occasionally include the actual table or stored procedure name if I am worried about any ambiguity. An example could be an application that updates two similar tables (let's say Shipments and ShipmentLines); these tables both have a UserDef field that must be updated and you want to avoid ambiguity in which one is being updated when. UpdateShipmentTableUserDef() and UpdateShipmentLinesUserDef() seem like perfectly reasonable and clear names for the methods that will update those fields. Obviously this would be overly wordy and unnecessary for most database updates, but I feel it certainly helps in the odd case like the example.
Is your method returning something?
In the case of a method that returns something, I opt toward using names that describe whatever is being returned. If I'm returning a comma separated string of item Ids, I may choose a name like CommaSeparatedPartProductItemIds(); or GetPartAccountIdFromSalesforce() if I'm running a query that returns the id of the Salesforce Account associated with a part. The important part is to indicate to the reader what the expected value being returned should be. If they're expecting an itemId and get back a customer name, they have a good idea where to start looking for that bug.
Grammar Lesson
Recently fellow dev.to writer @somedood released an article describing the details of naming grammar - essentially when you should be using camelCase, PascalCase, or SCREAMING_CASE. Check it out here:
Did I Miss Anything?
Do you have any awesome ways you make sure your names tell the story of your code? Any techniques to ensure good readability for those who may come behind you? I'd love to hear your own favorite naming conventions.
I'd also love to hear the worst names you've ever seen. I'm sure there's some funny ones out there!
Top comments (23)
Loved this, thank you!
I've been ranting about a method I found in one of our old libraries for the last couple of weeks.
GetIdById()
, really? What the heck is that supposed to even do?After digging into it and figuring out what it did I eventually renamed it to
GetPatientIdByChartId()
You write that it is a method, not a standalone function. So it belongs to an object, probably an object of type
Patient
. So what about calling itGetIdByChartId()
? It makes no sense to put information into a name that is obvious from the context.Because it was a standalone function. I tend to use method and function interchangeably when I really shouldn't.
Your rename makes a lot more sense than the original. "GetIdById" sounds like the code equivalent of trying to divide something by zero if you ask me!
Ha. I wish it had just contained
return id;
I once implemented model class Room, with supported classes RoomView and of course RoomService :-)
Nice article by the way, only thing I do not like in examples here is to use "list" or any other data typ word in names. I prefer simply to use plural nouns. So instead of getListOfProducts simply getProducts.
True, you're right. Using the variable will show clearly that it's a list - it's probably a bit redunant. Thank you!
I can see using the data type in the name for some weakly typed languages. Like if youโre not on the latest Python and type annotations are a pain, itโs nice to be able to see what youโre doing.
I have no excuse, I almost exclusively write in C#. sheepish grin
There's the industry-standard Javascript hackโฆ
var that = this;
I sometimes encounter
var self = this;
too, kind of annoying. I prefer to usemyFunction() { /* much stuff, very algorithm */}.bind(this)
if I am in an event handler for example, much natural to work withthis
even if the bind is a bit ugly!haha "much stuff, very algorithm" :)
Thankfully I don't need to deal with this very often at this point, but I agree with you. I'll keep this style in mind and try to remember to use it whenever I encounter it again!
I think, at my current level, I'd probably just sit there and cry (or laugh maniacally) for a few minutes if I came across this.
Thank you!
One of my favorites is when we spread a single giant method across multiple methods so that the names are
UpdateCustomer
,ExecuteUpdateCustomer
,DoExecuteUpdateCustomer
, and evenPrepareToUpdateCustomer
.Great article. Curious about one thing. Have one another question. For example :
getUserNearestLocation(user)
by going through it we can say it this function is going to return user location based on user information. If suppose if I have to add another parameter in function let's say hospitalgetUserNearestLocation(user,hospital)
now context has change name should begetUserNearestHospitalLocation
. My question is that if tomorrow I have 10 parameters. Then this function name might be very big if I keep adding parameter. Eventually function is returnuserLocation
based on parameter. In those cases what are good naming convention?Hello everyone,
Do you think that we should keep variable names the same in the method that is calling and in the method that is getting the value?
Let's say we have a main method in Scala:
@main def create_etl_project = {
println("Please enter the project name, avoid using blank spaces:")
val project_Name = readLine().replaceAll("\s", "")
Create_Project_Directories(project_Name)
}
def Create_Project_Directories(project_Name: String) = {
}
Could you please let me know what do you think would be a best practice?
Thank you in advance.
I saw a great one in a meeting today and had to share:
very.long.name.to.work.around.bug();
Totally agree with your point. Taking a step back and putting some thought on how to name a variable or a method can help your app have more SOLID foundations and save you hours of refactoring.
I feel like it saves me a lot of time when I do small refactoring as I go instead of waiting until I have a 6000 line method to break apart all at once. (not to mention the time saved debugging when the only clue you have is "thing broke in main()"
I am not talking only about breking long methods to smaller ones, but conceptual refactoring when trying to name a variable/method. Often times I find myself struggling with coming up with a name, only to end up deciding that my method needs to be a part of a better designed class (or to be extracted to a new class), even before start writing it ๐
Naming is so hard.
I'm also much better at pointing out problems in other developer's names in a PR than I am at naming things myself. ๐
What if the class name would be โCustomerโ and its method name would be โcreateโ.
Is it good,
I think a case like this would actually make sense, because I assume you'd do something like Customer customer = new Customer(); to instantiate your class... then you would be doing customer.create() whenever you called that create method. I hadn't considered the combination of classes and their methods - you made a really good point! Thank you!