There’s a common joke in computing, usually attributed to Phil Karlton, Tim Bray, and Leon Bambrick:

"The two hard things in computer science: cache invalidation, naming things, and off-by-one errors."

It's a funny joke, but by throwing naming things (components of your software; views, controllers, classes, files, etc.) into the same category as cache invalidation it makes a serious point. One that most of us accept without thinking, but one that I propose is very slightly off the mark.

To the uninitiated, picking out names may seem like a strange thing for a technician to be doing, and after learning that correct naming is perhaps the most time-consuming task of a project, the question "what does it matter anyway?" is quite common; usually asked in exasperated tones by someone feeling the pressure of a looming deadline.

Yet, as computing is about abstractions, giving good names to things is hugely important. When sitting down to develop a new application, the developer is starting the task of teaching the computer about concepts it doesn't understand. If the project wants software which will receive payment for goods and services, all of these terms need to be defined with a name – specifically Payment, Goods, Services, and even what it means to ‘receive’.

This stands true for all the things, all the way down. Is the page in the web application where payment is received the payment page, payment manager, payment receiver, payment details collector, charge authorisation system, PayPal controller, or PayPal manager? What about a name for the button on the page? No, the other button! Does that conflict with a name used somewhere else in the application? What are the pros and cons of these names? Why is one better than the other? What are the consequences of picking a bad name?

Thankfully, there are some answers to these questions. In the simplest of terms, the answer is to think about scope.

1) Get the abstract concept defined.

2) Consider carefully the scope of the thing that is being created.

3) Name it appropriately to its scope. 

4) Repeat.

This is where the premise falls down. It’s not naming things that is hard, it’s deciding the scope for things that is difficult and time-consuming.

This is true because a project starts with a high level of abstraction and becomes more detailed. ‘Take payment’ is a high-level concept, which includes several lower-level concepts such as: getting payment information from the user, processing a charge, and knowing a payment is received. Each of these themselves incorporate lower-level components, and so on.

The solution, in broad terms, is to focus on the details from the start. It is wrong to call it a Payment Manager because there’s no one single thing that manages payments. Instead, there are lots of small things which each play their own part. Once a developer can no longer move to a lower level of abstraction, and when it can be said that the thing has only a single responsibility, then a name can be chosen for it.

To phrase this another way: focus on the reasons for change. Once a thing is split up enough that each of its components have only one reason to change, and that it has only a single responsibility, then a name can be chosen for it.

Know the scope to easily name things, then profit from software which is easier to understand, utilise, test and maintain.

That is my fundamental understanding of the concepts of separation of concerns, the first of the five principles of object-oriented design (single responsibility, open-closed, Liskov substitution, interface segregation and dependency inversion), microservice architecture, and modern computing in general. Yeah, okay, there is a lot more detail to it than that, but understanding at a high level is important too. Keep It Simple...