NotionCommotion Posted January 20, 2017 Share Posted January 20, 2017 https://forums.phpfreaks.com/topic/302974-oop-abstract-classes/ and http://forums.devshed.com/php-development-5/questioning-abstract-classes-vs-regular-classes-929822.html inspired me to more often use interfaces. I would like to start off with a good naming and directory strategy. Looks like two common naming approaches are appending "Interface" after the class name and prepending a capital "I" before the class name. For instance, if my class name was BinaryMathOperator, it might be BinaryMathOperatorInterface or IBinaryMathOperator. And maybe other standards? I've also seen including the interface file in the same directory as the class, and also creating a separate directory for all? the interfaces. A little off topic, but got me thinking... Is it typical to ever have more than one class implement the same interface (or some multiple interfaces)? This will have some bearing on the naming strategy. For one just starting off, what would you recommend? Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted January 20, 2017 Share Posted January 20, 2017 Looks like two common naming approaches are appending "Interface" after the class name and prepending a capital "I" before the class name. And the third is to not use any prefixes or suffixes at all. What do you expect to gain from those hints? All IDEs I use tell me that it's an interface, so the naming standard doesn't provide any useful information. Quote Link to comment Share on other sites More sharing options...
requinix Posted January 20, 2017 Share Posted January 20, 2017 It doesn't matter as long as you're consistent. I personally like the .NET approach of naming I*. I know some open-source projects use *Interface. I've even seen them named interface_*, thus putting them in their own directory at the top-level, but I think that's silly. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted January 20, 2017 Author Share Posted January 20, 2017 And the third is to not use any prefixes or suffixes at all. What do you expect to gain from those hints? All IDEs I use tell me that it's an interface, so the naming standard doesn't provide any useful information. And you use this one? Do you not bother making the name suggest the class which implements it? Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted January 20, 2017 Share Posted January 20, 2017 The name doesn't suggest anything about the implementation. In fact, there's something wrong if it does. In interface specifies methods. It doesn't say how or by whom they're implemented. There can be many different implementations, and that's the whole point. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted January 20, 2017 Author Share Posted January 20, 2017 It doesn't matter as long as you're consistent. I personally like the .NET approach of naming I*. I know some open-source projects use *Interface. I've even seen them named interface_*, thus putting them in their own directory at the top-level, but I think that's silly. Thanks requinix, I agree with the consistency part. I know in the past, I started one approach (curly brackets is a classic example) , later second guessed myself, and flipped, and I don't wish to do so again. I feel I* is nice as it is shorter, but also feel *Interface is nice as it matches many open-source projects and files are better listed in alphabetical order. Maybe I will flip a coin! Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted January 20, 2017 Author Share Posted January 20, 2017 The name doesn't suggest anything about the implementation. In fact, there's something wrong if it does. In interface specifies methods. It doesn't say how or by whom they're implemented. There can be many different implementations, and that's the whole point. Agree, not how they are implemented. As far as by whom, almost every example I have looked at does so (Symphony, Slim, ReactPHP, Pimple, etc as well as http://php.net/manual/en/language.oop5.interfaces.php). Are they all wrong, or am I missing something? Quote Link to comment Share on other sites More sharing options...
kicken Posted January 20, 2017 Share Posted January 20, 2017 I prefer the "Interface" suffix these days. I did the "I" prefix for a while when I started doing more OO stuff. Using a suffix means that the files are still sorted alphabetically and are not all clumped up in the I's section. That makes it easier to find them in a directory listing. Having a suffix or prefix also makes it easier when see exactly which files are classes rather than interfaces. Letting your IDE break everything down by type is great but it doesn't work so well when you're not using the IDE, such as browsing code in a GitHub repository to find something. Having a suffix or prefix also means you can have an implementation who's name matches the interface if desired. class Firewall implements FirewallInterface { } Quote Link to comment Share on other sites More sharing options...
benanamen Posted January 20, 2017 Share Posted January 20, 2017 (edited) That makes it easier to find them in a directory listing. With only 5 files in my class directory that have been recently created I am having to take a moment to think to remember which one is the Interface. As mentioned, you are not always going to be using an IDE when viewing those files. Even the manual shows a designator. It is also a standard in major frameworks. For those reasons and probably more, I will probably designate either a prefix or suffix. While I prefer the full suffix Interface for clarity, a prefix would be best for sorting. * I see that PhpStorm clearly shows what is an interface as @Jaques1 mentioned. That is not my prefered IDE at the moment. Perhaps I will switch which does solve the "problem" aside from viewing on github. Edited January 20, 2017 by benanamen Quote Link to comment Share on other sites More sharing options...
ignace Posted January 21, 2017 Share Posted January 21, 2017 I used to use the *Interface suffix until I read this article: http://verraes.net/2013/09/sensible-interfaces/ Quote Link to comment Share on other sites More sharing options...
requinix Posted January 21, 2017 Share Posted January 21, 2017 tl;dr: I'm getting old and set in my ways. I get what that guy is trying to say, but I particularly disagree with <?php class KlingonDecoder { public function __construct(TranslatorInterface $translator)This constructor definition is saying: “I need a translator interface to operate”. But that would be silly. It needs an object that is a Translator. It does not need an interface. And that object has a certain role, a certain contract, namely that of a Translator. To me, the definition is not saying "I need a translator interface" but "I need a thing that acts as a translator"; "interface" is a technical term that I recognize for the mechanism that separates a thing that does (object) from a thing that can do (interface). And that is actually what it needs. It does not need a particular object from a particular inheritance hierarchy: it needs some kind of object that can fulfill the "can translate" requirement. That may very well end up being from a particular inheritance hierarchy, but as a KlingonDecoder I don't need to enforce that constraint. With languages like PHP that only support inheritance from one parent, classes need to be careful about what they extend, and if I intend to create a protocol droid* that is capable of translation then I'm certainly not going to make my choice of parent class be a Translator. On that note, "Translator" sounds like an actual thing that translates (an object) but "ITranslator" or "TranslatorInterface" make it clear that yes, they do translation, but they only dictate the ability to translate. Backing up a bit: Is [the Translator vs. TranslatorInterface naming issue] bad? I believe it is. It confuses people, as they tend to misunderstand whether they should typehint for Translator or TranslatorInterface. So both are being used in the client code. Program sometimes to an interface, sometimes to an implementation?That's a known problem with newbie/new-to-OOP programmers: not understanding the differences between the object and interface paradigms. Objects as real-world counterparts acts as an easy (if inadequate) analogy and makes initial comprehension straightforward, but interfaces don't have one. Interfaces look like mysterious classes that don't have any code... but abstract classes don't have any code either, so are they the same thing or what? It's an education problem. Teach people about objects and interfaces and suddenly the naming problem goes from "I need a translator so I think I need a Translator and not this weird TranslatorInterface thing" to "I need a thing that can translate, and since I don't need a particular Translator I think I should use a TranslatorInterface". And back to naming, Another bad habit, is using the -able suffix for interface names. I guess I can live with something like Translatable, or maybe Serializable. But Timestampable? Jsonable? Is that the world we want our children to inherit? English motherfucker, do you speak it? Try making a sentence, it’s so much nicer.I tend to use -able when it creates a reasonable word, but making sentences is introducing a whole 'nother problem. I know that "Jsonable" is a bit awkward, but as an English speaker I don't need a dictionary to know what it means: able to become Json. It's short and simple. As a descriptive term you'd want "CastsToJson"? But it's not actually a cast. So "ConvertsToJson"? Converts itself or other data? "SerializesToJson"? How does it serialize? "ReturnsSerializableData"? How is that data serializable? I can keep going. To me, the whole blog entry seems based on a knee-jerk reaction to the fact that interfaces are becoming more and more popular - in the same way that singletons and registries did, and quite possibly to the same conclusion. The names are a red herring. * Yes, I know, wrong universe. 1 Quote Link to comment Share on other sites More sharing options...
ignace Posted January 21, 2017 Share Posted January 21, 2017 (edited) Sure a few of his examples are a little far-fetched. I have never had the trouble distinguishing between what a Translator is or what a TranslatorInterface does. I think SerializeToJson is a good descriptive name for the interface as would JsonSerializable I imagine. But again this is probably a bad example because an object should not be aware of what JSON is nor how it "serializes" itself to it. It gives you something to think about though the next time you develop a system. Proper naming is always half the battle. Even though I prefer to write an interface without the suffix on small (individual) and private projects, on big projects I tend to stick to "open-source" standards and that means *Interface suffix, *Trait suffix, and Abstract* prefix. This makes it easier to work together, and publish libraries. Edited January 21, 2017 by ignace Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.