“There are only two hard things in Computer Science: cache invalidation and naming things.”

  • Phil Karlton

In a recent project I worked on, there was an entire wiki page dedicated to naming code elements. It covered almost everything from class names to plugin names to variable casing. This wasn’t a document handed down from on-high, it was hashed out over time by experimenting to discover what worked, what was confusing, and the results were debated constantly in retros and pull requests.

Conventions would be introduced, discussed, implemented, and then deprecated when they no longer served their purpose. We didn’t call them standards, because they were constantly evolving. Despite the language of the document, they were a strongly held cultural guideline, and not a draconian requirement. It was possible to override the naming convention if you had a good reason.

Over time, combined with coding standards and some very persistent peer review, the code looked less and less like a composite of individuals coding styles, and more like a single coherent whole. This meant that any team member could pick up a piece of code, and spend less effort unravelling it and more adding to it. Adherence to the local conventions also reduced the cognitive load when writing code, as there were less decisions per line of code to work through.

“Tests of an object should be called ClassNameTest. ie; The test class for the WidgetFactory class should be called WidgetFactoryTest.”

The above convention meant that working out what unit tests were testing which classes became less an exercise in discovery and simply a case of opening the file that was always exactly where we expected it to be. This was one of the most commonly flouted conventions, because so many legacy classes were simply too large to efficiently test from one unit test. Had I worked on the project for longer, it’s likely that we would have written further conventions to handle this case.

“As per PSR 002, “Interfaces MUST be suffixed by Interface: e.g. Psr\Foo\BarInterface.”

In some cases, it’s possible and ppropriate to borrow and extend from upstream conventions. Building on top of these conventions will a lot of a headache, and reduces the friction between your code and the framework and heavily reduces the time for a new programmer to get up to speed. For example, if you are building an application based on Symfony, there’s already a rich lexicon for describing it’s various components, which you can import into your project wholesale. Symfony already does this in turn, by following PSR standards, and using common MVC terms like Controller for the classes called by it’s Routing components.

“The keyword ‘message’ must always prefixed by another noun to avoid confusion. ie; EmailMessage or JsonMessage.”

“The ‘factory’ keyword is reserved for classes extending CoreFactory.”

Part of our naming conventions to limit the use of some key words. Besides the obvious danger of using keywords from PHP itself, we also found that some words were so generic that we had to document against using them, unless they were prefixed by a more descriptive term or were only allowed within clearly defined parameters.

Before we finish up, it’s worth pointing out that bad naming conventions are almost worse than none. Carlos Pescio has an excellent post from titled Your coding conventions are hurting you where he demonstrates the use of some very poor naming. If you have this problem, and no documented conventions, it could be an opportunity to spur some healthy debate to clean up your practice.