We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Miljar • 10 years ago

When I read this post yesterday, I had all these strong opinions which came down to disagreeing with the "no suffix needed" part. After a good night's sleep, I can understand your point of view. I could even agree with it, given time, and changing my expectations.

I, for one, am so used to having the *Interface suffix that it would alter my entire perception my PHP code, if I changed it. Small example: When typehinting for LoggerInterface, I expect an object which has at least a certain set of methods implemented. Don't care about the implementation. But when the typehinting would be Logger, I expect a specific implementation.

So for me, reading the code, and reading "Interface" creates a certain expectation. If I weren't to use the *Interface suffix anymore, I'd not really know what to expect from the object anymore. This would make it harder for me to understand my code again after a couple of months.

David Pesta • 8 years ago

Here is a practical reason why you shouldn't suffix your interface names with "Interface" or prefix them with "I" and should just name them the same as if they were a class: your classes may someday become interfaces or (less often) vice versa. That's right. Your program at first might only need to have basic understanding of Person. Over time, your program becomes more sophisticated and needs to differentiate between different types of Person (PoliceOfficer, Mechanic, Politician, etc), thus you convert your Person class into an interface that serves a whole bunch of different subclasses. By naming your interfaces just like classes as a convention in your project, you do not need to rename "Person" to "PersonInterface" all over your application when this happens and furthermore you find yourself thinking about interfaces properly along the way: They represent the essential nature of the thing a receiving method is interested in at the level of abstraction that it cares about--whether it is a class or an interface is an abstraction detail that the receiving method should not worry about--therefore creating a more perfect abstraction. Less effort for a better abstraction is a win-win.

CCCrazyPanda • 9 years ago

I suffix my interfaces because it makes them easier to identify in my IDE/editor. If I have multiple tabs open, I can see the title of the file and know immediately which one it is. I can also Ctrl+P (or editor-equivalent) the interface I want to load much more easily.

And frankly, it makes the code much easier for newer developers to understand. If you have a file sitting in a folder called `Jump.php`, it's not immediately clear to another developer that this is an interface that can (and needs to be) implemented somewhere.

There's nothing wrong with suffixing 'Interface' on your interfaces, and 'Trait' on your traits.

At the end of the day, a file name still needs to clearly describe what it is.

Mathias Verraes • 9 years ago

So why don't you suffix your classes with Class?

CCCrazyPanda • 9 years ago

It's implied by process of elimination. If it's not suffixed with interface or trait, then it's a class. I suffix factories with Factory. I suffix factory interfaces with FactoryInterface. I suffix repositories with Repository. I suffix controllers with Controller.

Mathias Verraes • 9 years ago

The point, is that in a good design, it is not important to know whether something is an interface. If the contract is for an Order object, my client code doesn't care whether Order is a class or an interface, as long as it behaves as expected. See some of the other comments here.

Stijn Vannieuwenhuyse • 10 years ago

I think Mathias' point is that in client-code you don't need to know if you're dealing with a specific implementation or an interface. You just want to know that the "unidentified concrete class" you're receiving as an argument, has the expected contract: does it implement a certain interface? (cfr. Interface Segregation Principle)

mnapoli • 10 years ago

I 100% agree with everything here, except maybe the "Nameable" part.

class Product implements CastsToJson, HasTimestamp

HasTimestamp is a question, it would be a great method name, but I don't think it suits a type name.

Think of:

if ($product instanceof HasTimestamp) {
}

That's doesn't make any sense: "the object is has timestamp"... It's not a type.

"The object is an animal", "the object is a repository", "the object is serializable". "The object is timestampable" may not be Shakespearian, yet it means what we all think it means.

Mathias Verraes • 10 years ago

If you remove the syntax, and keep only the essential words, it does work: "if($product HasTimestamp)"

It fits with the idea of signal/noise ratio: http://cyrille.martraire.co...

PHP's syntax is not really suited for expressing these sort of things elegantly. So it takes some imagination to reorder words. Imagine for example, that method parameters took the typehint after the variable, as is the case in some other languages:

calculateAge($tweet HasTimestamp)

I'm not against Fooable naming per se, but I do dislike when people slap -able on words without spending 30 seconds of thought on a better name. It all comes down to obsessing over naming and SRP. It makes everything else easier.

mnapoli • 10 years ago

"if ($productRepository Repository)" or "if ($object Animal)" doesn't make sense. "instanceof" is not unnecessary syntax, it's like "if", it has a meaning, it's part of the sentence.

Same goes for:

buy($item Product)

The relation is "IS", it's a type, I mean $object has the type Product, it *is* a product, or $object *is* a repository.

Still, I understand it's not a big issue, I don't want to start a flamewar ;)

also, related: http://stackoverflow.com/a/...

Stijn Vannieuwenhuyse • 10 years ago

This is because PHP chose a word for 'instanceof'. Of PHP would have chosen a symbol like for the assignment (=), you could read it as you want. "Suppose" a colon would represent 'instanceof', you would have:

if( $dog : Animal ) { ... }
if( $tweet : HasTimestamp ) { ... }

which we would both understand.

So Mathias has a point in identifying keywords like 'instanceof' as noice, I'd rather have my own interpretation for such things.

Mathias Verraes • 10 years ago

The Pilot is a great analogy! I'm not proposing to make all interfaces use the HasX convention. The naming depends on what makes it understandable, and on the nuance of the relationship: is a, has a, behaves as a, is able to, ...

Florian Klein • 10 years ago

I agree with this, most of the time, "able" suits correctly the fact that an object has the capacity to do things.

Florian Klein • 10 years ago

Or, you could use a (maybe) more shakespirian version:

(has)AbilityToReturnTimestamp
// or
(is)AbleToReturnAndSetTimestamps

:)

Mathias Verraes • 10 years ago

Heh :-)
$object instanceof Product
=>
$object toBeOrNotToBe Product

Florian Klein • 10 years ago

... that is the answer. :)

Stijn Vannieuwenhuyse • 10 years ago

May a remark that in plain English we don't often say:

Timestampable or
HasTheAbilityToReturnTimeStamp

but more often, we do say:

CanReturnTimeStamp or
HasTimestamp or
KnowsWhenItHappened
...

Just listen closer to the conversations you have with your co-workers from time to time ;-)

David Thalmann • 10 years ago

If I may comment it section by section :)

In my company, we usually do it this way (as for example with db adapters):

Interface: "AdapterInterface" (Namespace: /Project/Db/)
Default Implementation (abstract!): "Adapter" (Namespace: /Project/Db/)
Implementations: "Mysql", "Oracle", ... (Namespace: /Project/Db/Adapter/).

So if we'd take your first example:

/Project/Package/TranslatorInterface - Interface
/Project/Package/Translator - Abstract, common implementation
/Project/Package/Translator/XML- Implementation
/Project/Package/Translator/Cache - Implementation

The "-able" suffix is only used for behaviour changing classes we can inject in the event live-cycle of a class, e.g. "Logable", "Timestampable". We know its ugly, but we think it's more a behaviour thing than a contract one.

Respecting the contract is a must anyway, IDE's can help and if I remember correctly, some languages don't even allow this.

Good point on the interface "size". But one thing to think of: did you not implement the method because you did not use it (so it's maybe the wrong interface?) or were you just too lazy (default implementation could help you)?

Roles: good example for fast prototyping. In production you could use a factory or abstract factory - if you need the flexibility.

I mostly agree on the "One implementation" part, it comes down on how you program (for you, contract, prototype or ever lasting genius implementation) and if you may have style-guides which enforce you to write interfaces or not.

And lastly: aware. In my opinion, aware is the wrong direction for a contract. Aware means (at least how it's used), that you have a protected property (e.g. a container, dispatcher, event manager) and a respective setter. But it does not offer you any functionality - you can't retrieve it - in the public API because you have not defined a getter. So in my opinion it does not belong in the public API.

Maybe (but I did not think it through, just from the top of my head) Traits are the better way to share such a functionality, as you only use it inside of your implementation and even if you expose some methods to the public API (the setter), you don't "pollute" your classes and interfaces hierarchy.

Greetings! :)

Marco Pivetta • 10 years ago

I honestly don't agree with the `Interface` bit. The problem is not really readability to me, rather than the convention people should follow. There's two main ways to do that in my opinion:

* Translator and TranslatorImpl
* TranslatorInterface and Translator

The suffix is a necessary evil to actually force people to do less decisions on naming. We had that problem while starting developing ZF2, with lots of classes and a lot of confusion, and just going one way (we picked the *Interface suffix) or the other made it much easier to handle any future problem/discussion raising from that. It's also predictable naming, which is really nice if you have a large code base to read.

As for the fact that it's less readable, or that we require an *Interface, I think it's no big deal. It is as readable as the code constructs that surround it.

If the readability that much of a real problem, then I suggest going the *Impl suffix, assuming nobody will yell "you're too java-ish!" (yes, there are still people that think java is bad... poor souls.)

Mathias Verraes • 10 years ago

Hey Marco,

Thanks for commenting, this is exactly the sort of debate I hoped to get :-)

If you have TranslatorInterface, and you want to support both XML and Json, which one gets to be called Translator? And what is the other one called?

Marco Pivetta • 10 years ago

Why would you need to put one of those in a more privileged name? The only thing that is privileged is the interface... Implementation names are not that relevant.

Mathias Verraes • 10 years ago

That's what I'm getting at. The interface is the privileged thing. It's the thing you will work with most of the time (in a well-factored app), and it should get the best, most expressive (!= readable) name. Picking a generic naming convention to avoid making decisions, is the opposite of what, in my opinion, good naming is about.

Marco Pivetta • 10 years ago

The problem with that is that anyone reading the codebase won't be able to differentiate interfaces and classes by just looking at the directory structure.

As said, the problem is really about organizing the structure. Reading an additional *Interface in the code won't kill you, and is an acceptable evil.

If you have a generic implementation for a component that you expect to be implemented also in userland code (again, I'm talking as a framework coder, not as an application coder), then SomeFooInterface aids everyone and is less confusing.

Less decisions -> Less thinking -> less mistakes -> happier coders.

That's the entire point in it. Having all the things work together like an English sentence is fine, but English itself is a quite crappy language, and sometimes we can really just be confused by it.

Therefore, adding suffixes and prefixes is perfectly fine to make things more clear. Even more if the user base is larger, since otherwise you really risk to run into consistency problems, and nobody will like BC breaks for the sake of consistency :-)

mnapoli • 10 years ago

> The problem with that is that anyone reading the codebase won't be able to differentiate interfaces and classes by just looking at the directory structure.

How is that a problem?

Also, I think you are thinking too much in the POV of the developer. As a user of a framework or library, I don't want to typehint against "*Interface", that makes no sense to me.

Take for example the Logger PSR. Now I think it was a mistake naming it LoggerInterface, because everywhere in my code I inject and use a LoggerInterface. For me, the user, I ask for a Logger. Should I get a "Monolog Logger" or anything else, I don't care.

In the end, if, for example, in an MVC framework, you have (random names)

- DispatcherInterface
- Dispatcher

It's actually that the framework declares an interface (in the broad meaning of the term, think of it like a PSR) and consider its implementation as the "Dispatcher". That's not good, there's no point of having an interface then, if nothing is supposed to exist except this implementation.

On the other side (random example):

- Dispatcher
- ZendDispatcher (or Zend\Dispatcher)

It's very explicit: ZF defines a interface for a Dispatcher, and then it proposes its own implementation. But the important thing here is `Dispatcher`.

The implementation is Zend's one, but it's clear that there could be others.

And me, as a user, I only care about using `Dispatcher`. In my DI config, I'll configure that I use Zend's implementation.

**TL/DR**: either code against an interface, either don't create one. If you create an interface, expect there could be several implementation, and your implementation is just *an* implementation.

Daniel Ribeiro • 9 years ago

I get what Marco is talking about the naming convention. Maybe it's not a problem, but it's hell a lot easier to mass-browse inside an IDE using *Interface...

Marco Pivetta • 10 years ago

The directory structure is actually a problem when you have a large code base to browse. Good naming conventions only help when reading a project.

I am thinking from the POV of the developer because that's the ONLY POV that matters. Code is seen by developers, not by managers.

The fact that some implementations are just the interface name with the chunked off *Interface bit doesn't really matter. As said, only the interface is what matters, and FooInterface won't bring you to suicide :)

As a matter of fact, the ZF code base became much more readable, manageable and easier to patch (from the perspective of a contributor). I don't think a religious belief on naming conventions can beat that. As said, it's a necessary evil, if even an evil thing.

I'd like to hear about a use case where the codebase became easier to work with by removing the *Interface suffix. Then I'd eventually put the thing under discussion again :-)

mnapoli • 10 years ago

The POVs I'm talking about is developer (of the framework) and user (of the framework), so the user is a developer ;)

And for him (the user of the framework), LoggerInterface makes no sense.

I understand your point though about the necessary evil.In my experience, we switched to BlogRepository and DoctrineBlogRepository recently at my company (i.e. no more *Interface). Type-hinting against BlogRepository is awesome, but maybe that's my OCD talking ;)

And at first, we were like "ok, let's get rid of *Interface, but how should we name our implementations? BlogRepositoryImpl?". And then it struck us that it was actually a Doctrine specific implementation. And now most of the time I notice that either there's something that makes your implementation specific (and replacable by something else), either there's no point in having an interface.

However I get that with libraries/frameworks, it's not always easy. For example with PHP-DI, I have a Factory and FactoryInterface. The interface exists only to leave the possibility to the user to override the default one. And in reality (at least in my head), the Factory implementation is actually the "PHP-DI Factory implementation", as opposed to the "user's Factory implementation".

Marco Pivetta • 10 years ago

I still see no point in why having a Logger is better than having a LoggerInterface :)

I'm also having DoctrineYaddaRepository in my codebase, but it's not a reason for having the interface called Repository. Nobody is going to notice that one :)

Putting the argument "you don't need an interface when yadda yadda" aside, there's only positive things coming from the *Interface suffix so far (all described above).

Daniel Ribeiro • 9 years ago

Also, the ability to mass-search inside an IDE using *Interface...

Marco Pivetta • 10 years ago

Sorry, noticed this is a different thread =) Missed the point completely: my bad.

cordoval • 10 years ago

maybe the interface prefix come from Germans, although @ocramius is Italian but he lives in Germany. In German the longer the word the more meaning. So in a way I want to agree with him, but I am really sold to DDD and to make the software work for you rather than you working for the software which means (you are the boss and english can be your tool to tame complexity). The developers will eat and get accustomed to what you give them. If you give them bad practices that is what they will learn.

Loïc Faugeron • 10 years ago

You're not limited to the choice between suffixing interface by `Interface` or by suffixing implementations by `Impl`.
Take the example of the Repository pattern: in your component you will have a generic interface that is expected to be implemented into userland code :
* interface : `Repository`
* implementation : `DoctrineRepository`, `InMemoryRepository`, `ArrayRepository`, etc

Those don't form an english sentence, but still carries useful information (you don't have to read the implementation code to know what they do).

Marco Pivetta • 10 years ago

My entire point is about _LIMITING_ it :)

I don't want the naming freedom, it's a mess. We've already been there, and don't want to go back ;)

Mathias Verraes • 10 years ago

You're making it sound like there are only two options: strict naming convention, or total naming freedom. In my team, we put a lot of effort into naming things. We always model a problem first with two or three people, and obsess over the names. We only start writing code when we are confident the names are good. It makes coding so much easier.

And still it happens that we later have a new insight and rename something. Even if that means that we have to change hundreds of things manually, we'll do the effort. Bad naming is the worst kind of technical debt, because it creates bad mental models.

So do we have naming freedom? Yes, any name can be valid. No, because if you pick a bad name, your code will not get merged until it's fixed.

I understand that for ZF2, the decision has be made a long time ago, so even if you did want to change it, it's not possible before 3.0. In any case, I think we should agree to disagree on the suffixes :-)

Marco Pivetta • 10 years ago

I never said there's a need to change that. Additionally, I'd argue that the "we put a lot of effort into naming things" is exactly what you want to avoid. For every effort you put into it, you get more work out on the other side if something doesn't fit your needs after a year or so.

Why would I need to worry a week about naming a thing while I can focus on actually building it having a guideline on how to do it?

A restriction makes things so much easier :)

There's actually the old RFC at http://framework.zend.com/w... (the markup is broken, since we don't use confluence anymore) if you want to see a complete list of reasons why this strictness was embraced.

Errata: I didn't mean you have to put less effort in naming things, but you shouldn't be wasting your time re-inventing your naming every time. Naming _IS_ important, so I wasn't saying that we should put less effort in it, but *waste* less time in it - pre-made decisions help :)

Mathias Verraes • 10 years ago

If we don't agree on the importance of obsessing over naming, we're not going to agree on anything :-)
Naming is at the core of what I think good programming is about. Please don't call that "a religious belief", because I base this on experience and literature (Evans 2003 for example)

Marco Pivetta • 10 years ago

I'm not saying naming is irrelevant, I'm saying that having a guideline for it makes things easier/faster for all sides.

I also spend a lot of time in deciding how to name stuff, since I will spend time maintaining it later on and since I also want to be able to read what I wrote.

What I mean is that browsing a code base where anything could be either an implementation or an interface is very confusing.

Mathias Verraes • 10 years ago

I work with large codebases and it has never confused anybody. My team knows to program to an interface.

Marco Pivetta • 10 years ago

Your team may be kickass then :)

You can't think like that with a wider audience in my opinion.

I honestly get confused by my own code base if I start removing the suffixes.

Having to re-open a file or looking up the implementation for a type hint every now and then is annoying and counterproductive, and decreases readability (for me). Even just having suffixed the name of a class/interface in a tabbed view in an IDE helps a lot.

Add that to the fact that I spend a lot of time reviewing code and that I'm not the worst coder on the planet (I hope so at least!) and you see that the sentence "My team (.*)" becomes an edge case :)

Loïc Faugeron • 10 years ago

I don't see how suffixing interfaces is limiting the "naming freedom": you still can implement RepositoryInterface with YaddaYadda (note that I didn't even suffixed my implementation with Repository).

IMHO naming the implementation YaddaYadda is as bad as naming it Repository: it doesn't communicate the details of the implementation (is it a doctrine implementation? Is it an in memory one?)

Marco Pivetta • 10 years ago

What I mean is getting rid of being able to name the interface what you want. For example, by appending *Interface to any interface name, it becomes automatically a noun. Seems quite straightforward to me. As mentioned above, implementation names don't matter at all: for those, a specific and descriptive name is perfect :-)

alessandronadalin • 10 years ago

Translator (int) and BaseTranslator (class): wherever we go there will always be some imperfection :(

Mathias Verraes • 10 years ago

You could probably solve that better without inheritance, so you wouldn't need a Base anyway :-)

alessandronadalin • 10 years ago

Not really: what I mean is that you probably need to have a base class, else the Translator word is free to be used for your interface and we're all good :) In that case the compromise is on the class' name

Stijn Vannieuwenhuyse • 10 years ago

I like to do it this way: https://gist.github.com/sti... ;-)

Deryk Wenaus • 9 years ago

I think you have a typo in the Namable section above. The correct word is "Shakespearable" ;)

Florian Klein • 10 years ago

Just to give some more reading (people already thought about that): http://programmers.stackexc... and http://stackoverflow.com/a/...

I tend to agree on avoiding suffix for interface. As said in the second link, a Truck is not an ITruck, neither a TruckInterface.
Talking about that, It always killed me to see folder structure containing "classes" (You don't say ?).
Do you create a folder named "Folder" to say there will be folders in it ?
Same for classes, and same for interfaces.

I agree that **consistency** is what matter the most at the end, and as pointed by David Thalmann or Marco Pivetta, if you put rules, it will greatly simplify naming **consistency** and mental model. That's what matter the most. And if your interfaces are not suffixed, but are consistent and people understand they are interfaces, no problem.

Florian Klein • 10 years ago

Very cool article.

steven_rosato • 7 years ago

This article has made my team switch completely. I cannot agree more! Though I still find it hard to find the proper naming, it is worth it. Still struggling a bit about how to name traits now. I do not use traits much, but when used in conjunction with small interfaces that define an aggregation it gets weird to find the unique name, since the interface does not really suggest multiple implementations, but rather a marker for cross-cutting concerns.

Mathias Verraes • 7 years ago

The trick is to not name a trait for what it _is_, but for what feature or capability it provides. If you want to add logging to an object, instead of calling it LogTrait, call it Logging. I guess you could even do AddsLogging, or LoggingCapability, but that probably gets weary fast. In any case, don't try to find a single generic rule for naming them, just answer case by case "what does it really do?". If you can't answer that question, it's a design smell.