Interface Names and Suffixes

737 views
Skip to first unread message

Jeremy Lindblom

unread,
Dec 4, 2012, 12:17:10 AM12/4/12
to php...@googlegroups.com
In the discussion about the common Log interface, there was a little derailment about what to name the Logger interface. The current implementation by Jordi (@seldaek) uses the name LoggerInterface. There are some who do not like the use of the "*Interface" suffix, and prefer either the name without the suffix or a derived name with a "*able"-type suffix. We should discuss this as a group because which naming method we choose will also become a precedent for future code we publish as a group.

The two main questions we need to discuss are:
1.) How do we name interfaces? With the "*Interface" suffix or some other way?
2.) Do we apply the same naming rules to traits, abstract classes, or anything else.

Two things we should do to help us make this decision are:
1.) Consider what the majority of the projects under the FIG banner are doing right now.
2.) Discuss pros, cons, opinions, etc.

I'll let someone else own #1, since I don't have time to do this at the moment, but I will voice my opinion to start things off.

I am in favor of the "*Interface" suffix for interfaces (as well as the "*Trait" suffix for traits). Here are my reasons (Note: some of these have already been voiced by others in the other thread):

1. Eliminates name collisions between interfaces and concrete implementations of the same family of classes.
2. Facilitates predictable file/class names. Example: LoggerInterface describes the interface for a logger object; Logger would be a concrete implementation of the LoggerInterface.
3. Differentiates a concrete implementation from a contract/interface when it is being used. If you see `if ($thing instanceof Logger)`, you might assume that only one class may satisfy that condition. If you see `if ($thing instanceof LoggerInterface)`, you could safely assume that multiple classes could satisfy that condition (i.e., anything implementing that interface).
4. (imho) Seems more appropriate than adjective-like "*able"-type names now that we have traits. The name of an interface should reflect that it is something that defines an interface for a object (e.g., LoggerInterface), not that it is a description or attribute of an object (i.e., HasLogger, Countable).
5. Follows existing practices of suffixing class types like Exception classes (e.g., InvalidArgumentException).
6. Follows existing practices observed in other programming languages. Not that we have to copy them, but it shows that it is a popular decision.
7. Follows existing practices observed in many of the projects within the php-fig group.

--
Jeremy Lindblom
PHP Software Development Engineer & Web Application Developer
Amazon Web Services – AWS SDK for PHP

@jeremeamia • https://github.com/jeremeamia

Ryan Parman

unread,
Dec 4, 2012, 10:32:46 AM12/4/12
to php...@googlegroups.com
+1

--
Ryan Parman
Geek. Writer. Music Lover.
http://ryanparman.com

"Illiteracy will not be defined by those who cannot read and write, but by those who cannot learn and relearn." — Alvin Toffler







--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to php-fig+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Larry Garfield

unread,
Dec 4, 2012, 12:36:25 PM12/4/12
to php...@googlegroups.com
Did you mean to +1 in the voting thread, which says mostly the same thing?

--Larry Garfield

On 12/4/12 9:32 AM, Ryan Parman wrote:
> +1
>
> --
> *Ryan Parman*
> Geek. Writer. Music Lover.
> http://ryanparman.com <http://ryanparman.com/>
>
> "Illiteracy will not be defined by those who cannot read and write, but
> by those who cannot learn and relearn." � Alvin Toffler
>
>
>
>
>
>
>
> On Dec 3, 2012, at 9:17 PM, Jeremy Lindblom <jerem...@gmail.com
>> *Jeremy Lindblom*
>> PHP Software Development Engineer & Web Application Developer
>> Amazon Web Services � AWS SDK for PHP
>> @jeremeamia <https://twitter.com/jeremeamia> �
>> https://github.com/jeremeamia
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "PHP Framework Interoperability Group" group.
>> To post to this group, send email to php...@googlegroups.com
>> <mailto:php...@googlegroups.com>.
>> To unsubscribe from this group, send email to
>> php-fig+u...@googlegroups.com
>> <mailto:php-fig+u...@googlegroups.com>.

Jeremy Lindblom

unread,
Dec 4, 2012, 12:49:41 PM12/4/12
to php...@googlegroups.com
Ryan and I are on the same project. We haven't cast our vote yet (waiting for another team member to respond to our internal inquiry). I think Ryan probably just +1'd my post since he felt bad that it got mostly ignored. :-/ Thanks Ryan!

--
Jeremy Lindblom
PHP Software Development Engineer & Web Application Developer
Amazon Web Services – AWS SDK for PHP
@jeremeamia • https://github.com/jeremeamia

Looking for work? Help bring the "cloud" to developers. AWS needs
- JavaScript developers: http://www.amazon.com/gp/jobs/173568
- Ruby developers: http://www.amazon.com/gp/jobs/160651
- Python developers: http://www.amazon.com/gp/jobs/173569
- Systems engineers: http://www.amazon.com/gp/jobs/174287

Let me know if you are interested!


On Tue, Dec 4, 2012 at 9:36 AM, Larry Garfield <la...@garfieldtech.com> wrote:
Did you mean to +1 in the voting thread, which says mostly the same thing?

--Larry Garfield

On 12/4/12 9:32 AM, Ryan Parman wrote:
+1

--
*Ryan Parman*
Geek. Writer. Music Lover.
http://ryanparman.com <http://ryanparman.com/>


"Illiteracy will not be defined by those who cannot read and write, but
by those who cannot learn and relearn." — Alvin Toffler
<mailto:jerem...@gmail.com>> wrote:

Amazon Web Services – AWS SDK for PHP
@jeremeamia <https://twitter.com/jeremeamia> •

https://github.com/jeremeamia

--
You received this message because you are subscribed to the Google
Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com

To unsubscribe from this group, send email to

For more options, visit https://groups.google.com/groups/opt_out.



--
You received this message because you are subscribed to the Google
Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to

For more options, visit https://groups.google.com/groups/opt_out.



--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to php-fig+unsubscribe@googlegroups.com.

guilher...@gmail.com

unread,
Dec 5, 2012, 12:49:33 AM12/5/12
to php...@googlegroups.com
I'm pro to not suffix interfaces and traits, but rather use *-able like naming convention.


To unsubscribe from this group, send email to php-fig+u...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Guilherme Blanco
MSN: guilher...@hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada

guilher...@gmail.com

unread,
Dec 5, 2012, 1:14:41 AM12/5/12
to php...@googlegroups.com
The argument used for interface suffix by considering only 5 interfaces in PHP, as well as wrong naming does not justify the adoption of interface suffix. Why wouldn't it apply to all structure types then? UserInterface, UserClass, UserAbstract and UserTrait?

Let's take then another OO language and make a comparison. Java SE only have 1 *-"Interface" suffixed (and it is not because it's an interface, it's actually an abstract class, called NetworkInterface), but I'm quite confident that there's more than 5 interfaces there.
What's the problem then? The problem always come when the interface provides a context that is also reused by a class.
Let's consider an example:

interface User {}
class User implements User {} // I know this is wrong

Java solves the problem by adding a suffix Impl when it means a concrete class. That way, it would become:

interface User {}
class UserImpl implements User {}

Some people may disagree, but I tend to remove type (interfaces in Java are types) context from names.
People will come and ask why I left Abstract out. Because it's not a type, it's a class modifier. Of course I do advocate to not use Abstract as a prefix, but it may happen under the situation where:
- An interface with this name already exists
- A trait with this name already exists

Talking about traits, it should follow the same convention of interfaces.
That way, we simplify the code.

So, grouping the rules:

- Interfaces are named over their objectives, without any prefixes or suffixes;
- A trait follows the same rules as interface. It enforces appending a "Trait" suffix only if an interface with the same name already exists;
- An abstract class follows the same rules as interface. It enforces "Abstract" prefix only if an interface with the same name already exists;
- A class follows same rules as interfaces. It enforces "Impl" suffix only if an interface with the same name already exists;

That doesn't mean you are forced to write "Impl" classes, but rather think twice when naming your interfaces. Let's consider another example:

interface Customer {}
class CustomerImpl implements Customer {}

In reality, with a deeper look over the problem, you may easily solve by:

interface Identity {}
class Customer implements Identity {}

I'd quote what one guy wrote down at mockobjects.com[1]:

"

Sometimes we see code with classes that are named by adding “Impl ” to the single interface they implement. This is better than leaving the class name unchanged and prefixing an “I ” to the interface, but not much. A name like FooImpl is duplication, it says exactly the same as implements Foo , which is a code smell. We would not tolerate such obvious duplication elsewhere in our code, so we ought to refactor it away.

It might just be a naming problem. There’s always something specific about an implementation that can be included in the class name: it uses a bounded collection, it communicates over HTTP, it uses a database for persistence, and so on. A bridging class is even easier to name, since it will belong in one domain but implement interfaces in another: for example, SnipersTableModel (a user interface class) implements SniperListener and PortfolioListener (from the application core).

If there really isn’t a good implementation name, it might mean that the interface is poorly named or designed. Perhaps it’s unfocussed because it has too many responsibilities, or it’s named after its implementation rather than its role in the client, or (just occasionally) that it’s a value not an object—this discrepancy sometimes turns up when writing unit tests

"


So here's my deeper, long version explanation why I'm against suffixes and prefixes, and also with my proposal. =)


Cheers,


[1] www.mockobjects.com/book/achieving-object-oriented-design.html#impl-classes-are-meaningless

Jake Bell

unread,
Dec 5, 2012, 8:39:22 AM12/5/12
to php...@googlegroups.com
I'm pro to not suffix interfaces and traits, but rather use *-able like naming convention.

I agree with this. Interfaces and traits function as behaviors, and suffixing them with "Interface" and "Trait" make code less readable. For example,

class Post implements Persistable
{
    use Commentable;
}

reads a lot clearer to me than PersistableInterface and CommentableTrait.

I do sincerely hope that you all amend the proposal to exclude those two naming conventions. The rest of the suggestions in the proposal are great.

Marco Pivetta

unread,
Dec 5, 2012, 8:48:53 AM12/5/12
to php...@googlegroups.com
Actually, I'm pro "*Interface": it helps readability, and most importantly it reduces freedom in naming choices. Too much freedom in naming various components causes a lot of confusion.

It has been widely discussed before the release of ZF2 for example, and I'll limit myself to linking it: http://framework.zend.com/wiki/display/ZFDEV2/RFC+-+Revised+Naming+of+Interfaces+in+ZF2

Just my thoughts.

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/74N-R0MSfSkJ.

Evert Pot

unread,
Dec 5, 2012, 8:54:04 AM12/5/12
to php...@googlegroups.com
In your simple examples I agree, those are great interface names.

But as mentioned before on this list, complex systems have many interfaces, and the english language simply does not allow adding 'able' just about everywhere, without resorting to incredibly convoluted naming.

I too started with the 'able' prefix in the advent of my project, but after some time you realize this is an unworkable situation. I'm certain that the other people who voted +1 one this proposal have ran into the same thing after some time. It is very hard to come with names for every abstract concept, let alone coming up with an adjective that makes sense.

Just like for an exception this would be 'Throwable' and not 'Exceptionable', many of these words simply don't exist in the english language.

-able simply does not work in real life. If you ran a sufficiently large open source project with a strong API, you would know this.

So given that, lets go through the other options once more:

1. Prefix everything with an 'I'. Pascal/Delphi uses this and I've done so for a while as well.
2. Suffix with 'Interface', this is what many projects have started doing.
3. No suffix or prefix, which usually implies that the concrete implementation has to end with something like (Impl.) like Java does.

Aesthetics aside, many PHP projects have chosen to go with #2, and the ZF people had some good internationalization reasons to go along with that as well.

Evert

Jake Bell

unread,
Dec 5, 2012, 9:10:13 AM12/5/12
to php...@googlegroups.com
In your simple examples I agree, those are great interface names.

But as mentioned before on this list, complex systems have many interfaces, and the english language simply does not allow adding 'able' just about everywhere, without resorting to incredibly convoluted naming.

I too started with the 'able' prefix in the advent of my project, but after some time you realize this is an unworkable situation. I'm certain that the other people who voted +1 one this proposal have ran into the same thing after some time. It is very hard to come with names for every abstract concept, let alone coming up with an adjective that makes sense.

Just like for an exception this would be 'Throwable' and not 'Exceptionable', many of these words simply don't exist in the english language.

That makes a lot of sense; thanks for the insight.

To be clear, I am not in favor of adopting a bylaw to suffix all Interfaces and Traits with "-able". I am simply citing examples where the proposal to standardize the naming of these things decreases readability. I'm personally in favor of not standardizing these two things, and leaving it to developers to name interfaces and traits sensibly.


-able simply does not work in real life. If you ran a sufficiently large open source project with a strong API, you would know this.

Again, thanks for the insight, but the purpose of APIs is not be easy on the API developer, but the API consumer. As an API consumer (and, perhaps less so, developer), PersistentEntityInterface is much less readable than Persistable, especially in typehints, which can often read like English:

public function save(Persistable $entity)

Jordi Boggiano

unread,
Dec 5, 2012, 9:20:29 AM12/5/12
to php...@googlegroups.com
On 05.12.2012 15:10, Jake Bell wrote:
> I'm personally in favor of not standardizing these two
> things, and leaving it to developers to name interfaces and traits sensibly.

FWIW, that is also my opinion in general. And that's why I would not
want to specify this as a PSR. But I feel the bylaw is necessary because
in the FIG context, every time you create a class you need to justify
its name to 500 persons. Therefore in the hope of saving time and
especially energy I have a feeling that we are better off with the bylaw
even if in some rare cases it leads to less optimal names.

Cheers

--
Jordi Boggiano
@seldaek - http://nelm.io/jordi

Moisa Teodor

unread,
Dec 5, 2012, 9:48:57 AM12/5/12
to php...@googlegroups.com
Hi all,

Since this is the first real specification that produces a set of interfaces, I think it is kind of expected for things to take a longer, as stuff like the naming conventions are brought to the table and discussed. It's like a setup fee which is payed only once.

I'm pretty sure that future specifications will benefit greatly form these initial discussions, especially if they end up with generally accepted conclusions which can be referenced at any time.

Thinking about these, I also agree that - at least in the beginning - a reasonable amount of time should be allocated for different opinions to emerge, because it's an open group. 

Thanks!


--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to php-fig+u...@googlegroups.com.



--
Doru Moisa
web: http;//moisadoru.wordpress.com
tel: +40 720 861 922
Bucharest, Romania

Jake Bell

unread,
Dec 5, 2012, 10:00:02 AM12/5/12
to php...@googlegroups.com
How about something like this for the part regarding interfaces and traits:

For interfaces and traits, developers are encouraged to use names that promote code readability for API consumers. For example, a trait to add commenting functionality to a class may be called "Commentable", so that type-hinted method signatures read nicely:
    public function addComment(Commentable $post);
In cases where a suitable English adjective does not exist or is not sufficiently clear, "Interface" and "Trait" may be appended to the name of the interface or trait, respectively. For example, "SecurityContextInterface".

Does something like that seem OK? The idea is that it provides clear guidelines while still giving developers options to optimize for human readability.

Sebastian Krebs

unread,
Dec 5, 2012, 11:53:17 AM12/5/12
to php...@googlegroups.com



2012/12/5 Jake Bell <ja...@theunraveler.com>

How about something like this for the part regarding interfaces and traits:

For interfaces and traits, developers are encouraged to use names that promote code readability for API consumers. For example, a trait to add commenting functionality to a class may be called "Commentable", so that type-hinted method signatures read nicely:
    public function addComment(Commentable $post);
In cases where a suitable English adjective does not exist or is not sufficiently clear, "Interface" and "Trait" may be appended to the name of the interface or trait, respectively. For example, "SecurityContextInterface".

And the big question I ask myself for years now: Why not just "SecurityContext"? I can't imagine, that it is that hard to remember (or find out (especially with a decent IDE)) that this is an interface, so it must be hardcoded into the identifier (what is pollution in my eyes). It is pollution, because (strictly spoken) it's plain wrong: It is not "an interface to a Security Context", it is "a Security Context".

 

Does something like that seem OK? The idea is that it provides clear guidelines while still giving developers options to optimize for human readability.

OK :) Don't care :) 

Regards,
Sebastian
 

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/T4_UBawEFyYJ.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

Kirill Chebunin

unread,
Dec 9, 2012, 6:49:37 AM12/9/12
to php...@googlegroups.com
In the ideal model we have:
* Interface names are used in dependencies (constructor and method type hinting), in return values (method doc blocks), in class implementations.
* Class names are used in implementations.

So why we have to write Interface suffix in 90% of our code, when we actual classes are rarely used? Especially when we talk about PSR which mostly consist of interfaces.

And yes, PHP core does not have any suffixes for their 13 interfaces (in version 5.4). And it seems well.

More over it's better when class name which implements an interface has some implementation description in its name. Like CachedSecurityContext which says that this class supports internal cache.

So it's really weird for me to see some suffixes in interfaces.


2012/12/5 Sebastian Krebs <kreb...@gmail.com>



--
Best Regards,
Kirill chEbba Chebunin,
Programmer to the bone,
Moscow, Russia.

Florin Patan

unread,
Dec 9, 2012, 10:03:46 AM12/9/12
to php...@googlegroups.com
I think that sufixing with the specific type, Interface/Trait, helps readability / naming things much better that any other options would.

I see that Guilherme suggested that either sufixing with *-able or having the implementation class named *Impl.
- *-able doesn't allow better naming of things, like: CacheInterface vs Cacheable or CacheObjectInterface vs CacheObjectable
- *Impl in the implementing class is rather inconvenient, think of projects like Symfony2/Zend Framework 2 and many others that would create a biiig BC break when they would adopt this new standard.

So all in all, let's have the vote be done with, see who gets to name things and how, and lets get FIG to move to more important things like: Logging, Cache, Events and many more.

I know that naming things is hard, see Phil Karlton quote "There are only two hard things in Computer Science: cache invalidation and naming things.", but I also think that if we allow too much time to pass between a proposal and the acceptance / rejection vote and get stuck in small issues then everyone would be hurt.

Best regards,
Florin

Moisa Teodor

unread,
Dec 9, 2012, 11:26:53 AM12/9/12
to php...@googlegroups.com
Hi all,

I think it would be very helpful to see how others are doing it. In the Java world, there's the Java Community Process (JCP) - which defines the rules for the specifications they produce (JSRs). It has a long histroy (active since 1998 or so) and I believe it has been quite succesful in the specifications it produced.


FWIW, the JCP allows for a 30 day time period for feedback, before the thing goes through voting and becomes final.

Thanks!

--
You received this message because you are subscribed to the Google Groups "PHP Framework Interoperability Group" group.
To post to this group, send email to php...@googlegroups.com.
To unsubscribe from this group, send email to php-fig+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/php-fig/-/5bag3n9NdhIJ.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--

Kirill Chebunin

unread,
Dec 10, 2012, 2:41:28 PM12/10/12
to php...@googlegroups.com
Example of "pretty" client code

public function __construct(UserManagerInterace $userManager, SecurityContextInterace $securityContext, EventDispatcherInterface $dispatcher, LoggerInterface $logger)
{}

And it's 90% of code with useless Interface suffixes when you don't interesting in implementations at all. Interfaces are first-class citizens in OOP code.


2012/12/9 Moisa Teodor <mois...@gmail.com>



--
Reply all
Reply to author
Forward
0 new messages