Essay
Interface Naming Conventions
Naming is an important process that forces you to think about the very nature of things. This article discusses the PHP convention of suffixing interfaces.
At an earlier crossing on my development journey, many moons ago, it was considered best practice to use the “Hungarian Notation” for variables. You basically prefixed every variable name with a code denoting the data type that variable contained. This resulted in variable names like strName (a string) or u32Number (a 32-bit unsigned integer).
The reason why this was considered best practice was that you were dealing with low-level languages that were pretty literal when given commands by the developer. So, if you had a 32-bit variable, 32 bits of memory were reserved to contain the contents of that variable. If you copied the contents of a different 64-bit variable into that first one, the language would just allow you to do that… writing 32 bits of information into your variable and the remaining 32 bits into whatever happened to be stored immediately behind that allocated spot in the memory. You can be sure that that often resulted in very random bugs, being anything from spectacular to completely undetected until shipped. Take a look at the list of Types of Memory Errors for a nice catalog of memory abuse options.
So, with these languages, it was pretty much necessary to be aware of the exact technical implementations of what you were dealing with, to avoid greater harm. Clean, semantic code was of low priority if it made your computer explode in regular intervals.
Rise Of The Garbage (Collector)
Nowadays, most people will agree that the benefit of doing so is gone, as we have runtime checks, garbage collectors, and whatnot. That’s why Hungarian Notation is pretty much gone from modern OOP development. You will generally hear that you should code against interfaces, and not against implementations. Your code should not need to know implementation details, as that just causes unwanted coupling.
In a dynamically typed language like PHP, you are even encouraged to just ignore the type and let the PHP runtime figure it out (with varying degrees of success). So, surprisingly, trying to paint three dozen eggs with the following code will just work:
for( $egg = 1; $egg <= "12 eggs" * "3 dozen"; $egg ++) {
echo "Painting egg number ${egg}", PHP_EOL;
}
As you can see, PHP is very “flexible” with its typing system, so there’s no point in distinguishing between a 32-bit and a 64-bit unsigned integer anymore.
Code Against Interfaces, Not Implementations
One of the most important principles in software development (and one that takes years to properly assimilate) is to always “code against interfaces, not implementations”, with interfaces not referring to the PHP interface language construct, but rather to the concept of “abstract API that is agnostic of any specific implementation details”.
The point of this is to decouple every part of your code from the other parts of the code, as well as from any specific, short-lived implementation. For example, if your business logic is expressed entirely in terms of how it interacts with such interfaces, you can replace some or all of your infrastructural implementations without needing to change that business logic.
When you start really applying this principle consistently, you’ll end up expressing most higher-level logic in terms of how it manipulates the underlying interfaces, and you only ever have interfaces be injected as dependencies.
The logical conclusion should be that this conceptual “interface” then is the most important building block for you to communicate your intent to the system.
PSR-2 Suffix To The Rescue...?
A lot of developers have trouble thinking in terms of interfaces and APIs. The mind has a natural tendency of thinking procedurally, and you’ll need some time to get good at thinking at the object-oriented level.
That’s why folks often end up with a number of classes that are just whatever useful first implementation they could come up with.
When the PHP-FIG introduced the PSR-2 - Coding Style Guide, they included a bylaw (which is actually not part of PSR-2) that stated that all interfaces (and this time we’re talking about the actual PHP language construct) should be suffixed with the word Interface for all code that the PHP-FIG would release. This is why we have a Psr\Log\LoggerInterface instead of a Psr\Log\Logger.
This has lead many developers that were still struggling to entirely grasp the OOP paradigm to take a shortcut in their development “proficiency” and let most classes they create implement an interface of the same name, suffixed by the word Interface. This way, you can “code against an interface” without needing to think about the design of your code. Neat!
What's In A Name?
Naming a thing is a very important process. It forces you to think hard about the actual nature of the thing you want to find a name for. Also, the name brings with it an entire set of assumptions and expectations. If I name a class IconRenderer, you will probably know not to use that one to make a connection to an FTP server, even without looking up its functionality in the documentation. Similarly, if I name a class Class153A , you have no clue what that could possibly do.
Naming is an important process that forces you to think about the very nature of things.
So, the following way of naming classes and interfaces also carries a lot of semantic information:
class Thing implements ThingInterface { };
Because of the way the brain makes assumptions about the logical relation of these two based on the specificity of the words, this tells me loud and clear: “Thing is what we’re after, that ThingInterface is only there to support it.” - And that’s where we messed with our brain!
To properly follow the above-mentioned principle and general best practices, we need to make it obvious for our brain that the interface is what counts, and the actual implementation is just some noisy detail that could easily change from one week to the other:
class CurrentThing implements Thing { };
So, please take the time to let both of these snippets sink in and consider what their “appearance” suggests. You will probably agree that the perceived importance switches positions from one example to the next.
Hungarian Class Notation
I see this as a variation of the Hungarian Notation described above. It encodes a technical implementation detail of a given entity into the domain language that we should want to have as clean and clear as possible. And, yes, the word Interface is an implementation detail, as paradox as that may sound.
To make this consistent, you would also need to have names like ThingClass or $thingVariable. It provides us with information that might be accurate, but not relevant for the consuming code.
Consider the following code:
<?php namespace Example;
use Example\Message;
class MessageRenderer {
/**
* @var Message
*/ property $message;
/**
* Initialize a Renderer instance.
*
* @param Message $message The message we want to render.
*/
public function __construct( Message $message ) {
$this->message = $message;
}
/**
* Render the message.
*/
public function render() {
echo $this->message->toString();
}
}
Is Message a class?
Is Message an interface?
Should we even care?
Yeah, About Naming Being Hard...
I would argue that we should get rid of that Interface suffix and use the most meaningful name for the interface, not the class. But, what will the class be named then?
If we name our interface Thing, we need a more qualified name that provides additional information about our specific implementation for the class that implements Thing. Something like GenericThing or DefaultThing does not fit that requirement. Furthermore, it might mean that we will have a situation later on where we need to provide an alternative implementation. Our DefaultThing might end up not actually being the “default thing”.
Think About Your Design!
You will probably encounter three different situations:
- Your current code needs multiple implementations of a same concept.
- Your current code provides one implementation of a concept, but is meant to be extended by more specialized third-party code.
- Your current code only needs a single implementation, and there's currently no point in extending it.
Multiple Implementations Of A Same Concept
The first one makes it pretty obvious of how to define the naming. The interface is named after the concept and the actual implementations should be named after what makes it even necessary to have different implementations in the first place. So, as an example, if you need an EmailList that can work with different mailing list service providers, like MailChimp and AWeber, the names of the classes should reflect that distinction:
interface EmailList { };
class MailChimpEmailList implements EmailList { };
class AWeberEmailList implements EmailList { };
One Implementation Open To Extensions
The second situation is less obvious. But generally, the naming should reflect the way you intend the extensions/replacements to happen.
If the one implementation you provide is useful on its own, you should still name it like you did for the first scenario.
If the implementation is only meant as a starting point so that the extensions don’t need to start from scratch, you can call it something like BaseThing and should make it an abstract class.
If the implementation is just provided so that the code does not throw errors, but does not do anything useful at all, you should name it after the NullObject pattern: NullThing.
Single Implementation, No Extension Planned
This is the most interesting scenario. Most developers will agree that one of the most difficult things to deal with in software development is to correctly anticipate future requirements. In this regard, “not planning to allow extensions” does not necessarily mean that this won’t ever happen or be necessary in the future.
One of the most difficult things for a developer is to anticipate future requirements.
If you’re going with the PHP-FIG suffix, you’ll have a ThingInterface and code that relies upon that interface. Because, introducing a ThingInterface later on while all your code is programmed against a Thing would mean major refactoring. This is probably the reason why it is considered a “brainless trend” right now to just provide an interface for everything.

However, that’s where my naming recommendation provides a very nice perk: If your naming does not reflect the difference between interfaces and classes, your code doesn’t need to care!
Think about it for a second!
If you don’t plan for your code to be extensible, just go ahead and provide a simple class Thing {};. As that is not extended, the only places where you’ll encounter it is in type-hints and doc-blocks.
And after six months, your client might need to have two different things: one that runs from the database, and one that runs from the filesystem. That’s where the beauty of thoughtful naming comes in… As Thing still is the actual concept you’re dealing with, you can just turn the class Thing into an interface without breaking any existing code. And all of your existing code will happily accept that new DatabaseThing implements Thing, even though you never planned for that scenario!
Conclusion
As a developer, I spend most of my time interacting with the interfaces (in the API sense) that other parts of my code provide. Naming is a hugely important factor to consider and directly influences how effective my work is and how much I enjoy it.
The names of your objects should directly stem from your domain language and provide a clean representation of it. This will result in code that often is as readable as a normal English prose. The times where we need to add cryptic symbols and abbreviations or encode technical details into our entity names are long gone, and we should be glad about that!
I would love to hear your thoughts about this! How do you go about naming your interfaces? Let me know in the comments!