7

I work in php, and the concept of interfaces seems to me a little useless here. From reading, I understand that interfaces are part of "design by contract", but without at least guaranteeing a return of a type of a particular kind, there really isn't any contract. It seems it's like a contract that reads, "We agree to do the following: '' " -- there are no terms of the agreement.

If I want a guarantee that an object has a method, it doesn't seem like interfaces are particularly useful. If I try to call a method that an object doesn't have, I get a Fatal Error, so I find out pretty quickly that that class doesn't have a method with that name. If I want to be smart and check beforehand whether a class has a method, then checking the interface, and seeing whether the object implements that interface doesn't seem to save me any more time than just checking that object directly ( which I would do anyways to see if the class had that method regardless of any interfaces it did or didn't implement).

In other words, just because I have a set of methods that have particular names, that doesn't guarantee me any particular behavior. If I'm guaranteed a return of a variable of a certain type, I at least have some inkling of what the output would be, and I can write code that uses an object with that interface, because I know what I'm getting out of it. If it returns a string, I can continue coding with at least the certainty that I'm dealing with a string output afterward. So I'm guaranteed at least some behavior when a return type is specified. Is guaranteeing behavior part of what interfaces are for, or no?

The only thing I can think of is that when I'm writing code, it serves as a post-it note to myself to be sure to create certain methods when writing that class later on. It seems more like scaffolding for when I'm writing the code; I don't see much benefit from when I'm actually using it. So it's more for me to keep the standard when I'm creating classes than when I'm writing them. This benefit doesn't really seem to be captured in the concept of design by contract.

What benefit(s) do you actually get from using an interface in dynamic/loose-typed languages like PHP? Are they great, or is it something that more robust OO languages implement, so PHP implements it also?

user151841
  • 17,377
  • 29
  • 109
  • 171
  • 4
    Pedantic note: PHP is not `Untyped`. It's dynamic and loose typed. There's a HUGE difference... – ircmaxell Aug 25 '10 at 16:26
  • That's not so pedantic if it makes a huge difference :) Fixed. – user151841 Aug 25 '10 at 16:41
  • 1
    What if your software requires that a method returns a prime number or a US-ASCII string? Just because an interface cannot specify that part of the "contract", and those things can throw your program off, does that mean interfaces are completely useless in all languages? Also, in strongly-typed languages, a type-mismatch produces an error as well. So you could just as easily ask why you need to specify a return type in your interface in strongly typed languages. – Lèse majesté Aug 25 '10 at 16:44
  • Well, it is a huge difference, but I'm not sure it changes the sentiment or answers to your question... Which is why I said pedantic... – ircmaxell Aug 25 '10 at 16:44
  • sounds rather like rant than a question – Gordon Aug 25 '10 at 16:53
  • Lèse majesté: "What if your software requires that a method returns a prime number or a US-ASCII string?" - there are efforts in languages and/or tools that let you specify those pre/post conditions. – VolkerK Aug 25 '10 at 16:59
  • @Gordon There are obviously rant elements here, but they don't negate the questions, IMHO ;) – user151841 Aug 25 '10 at 17:03
  • @Lèsemajesté "What if your software requires that a method returns a prime number or a US-ASCII string?" You would create a class that can only store those value types and require that objects of that type are returned, very simple. – Solaris Aug 16 '14 at 13:55

4 Answers4

3

Interfaces are used when you actually expect an object to implement a method.

For example, if I'm building a DB wrapper and it supports behaviours, which you register yourself in a bootstrap, then before running your behaviours (for example, sluggable), I will check that they implement my "DB_Wrapper_Behaviour_Interface" by using:

if(!($behaviourObject instanceof DB_Wrapper_Behaviour_Interface)) {
    throw new Exception("Your behaviour doesn't implement my interface");
}
Andrei Serdeliuc ॐ
  • 5,828
  • 5
  • 39
  • 66
  • user151841 already picked this aspect up in the question. Can you please elaborate on the usefulness in regards to the doubts raised in the question? – VolkerK Aug 25 '10 at 16:36
  • More than just a `method`. A method signature. Including types hints and defaults... – ircmaxell Aug 25 '10 at 16:36
  • VolkerK, from both OP and greg0ire I'm getting the feeling they are using interfaces on one-man projects. While this is encouraged, interfaces will start making sense when inter-developer assumptions come into play, like my DB Wrapper - behaviour example. – Andrei Serdeliuc ॐ Aug 25 '10 at 16:42
  • 1
    @Andrei Yeah, but what does it get you in the big picture? If my class has a method named 'sluggable', and there's no guarantee for what it actually does, why use that functionality? Why not just use `function_exists` in that case? All your doing is making sure that a method of a particular name exists. That method could do nothing at all, or something completely other than what you expect it to do. What use is interfaces, then, in this case? – user151841 Aug 25 '10 at 16:43
  • 1
    @user151841: Well, what language does an interface enforce the functionality of a method? At most, they inforce input and output types, and exceptions thrown. That's really about it. What happens under the hood is black boxed (and that's the true benefit of the interface, is that you don't care how it does what it does). You could make an iterator where `current()` returns the inverse of the next variable. The interface would be correct, but the implementation would be "not what was expected", but that's also not what interfaces are designed to enforce... – ircmaxell Aug 25 '10 at 16:48
  • 1
    @maxwell At least in a language where a return type is guaranteed, there is *some* ( perhaps small ) guarantee of behavior. If it returns a string, I can continue to write my code with the knowledge that I'm dealing with a string output, at a minimum. The usefulness of that may be debated in its own question :) However, with dynamic languages, there seems to be almost *no* benefit whatsoever... am I off-base here? If there's no enforcement of input and output, are they of any use? If I just need to verify that a method of a particular name exists, interfaces seem to be an 'inner-platform'. – user151841 Aug 25 '10 at 17:02
  • @user151841: First off, it's ircmaxell (It's a pet-peeve seeing `maxwell`). Secondly, in a dynamic typed language it doesn't matter (for the most part) what was returned. If it returned a non-string, it would be cast to a string when you first used it like a string. The only time it matters, is when you're expecting an object of a certain type. And for that, you can do a simple type check `if (!$return instanceof MyExpectedClassInterface) { throw new Exception`... But for the majority of the use cases, enforcing the return type would almost go against the loose typing nature of PHP... – ircmaxell Aug 25 '10 at 17:07
  • @ircmaxell: But that is exactly the question (which in my opinion hasn't been answered yet, maybe touched in comments but not as an answer): The "full" description of interfaces (or protocol) in oop includes the return type. php implements an oop-ish concept of `interface`. Is the return type an _integral part_ of the usefulness of interfaces or not? (And I'm not taking a side on this subject ;-)) Btw: php currently enforces default values on interface implementations but only _that there is_ a default value if the interface declaration provides one, but not which one. – VolkerK Aug 25 '10 at 17:16
  • @ircmaxwell apologies about the name; can't fix it now :( – user151841 Aug 25 '10 at 17:35
  • @ircmaxwell You seem to be arguing my point in your '2nd'... interfaces don't get you much in dynamically typed languages? If all it gets you is guaranteeing that a method of a certain name exists, then the whole idea of interfaces seem a very roundabout way to do it. – user151841 Aug 25 '10 at 17:38
  • @user151841: I'm not going to argue about this. They "don't get you much", because (from a return type perspective) they don't need to. The interface is there to lend both a semantic implication (which depends on people using them properly) and an enforcement upon the actual class structure (so you always know an object of the `iterator` interface will **always** have a `next()` method that takes 0 parameters... There's nothing you can do (or IMHO should do) about people abusing the interface to do other (unsupported) things. If they do and it breaks, it's their fault, not the language... – ircmaxell Aug 25 '10 at 17:55
  • @user151841: It's not just the name. It's also the number of arguments. And with php 5.3 it also enforces type-hinting. If the interface contains type hinting, e.g. `interface Foo { public function bar(Base $x, array $y=array()); }`, then the implementing class must use the exact same type-hinting (no covariance allowed). – VolkerK Aug 25 '10 at 18:01
  • @ircmaxell: With type-hinting you can enforce certain behaviour of the input parameters, but you can't enforce the type of the return value. At least it's a bit asymmetric if we keep to the argument of "loose typing is the nature of php". And regarding `iterator`: One big thing in java (and .net) was the introduction of generics, so the declaration of next() wasn't limited to the broadest type `object` but could be limited to e.g. `Integer` and narrower. The question still remains: If php puts the `interface` in the oop section is not enforcing the return type a game breaker? – VolkerK Aug 25 '10 at 18:14
  • @VolkerK If you write up an answer, I'll upvote and accept it :) – user151841 Aug 25 '10 at 19:08
  • @user151841: Sorry, I can't really make up my mind on this subject in the context of php (and I gave up developing in php for a living quite some time ago so I don't have to -_-). I just use it for what it is. – VolkerK Aug 25 '10 at 20:43
  • I still contend that just because interfaces don't include the return type, they are still quite useful. In a strongly typed language, they would be a lot less useful since you'd need to figure out the type of the return before moving forward. But since PHP is loose typed, I think the loss by not having it is relatively small. I don't consider the lack of return type a game breaker (or even a set back). I think interfaces are wildly useful even as they exist today. But it still boils down to the proper implementation if an interface still falls to the developer (no matter the language)... – ircmaxell Aug 26 '10 at 12:25
1

Design by contract is made more difficult without return types, but don't forget to favour 'tell' over 'ask'.

I believe an interface to be something like a responsibility. You are coding and need a collaborator. You ask it to do something because the code you are working on can't do everything. So you're asking another object to do something. An interface guarantees that the collaborator will do the job, but hides the 'how' it's done part.

Now you could argue that there's no need for the formal contract here, since the system will throw an error anyway if the collaborator can't do what you're asking it to do. But I think that misses the point in using interfaces as a responsibility.

koen
  • 13,349
  • 10
  • 46
  • 51
0

Getting a fatal error is not always "easy". Sometimes you have to go on a specific module/action to see that something is actually missing in your class. The interface enables you to make sure every method is implemented and to document these method (what the parameters are exactly going to be, what the return values should look like). This is useful if the parameters/values are arrays with a particular structure and you don't want to use classes instead (for the sake of simplicty).

greg0ire
  • 22,714
  • 16
  • 72
  • 101
  • "what the return values should look like" - but that is not enforced by php (and user151841 picked up that aspect, too, in the question). So, "to document" is to be taken literally; external tools and/or ide may pick up that extra information/annotation but php itself doesn't care. – VolkerK Aug 25 '10 at 16:41
  • @greg0ire I'm not familiar with many other language. Can you give an example in PHP where you call a non-existent method on a property, and there is an obscuring of what exactly went wrong? – user151841 Aug 25 '10 at 17:10
  • @user151841 : No, I can't, why would try to do such a thing? What I was saying is that it is harder to make sure that every method you are supposed to implement is implemented if there is no interface. You have to search all the code of the application for calls to the getters of the property, and then see what methods are called on it. Unit-testing all your app can help you find fatal errors, but an interface is far more convenient. – greg0ire Aug 25 '10 at 18:05
  • @greg0ire I mean, I've never had a problem getting a fatal error. Calling a method that doesn't exist invariably produces one, and it explicitly tells you where exactly it is (file and line). So in short it's "easy", at least PHP. It makes an interface redundant, at least for the purposes of ensuring that a method name exists. – user151841 Aug 25 '10 at 19:10
  • 1
    @user151841: Yes it is redundant, but it is more convenient. All you have to do is read the spec and implement, instead of testing all your app, and noticing on test #481, that someMethod() is supposed to exist... This is even more true if you did not write the interface and the class that calls someMethod() on an object of the class you are supposed to write. – greg0ire Aug 25 '10 at 19:25
  • @greg0ire I see -- one-stop shopping for what you need to do to write a class. Your requirements all in one place, like a spec. Makes sense. – user151841 Aug 26 '10 at 14:12
0

I want to note, that PHP 5.4 will support type hinting. Right now I think there is only type hinting for function arguments, but I suppose there will be for return values, too. (At least there already is an RFC, though a very old and outdated one.)

NikiC
  • 100,734
  • 37
  • 191
  • 225
  • It's there, but it's still a [very contested feature](http://schlueters.de/blog/archives/139-Scalar-type-hints-in-PHP-trunk.html)... I'm not in support of the current implementation... I think it's WAY too strict to be usable. – ircmaxell Aug 25 '10 at 16:50
  • I meant for argument type hinting. I haven't heard anything about return type hinting... Sorry for the confusion... – ircmaxell Aug 25 '10 at 17:04
  • Why do you think the current implementation is too strict? – NikiC Aug 26 '10 at 14:10
  • Because if you have `function foo(float $bar)`, and call with something like: `for ($i = 1; $i < 10; $i++) foo($i / 2);` you'll get a fatal error (since 2 / 2 == 1)... So you'd be forced to check your types before calling. So it breaks the `accept liberally produce strictly` principal... If it supported method overloading (where you could define `foo(int $bar)` and `foo(float $bar)`) then that could be worked around, but without it, it's going to make pre-call type checking a lot more important. And considering the loose typed nature, it's going to make for some interesting bugs... – ircmaxell Aug 26 '10 at 14:17
  • 1
    Not to mention that it kills all the benefits of type-coersion that's available in PHP. If you pass an object that has a `__toString` method to a function that has a `string` type hint, you'll get a fatal error (rather than an implicit conversion to a string first)... So it's going to require explicit casting in the calling statement to prevent fatal errors (`foo((string) $bar)`... – ircmaxell Aug 26 '10 at 14:19