In Nette, interfaces were named with the letter
I at the
IRequest). A couple of years ago, an extremely
slow and long term process began, which quietly while maintaining backwards
compatibility is getting rid of these prefixes. How exactly is this happening
The Conventions Around Us
Nette has used the convention of prefixing interfaces with the letter
I since its inception. It has never made any distinction in
abstract class names. In other frameworks (e.g. Symfony, CakePHP, Zend or PSR)
you may see a different convention, using the
Psr\Cache\CacheItemInterface) together with the
Abstract prefix for abstract classes (e.g.
Psr\Log\AbstractLogger). Finally, there are libraries (e.g. Laravel
or the PHP system library) that do not distinguish interfaces or abstract
classes in any way (e.g. the
interfaces, or abstract class
If we were to look outside the PHP world, the
I prefix is used
for example by C#, whereas in Java or TypeScript the names are not
About a decade ago, when the Nette DI, the heart of all modern and cleanly
designed applications was created, I fully realized that distinguishing
interfaces and abstract classes, whether by prefix or suffix, was a huge
mistake. But at that time, the framework was already celebrating 5 years of
existence and it was impossible to change the interface names without causing a
colossal BC break. To maintain consistency, I continued to use prefixes for
Nette, but abandoned them for all other projects. (Nette was still a monolith at
that time, but e.g. Nette Tester was a separate project and you won't find the
prefix for interfaces there).
However, I was still looking for a way to painlessly drop the
prefix. I see the differentiation of interface names as such a significant
mistake that it was worth putting a lot of effort into correcting it. Especially
since the framework is taken by programmers as a example of clean design.
The reasons are the subject of a separate article Prefixes
and Suffixes Do Not Belong in Interface Names.
How to Say Goodbye to the
After a few years I found a way to give
I away. Quietly and
with full compatibility. It was a process planned many years in advance, which
started with the release of Nette 3.1.
Usually, it was enough to simply rename the original interface (e.g.
Mailer) while creating an alias
IMailer) to make both versions work. Along with this, I added
“hidden” code to the source file that only the IDE and Composer can see. It
makes autoloading work for the alias as well, and forces the editor to strike it
deprecated in the code with a note that the non-prefixed version
should be used. So all existing code works unchanged, while the programmer is
led to prefer the new version.
In some cases, I did not rename the interface because the plan was to change
it (e.g. the new
Nette\Security\UserStorage is different from the
Nette\Security\IUserStorage and both can be used at the same
time as part of the transition), or because I am planning a different solution
In some cases, removing the prefix was not possible because the name was
already taken. This is for example the case of
SimpleIdentity needs to be taken first as a successor to
Identity and the name will be freed. Such a thing has to be spread
over several major versions and thus many years to be truly painless. But there
is no hurry.
So in Nette 4 only
IResponse will remain prefixed, as a reminder of a former time. And
but I'm not sure if their existence is useful at all. Aliases will continue to
work, of course.