A Talk About Naming Things

19 Dec 2017 in Tech

A Talk About Naming Things, by Shawn McCool and Mitchell van Wijngaarden. Presented at the DPC Uncon in 2015.

Naming things is cultural.

WordPress names things differently to Drupal, which names things differently to the Java ecosystem. This is a good thing, as it means there’s scope to change things

On Interface

When the section on interfaces came up I knew what was coming. I’m totally sold on this already. It doesn’t matter that you’re working with an interface. All that matters is that you’re working with an object with certain public methods available. How it accomplishes the task is nothing to do with you - so long as your collaborator respects your contract (and you respect it’s public API e.g. don’t call public methods that aren’t in the interface) then everyone’s happy.

Instead of adding Interface to differentiate your interface from your implementation, make your implementation more specificPaymentProcessor and PaymentProcessorInterface doesn’t tell me anything. StripePaymentProcessor and PaymentProcessor lets me infer that we’re processing payments via Stripe

On Exception

Although I’m totally on board with dropping Interface, I’m not too sure about dropping Exception. I think this is more about gut reaction than any educated decision.

We know that the thing we’re working with is an exception based on context

  • throw new MemberAlreadyRegistered

  • catch (MemberAlreadyRegistered $e)

  • class MemberAlreadyRegistered extends \Exception

This one will be a more difficult habit to shake, but I’m going to give it a go

Levels of cohesion

All code has to live alongside other code. Names help us understand how things relate to each other.

At the lowest level, all we have is a block of code. There's no context, just the raw facts about what it does. Take this code for example:

php
$i = -1;
while ($i < 0){
$callback($i);
}

We have no idea why it loops forever, or if that's intended. It could be a bug for all we know.

That's why we have functions, which provide context

php
function loopForever() {
$i = -1;
while ($i < 0){
$callback($i);
}
}
function loopTwice() {
$i = 2;
while ($i > 0){
$callback($i);
$i--;
}
}

Related functions are generally grouped in to a class, which indicate that they're related to each other

php
class Order {
public function getItemCount(){}
public function markAsImportant(){}
public function markAsShipped(){}
}

Usually I'd expect the next level of cohesion to be a namespace, but Shawn makes a good point that it's actually the file containing the code. It's a convention in the PHP world that each file only contains one class (due to PSR-0 and PSR-4) but this is just a convention. In other languages there's no such convention. Shawn mentions C# and Scala as examples of when you place exceptions relating to a class in the class itself.

Finally, we group things by namespace. Some projects namespace by type e.g. Repositories\PolicyRepository, Repository\MemberRepository etc. I've been guilty of doing this in the past. Do we really think about everything in categories?

Instead, group things by domain - Policies\PolicyRepository, Members\MemberRepository etc. This allows us to have Policies/Policy, Policies\PolicyValidator etc. You can easily view everything related to Policies in the Policies namespace. As an added bonus, it's easier to refactor this functionality - rename namespace or extract in to another package

Conclusion

Programming is about zooming in on what’s actually happening. Removing artefacts such as Interface and Exception help focus on the name of things. Grouping code by domain rather than purpose helps us build a model of the real world system that we're trying to emulate.

PS

As it was an uncon talk, Shawn mentioned a few board games to break things up. I’ve played Formula D and Dead of Winter and enjoyed them both a lot. Ca$h 'n Guns has been on my list for a while (and who can say no to a game where Rafael always dies?)