SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 26
  1. #1
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Ireland
    Posts
    349
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    PHP5: Interfaces and Type Hinting, Pros and Cons

    Quite often during surfing posts in this forum the issue of Interfaces and Type Hinting and it implications come up. I decided to start a thread up on this issue listing pros, cons. Also, on my personal opinion on them, and ideas on how they could be used. Pretty much a summarisation of what is being said in various other conversations.

    Pros
    • Useful for documentation purposes.
    • Enforces complicance from classes
    • Useful in IDE's (e.g. autocompletion)
    • Potential for helping in Dependancy Injection. (Type-hinting specifically)


    Cons
    • Performance: Another thing to parse, probably another file to open.
    • Unnecessity: Dynamic language, duck-typing should be enough.


    My Opinion:

    Besides for DI, I don't see an actual usage of these features enhance the application. I can see how Interfaces help in documentation, but actually using them is a waste of resources. Type-hinting is unnecesary, and goes against the very purpose of dynamic languages.

    Ideas:

    While developing in IDE's, using Interfaces and Type-hinting can help (e.g. Auto-completion). If the IDE's allowed you to remove references to them then before deploying, it would be good. The Interfaces could remain in the package then for documentation purposes.

    Maybe, implement a test case to check classes follow a particular interface. This could be done with the Reflection API. This way, the class is checked to follow the interface, however not during every runtime.

    Well, there is my view on the matter, any comments?

  2. #2
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wow. Man, you nailed it down squarely. When I saw the post subject I prepared for a long rant of my opinions, but I really have nothing to add -- you stated every single thing I could about the subject, and then some which I can only agree with.

    Respect.

  3. #3
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't use type hinting much at all. I can see the use of it in situations where you have several developers using a separate library to enforce the types being sent (eg dev a has created a library for dev b c and d to a specific set of requirements. Those devs a) instantly know it's to the correct specification and b) it provides an instant point of failure if it's used incorrectly). Other than that, your points sum up my feelings on it.

    \/\/ is a summation of what I was alluding to.
    Last edited by Tanus; Feb 2, 2006 at 06:24.

  4. #4
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Consider this "duck typed" code
    PHP Code:
    class Bar1 {}

    if(
    "some specific condition") {
        
    $a = new Bar1();
        
    $bar->foo();

    We have to unit test with that specific condition to find out that Bar1 doesn't implement foo. And since it will be a Fatal error we even don't get a chance to report it properly.

    On the contrary,
    PHP Code:
    interface fooAble {
        function 
    foo();
    }
    class 
    Bar2 implements fooAble
    {}

    if(
    "some specific condition") {
        
    $a = new Bar2();
        
    $bar->foo();

    This fails immediately, no need of unit test.

  5. #5
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    This [static typed] fails immediately, no need of unit test.
    There are pros and cons of static typing. The big benefit is that errors happens much closer to the source. I'm not sure if the pros outweight the cons. Perhaps weak interfaces would have been a better solution (qua our discussion in another thread).

  6. #6
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog
    We have to unit test with that specific condition to find out that Bar1 doesn't implement foo.
    Oh, come on -- you're mixing apples and oranges here.

    If the outlying code (the conditional block) goes within some class, we unit test that class, and in that case this particular example is bad code, since you have direct class coupling which is difficult to unit test anyway.

    Anyway, this goes well with my (and Ryan's) point: Interfaces as documentation, without type hinting.

    And since it will be a Fatal error we even don't get a chance to report it properly.
    Which is an intrinsic problem of PHP and has nothing to do with interfaces. A colleague of mine is just working on a custom handler wrapper which will provide exceptions in the place of errors, which should make it possible to report even fatal errors (he claims so -- we'll see).

  7. #7
    SitePoint Zealot DerelictMan's Avatar
    Join Date
    Oct 2005
    Posts
    123
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A colleague of mine is just working on a custom handler wrapper which will provide exceptions in the place of errors, which should make it possible to report even fatal errors (he claims so -- we'll see).
    I'd drool over something like that if it worked. One of my biggest problems with PHP is the fact that fatal errors cannot be dealt with. I know there's been some discussion about making type hint violations "recoverable", which is great, but I would also love it if calling a method on a non-object (the PHP equivalent of Java's NullPointerException) was something that could be caught by an error handler. If your colleague is planning on releasing this wrapper you are talking about then please make sure to let us know about it. Thanks.

  8. #8
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    There are pros and cons of static typing. The big benefit is that errors happens much closer to the source. I'm not sure if the pros outweight the cons. Perhaps weak interfaces would have been a better solution (qua our discussion in another thread).
    Static typing? I didn't use any types in my example did I?

    My point is that DBC is a Good Thing, and one should use explicit contracts whenever possible. Interfaces are class declaration contracts, type hints can potentially become call contracts, if php ever implements strict (not to confuse with static) typing.

  9. #9
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fatals thing is a piece of cake BTW

    PHP Code:
    ob_start('catch_fatals');
    function 
    catch_fatals($buf) {
        if(
    preg_match("~Fatal error~"$buf))
            return 
    "fatal error logged";
        return 
    $buf;
    }
    #test
    new ZZ(); 

  10. #10
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Interfaces as documentation, without type hinting.
    If your not going to use one (Interfaces) without the other (Type Hinting) then there is no benifit to using Interfaces at all. Period.

    The benifits of Interfaces, is that fact that you can type hint; It's not my particular problem that someone can't see any benifit of type hinting - in any language, but put it this way; If you can't or won't use Interfaces and type hinting, with experience, I wouldn't consider employing you

    There is having your own point of view, and there is just being plain ignorant of the technology, and the tools, to do the job, and do it properly.

  11. #11
    SitePoint Addict
    Join Date
    Apr 2004
    Location
    Melbourne
    Posts
    362
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    If your not going to use one (Interfaces) without the other (Type Hinting) then there is no benifit to using Interfaces at all. Period.

    The benifits of Interfaces, is that fact that you can type hint; It's not my particular problem that someone can't see any benifit of type hinting - in any language, but put it this way; If you can't or won't use Interfaces and type hinting, with experience, I wouldn't consider employing you
    Take for example generics that I like so much in C#; 'type hinting' collections at compile time based on their interface. But I digress

  12. #12
    SitePoint Guru
    Join Date
    Nov 2002
    Posts
    841
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ryan did nail it. One of the advantages of declaring an interface is to document it. Testing:
    PHP Code:
    class MyClassTester extends myClass implements myInterface {} 
    At the price of more complicated reflection processing, one could use phpdoc annotations in the applications where you wanted the typing hinting or interface implementation meta data.

    I think the question comes down to the two cons that Ryan listed. How expensive is it really to open and parse a few extra files? (I know that personally this bugs me.) The thing to ask is if there were no performance penalty at all, would I do it?

    The other question: is there an advantage to not forcing the implementation of a specific interface? Perhaps encourages violation of the Liskov Substitution Principle violation and should be avoided?

  13. #13
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nobody has yet brought up the slightly annoying issue that interfaces are actually implmented as abstract classes "under the hood". This means you can't decare two interfaces with an identical method name

    PHP Code:
    interface boat 
    public function 
    drive(); 
    public function 
    float(); }
    interface 
    car 
    public function 
    drive(); 
    public function 
    rotateTires(); }
    class 
    amphibious implements boatcar 
    public function 
    float() {} 
    public function 
    drive() {} 
    public function  
    rotateTires() {} } 
    Code:
    Fatal error: Can't inherit abstract function car::drive() (previously declared abstract in boat) in Command line code on line 3
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  14. #14
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    If your not going to use one (Interfaces) without the other (Type Hinting) then there is no benifit to using Interfaces at all. Period.
    Actually, you're mistaken here. Interfaces alone have the benefit of self-documentation. Type-hinting without Interfaces makes no sense at all.

    Quote Originally Posted by Dr Livingston
    The benifits of Interfaces, is that fact that you can type hint; It's not my particular problem that someone can't see any benifit of type hinting - in any language
    Excuse me, but no, I see no advantage of type hinting whatsoever -- in a static language there is no type hinting, because you have to declare the type anyway, but in a dynamic language, where not having variables tied to types is the primary advantage of the language, type hinting negates part of this advantage, and I still don't see any benefits in doing that.

    Quote Originally Posted by Dr Livingston
    but put it this way; If you can't or won't use Interfaces and type hinting, with experience, I wouldn't consider employing you
    Have you ever considered that it might be you who is mistaken here?

    I used to be a proponent of using type hinting, until I realized the advantages of duck typing. But exactly because of this, I am aware that I might not know everything and have all information -- my posts here were not intended to force my opinions to everyone else, but to test my ideas and draw forth responses which might disprove me. So far I saw nothing that made me realize the advantages of type hinting, but that doesn't mean that nothing ever will -- I'll be most grateful if you (or anyone else) could explain the real benefits of type hinting over duck typing in dynamically-typed languages such as PHP.

  15. #15
    SitePoint Zealot DerelictMan's Avatar
    Join Date
    Oct 2005
    Posts
    123
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fatals thing is a piece of cake BTW

    PHP Code:
    ob_start('catch_fatals');
    function 
    catch_fatals($buf) {
        if(
    preg_match("~Fatal error~"$buf))
            return 
    "fatal error logged";
        return 
    $buf;
    }
    #test
    new ZZ(); 
    OMG. It's amazing how long you can work with a technology and remain ignorant of certain things. I use output buffering on all my sites anyway, I just had no idea about the callback. Thanks for that (it's not as clean as true error handling, but it's better than what I'm doing now).

  16. #16
    SitePoint Guru OfficeOfTheLaw's Avatar
    Join Date
    Apr 2004
    Location
    Quincy
    Posts
    636
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DerelictMan
    OMG. It's amazing how long you can work with a technology and remain ignorant of certain things. I use output buffering on all my sites anyway, I just had no idea about the callback. Thanks for that (it's not as clean as true error handling, but it's better than what I'm doing now).
    Yup.. I use output buffering callbacks for a lot of things.

    However, I believe what was shown as an example is rather misplaced. For logging errors, http://us3.php.net/set_error_handler is great.

    James Carr, Software Engineer


    assertEquals(newXPJob, you.ask(officeOfTheLaw));

  17. #17
    SitePoint Zealot DerelictMan's Avatar
    Join Date
    Oct 2005
    Posts
    123
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by OfficeOfTheLaw
    Yup.. I use output buffering callbacks for a lot of things.

    However, I believe what was shown as an example is rather misplaced. For logging errors, http://us3.php.net/set_error_handler is great.
    No, I'm quite familiar with set_error_handler() (been using that for years) but the point was that a custom error handler cannot handle fatal errors (E_ERROR, etc.) such as type hint violations or things like calling a method on a non-object (PHP never calls the custom error handler, it just logs the error or prints it to the browser (depending on the config) and then terminates the script). For errors like that the output buffering callback hack is better than possibly showing your users a half-rendered page.

  18. #18
    SitePoint Guru OfficeOfTheLaw's Avatar
    Join Date
    Apr 2004
    Location
    Quincy
    Posts
    636
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DerelictMan
    No, I'm quite familiar with set_error_handler() (been using that for years) but the point was that a custom error handler cannot handle fatal errors (E_ERROR, etc.) such as type hint violations or things like calling a method on a non-object (PHP never calls the custom error handler, it just logs the error or prints it to the browser (depending on the config) and then terminates the script). For errors like that the output buffering callback hack is better than possibly showing your users a half-rendered page.
    Oh, true.

    The most annoying and aggravating email/call/scream for help from a client when I began coding was "The page is blank and I cannot submit!".

    James Carr, Software Engineer


    assertEquals(newXPJob, you.ask(officeOfTheLaw));

  19. #19
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sweatje
    Nobody has yet brought up the slightly annoying issue that interfaces are actually implmented as abstract classes "under the hood". This means you can't decare two interfaces with an identical method name
    Wow. What a bummer!
    Although, this is clearly an implementation problem, and one which we might expect the core developers to correct.

  20. #20
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    There is one problem with DBC (and strong typing) that hasn't yet been mentioned. Because the type information is mixed in with the code, the code becomes less clear and less readable. Type information adds clutter. As code inspection of clean code is the most powerful way of squashing bugs, you may find you are actually contributing to defects by putting in types.

    I find interfaces useful at package boundaries, especially with the dependency inversion trick. On occasion, unit testing will not do...
    PHP Code:
    class Request implements TaintedData { ... }

    class 
    Escaping implements SafeData {
        function 
    __construct(TaintedData $post) { ... }
    }

    class 
    WebPageWriter {
        function 
    paintStuff(SafeData $data) { ... }

    These and DI are probably the only placed I would use them though. Personally I prefer the cleaner duck-typed code, and to move the QA out of the code and into the test suite.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  21. #21
    SitePoint Addict
    Join Date
    Mar 2005
    Posts
    251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    ob_start('catch_fatals'); 
    function 
    catch_fatals($buf) { 
        if(
    preg_match("~Fatal error~"$buf)) 
            return 
    "fatal error logged"
        return 
    $buf

    #test 
    new ZZ(); 
    Works as long as you don't discuss how to handle a fatal error on your page.

  22. #22
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Hi...

    There is one problem with DBC (and strong typing) that hasn't yet been mentioned. Because the type information is mixed in with the code, the code becomes less clear and less readable. Type information adds clutter. As code inspection of clean code is the most powerful way of squashing bugs, you may find you are actually contributing to defects by putting in types.
    Definitely true, and this is why trying to figure out even simple java programs gives me a headache. So much noise.


    Quote Originally Posted by lastcraft
    These and DI are probably the only placed I would use them though. Personally I prefer the cleaner duck-typed code, and to move the QA out of the code and into the test suite.
    This reminds me of an old post from Robert Martin's blog on Artima that I recently stumbled on to:


    Quote Originally Posted by Robert Martin
    About two years ago I noticed something. I was depending less and less on the type system for safety. My unit tests were preventing me from making type errors. The more I depended upon the unit tests, the less I depended upon the type safety of Java or C++ (my languages of choice).

    I thought an experiment was in order. So I tried writing some applications in Python, and then Ruby (well known dynamically typed languages). I was not entirely surprised when I found that type issues simply never arose. My unit tests kept my code on the straight and narrow. I simply didn't need the static type checking that I had depended upon for so many years.
    Which brings me to another main reason why I'm wary of using interfaces; they make your code less agile. For instance:

    • Once you you have classes that rely on an interface, you can't modify the interface without having to change all the classes that implement it.
    • When you use type hinting, you lose parametric polymorphism, and since you don't have the ad-hoc polymorphism that method overloading provides in Java, you lose a lot of flexibility down the line. This is especially true if you use type hinting in your interface definitions.
    • The simple fact that using interfaces and type hinting means more typing at the keyboard; all else being equal, I would rather type less code than more.

  23. #23
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    Hi...

    There is one problem with DBC (and strong typing) that hasn't yet been mentioned. Because the type information is mixed in with the code, the code becomes less clear and less readable. Type information adds clutter. As code inspection of clean code is the most powerful way of squashing bugs, you may find you are actually contributing to defects by putting in types.
    It's only clutter if it's obvious or irrelevant what the type is. If not, it's useful documentation. In the kind of object-oriented code I write (and you too, I believe), the least obvious thing tends to be how objects interact. Knowing the type of a method argument may be the most helpful hint you can get.

    A comment may be equally helpful, though. I'm comparing type hints to no information at all.
    Quote Originally Posted by lastcraft
    I find interfaces useful at package boundaries, especially with the dependency inversion trick. On occasion, unit testing will not do...
    PHP Code:
    class Request implements TaintedData { ... }

    class 
    Escaping implements SafeData {
        function 
    __construct(TaintedData $post) { ... }
    }

    class 
    WebPageWriter {
        function 
    paintStuff(SafeData $data) { ... }

    These and DI are probably the only placed I would use them though. Personally I prefer the cleaner duck-typed code, and to move the QA out of the code and into the test suite.

    yours, Marcus
    Very interesting. I was just considering how to do something similar. You could do it with duck typing, though. Just make sure your Request object has no methods that can be used by the WebPageWriter.

    My variation on the same theme was:
    PHP Code:
    $request = new RawRequest;
    $validator = ... // Whatever we need to create the appropriate validator
    $clean $validator->validate($request); 
    Now $clean is another type, say FilteredRequest. And yes, you could use type hints to prevent a RawRequest from entering the bowels of the application. On the other hand, you could protect the contents of the RawRequest (that is the ultimate point of the exercise, isn't it?) by making sure it's only available using a method like getForValidation() or something even more difficult to access.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  24. #24
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lastcraft
    There is one problem with DBC (and strong typing) that hasn't yet been mentioned. Because the type information is mixed in with the code, the code becomes less clear and less readable.
    This is not a problem once you get a smarter compiler which can infer types for you.

  25. #25
    SitePoint Enthusiast silicate's Avatar
    Join Date
    Nov 2004
    Location
    Toronto
    Posts
    43
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey there,

    I know this thread is kinda old, but I was just looking at some solutions (work-arounds) to the type-hinting issues while using simpletest and I wondered what you all had to say about it.

    My personal view is that Type Hinting is good. I am really glad that I use interfaces as it provides a map for me when creating a new class that implements an interface or extends an object. I definitely agree that Unit Testing is the way to catch errors before they happen; however, if you have already gone through the mental work of defining an object's interface why would you want the next person to have to go through the same mental exercises if they are new to an area of the domain?

    I guess if you are a single developer or working with a small domain it's not an issue. I think the problem compounds itself if teams are dynamic and the domain large though. I guess it comes down to headspace. Would you prefer to remember all of the essential methods that are required for a specific type of object, or if you don't remember them would you prefer to read through an entire class definition sorting out what is required by other portions of the system or would you rather be able to look at a 5 line interface and use it as your blueprint to start writing your unit tests?
    Never memorize something that you can look up.
    ~Albert Einstein
    As for Type Hinting, I agree with both sides of the debate. In Java you have to specify the even the primitive types which definitely adds clutter and reduces flexibility due to lack of overloading in PHP. That being said, if your object can handle any old type of object as a parameter then I think that there is a flaw in your design.
    An object should be distilled until nothing remains that does not relate to its meaning or support its role in interactions.
    ~Eric Evans
    The important thing is how your objects interact (interface with each other) to handle tasks, the definition of these interactions I think should be the least brittle part of your coding. What makes a set of objects a composite pattern implementation? The fact that a Composite Object is a Component Object that may have other Components as children.

    Later,

    Matthew.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •