I recently migrated an Entity Framework model from EF6 to EF Core/.NET 6. This was made considerably more difficult by the fact that the original developers had not taken advantage of Entity Framework’s conventions. Not only that, but a few small conventions changed between the two versions. And it would have been so easy had properties been named correctly.
It got me to thinking about just how important naming conventions have become. Automation such as Infrastructure-as-Code, code generation tools, and your own automation based on reflection: all of these are based on having predictable names. But simply being predictable is not enough. It is also necessary that you be able to reconstruct the name the same way every time. And finally, you should probably be able to type it, or fit more than one identifier on a line of code. This was the main flaw of the model I was working with: the names were so descriptive that following a naming convention led to excessively long names, so abbreviations were made that broke the convention.
It seems that a middle ground needs to be taken. I grew up on C, where identifiers were typically one- and two-letter abbreviations that probably only meant anything in the mind of the author. Calling C code a “technical specification” is probably pretty generous given the lack of descriptive nouns and verbs within the spec. A webcomic I saw a long time ago, and alas cannot find now, makes the point that well-written code _is_ a technical specification. The characters were discussing how great it would be if it were possible to create a specification detailed enough that a computer could write a program. And yet, that is what software developers do every day – write higher-level constructs that specify the software to the point that a compiler can create executable machine language. That sounds like a specification to me.
So let’s treat it like one. Instead of the glory days of C where programmers competed with each other to create the most obfuscated code possible, let’s use the code also as a document that can clearly trace back to business requirements written in business language. Optimizing for readability should be a thing! Or at very least demanding that developers create readable specs that can be easily reviewed by an architect or other technically-capable businessperson.
That’s where the Ubiquitous Language of Domain-Driven Design comes in. If the business calls something by a name, we should also use that name in our specification. It will allows us to clearly trace our code back to our business requirements. It will allows us to desk check business rules without wondering what certain variables refer to. Indeed, a modern language like C# is fluid enough that you can express thoughts in very readable fashion. A well-organized, well-named code base is easy to work with. You can use your IDE’s code completion features much more easily if you don’t have to guess multiple names.
Other naming conventions that are important are the Entity Framework names I mentioned above. For example, a property named Id
is always going to be considered the primary key for an entity. Additionally, a property named <Entity>Id
is also considered the primary key if Id
doesn’t exist. Foreign keys can be inferred in much the same way. While annotations are provided in EF Core to allow you to override the default behavior, it’s so much easier if you work _with_ the conventions rather than _against_ them.
Terraform will get you thinking about names too, in terms of input variables. All of our names are going to look programmatic, because they are concatenations of input variables. Still, we want to be careful that names don’t get too long, since our cloud provider is going to have limits. So, what many have adopted is a variant of Hungarian notation (made popular during those glory days of C/C++!) where common abbreviations are adopted by those working with the technology. For example, a resource group will always lead to a -rg
suffix. A container repository -acr
and Kubernetes cluster -aks
.
So, I guess I’d make the following recommendations about naming in your own programs:
- Descriptive is good. Long is bad. Find a balance between the two. Hungarian notation can really help with this.
- It’s still ok to use one- and two-letter abbreviations for temporary/local variables
- Think of names in terms of input variables and how you can combine them programmatically as Terraform does.
- Use Ubiquitous Language from business requirements when available
- Take the time to do Domain-Driven Design when not available
Remember that you are not just writing software for an end-user. You are also writing documentation of business processes and rules for an organization. When you win the lottery, the organization still needs to be able to understand what has been written and what the current state of the business is. So, it is important that some conventions be put in place and enforced via peer review.