SitePoint Sponsor

User Tag List

Page 3 of 4 FirstFirst 1234 LastLast
Results 51 to 75 of 91
  1. #51
    SitePoint Enthusiast
    Join Date
    Jul 2004
    Location
    Finland
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think interfaces in php are most useful when it's about object identity
    and controlling how certain objects should be handled.
    Lets assume we have Apple and RawMeat objects which can be passed to FoodProcessor,
    but FoodProcessor must cook RawMeat before consuming it.

    PHP Code:
    interface IEatable{
        function 
    eatMe();
        function 
    vomitMe();
        function 
    cookMe();
    }
    class 
    Food implements IEatable{
        protected 
    $done 1;
        function 
    eatMe(){
            if (
    $this->done){
                echo 
    'Yumm.';
            }else{
                
    $this->vomitMe();    
            }
        }
        function 
    vomitMe(){
            echo 
    'Yaargh!';
        }
        function 
    cookMe(){
            
    $this->done 1;
            echo 
    "I'm done!";
        }
    }
    class 
    Apple extends Food{}

    interface 
    IMustBeCooked{}

    class 
    RawMeat extends Food implements IMustBeCooked{
        protected 
    $done 0;
    }

    class 
    FoodProcessor{
        function 
    process($obj){
            if (
    $obj instanceof IMustBeCooked){
                
    $obj->cookMe();
            }
            if (
    $obj instanceof IEatable){
                
    $obj->eatMe();
            }
        }
    }


    $obj = new FoodProcessor();
    $obj->process(new Apple);
    $obj->process(new RawMeat()); 
    Interfaces IN PHP are very useful in this kind of situations, but mostly they are pretty useless.

  2. #52
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could of course just implement a method on the object called mustBeCooked() and then do:

    PHP Code:
    if($obj=>mustBeCooked()) {
      @
    obj->cookMe();
    }
    $obj->eatMe(); 

  3. #53
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Luke Redpath View Post
    You could of course just implement a method on the object called mustBeCooked() and then do:

    PHP Code:
    if($obj=>mustBeCooked()) {
      @
    obj->cookMe();
    }
    $obj->eatMe(); 
    That's cute, but how is that any better? It requires convention, it requires end-user code to be written and tested, errors won't be flagged early and it has to be well documented. Maybe you don't like the syntax or something similar and it is causing a general bias against a feature that does have valid use cases?

  4. #54
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots View Post
    That's cute, but how is that any better? It requires convention, it requires end-user code to be written and tested, errors won't be flagged early and it has to be well documented. Maybe you don't like the syntax or something similar and it is causing a general bias against a feature that does have valid use cases?
    Since when has the purpose of interfaces been to *implement* behaviour? Thats the whole point of methods on an object - to implement behaviour. I don't really get your other points...all code needs to be tested. And as for having to write code...well duh. You could say the same thing about the interface code. It doesn't make any sense.

    Even if you can make a case for interfaces, implementing behaviour is *not* their purpose.

  5. #55
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Luke Redpath View Post
    Since when has the purpose of interfaces been to *implement* behaviour? Thats the whole point of methods on an object - to implement behaviour. I don't really get your other points...all code needs to be tested. And as for having to write code...well duh. You could say the same thing about the interface code. It doesn't make any sense.

    Even if you can make a case for interfaces, implementing behavior is *not* their purpose.
    Did I say implement behaviour? No, not at all. My point about writing code is that where you have to implement a method (which must be tested) that is used to simulate the test that a typehint would provide, using an interface obviates that need.

    I have made a clear case for interfaces, as have others. You can continue to refuse to accept their uses but I still think it shows a unwarranted bias.

    Best regards.

  6. #56
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In the example above, the fact that meat needs to be cooked first is what I would call behaviour/domain logic, not just a check to see if a certain interface is implemented. Therefore it requires a proper, tested implementation. Or are we just going to abandon boolean methods all together and replace them with type checking???

    In fact, I'd be inclined to encapsulate this even further by moving the check into the Meat object under a more unified API - the check, whether done with an interface or a method - seems a bit smelly. This would be a better design IMO:

    PHP Code:
    class Meat {
      public function 
    prepare() {
        
    $this->cook();
      }
    }

    class 
    Apple {
      public function 
    prepare() {
        
    $this->peel();
      }
    }

    class 
    Consumer {
      public function 
    consume($food) {
        
    $food->prepare();
        
    $this->eat($food);
      }


  7. #57
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots View Post
    That's cute, but how is that any better?
    From a TDD perspective, it's better because the code would come about naturally as part of making a test pass. A type hint can not make a failing test pass (unless you're testing for a failing type hint, I suppose), so from a TDD viewpoint, they are basically useless; they're never "the simplest thing that will work".

  8. #58
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    From a TDD perspective, it's better because the code would come about naturally as part of making a test pass..
    I can actually imagine the code starting off as some simple boolean checks that are then extracted into a boolean method.

  9. #59
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There seems to be a misconception about the use of interfaces and typehints in this thread. Bringing up the TDD angle is specious because where TDD is a design tool, interfaces and typehints are meant to serve a different purpose altogether. They aren't necessarily used to help you better design your code -- in fact, for the case I gave, they are used to help ensure that user code will stay within the limits that you were able to test your supplied code under. Is it so hard to see the point that that distributed development ought not merely rely on a closed-loop design-testing regime?

    Anyways, this doesn't seem to be going anywhere productive, so I'll let you guys have the last word

  10. #60
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    class Meat {
      public function 
    prepare() {
        
    $this->cook();
      }

    That's actually another thing I don't like in php5 code: visibility. There's the same testing argument: what test would fail if something which ought to be "private" (in the general sense) is actually public? Luckily I can just ignore it - at least until someone decides to enforce "best practices" and makes it a fatal error.

  11. #61
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    On the food example, it seems to me there are questions that haven't been asked yet. Is the conditional statement in the right class, and should it exist at all?

    How about this?
    PHP Code:
    $obj->cookMe();
    $obj->eatMe(); 
    This works if the Apple class has a null implementation of cookMe():
    PHP Code:
    class Apple extends Food {
        public function 
    cookMe() {}

    Or move all of it to the Food hierarchy:
    PHP Code:
    $obj->prepareAndEatMe(); 
    In general, explicit tests on the types of objects tend to be frowned upon by object gurus. The problem is that if you add more types, you need to change the conditional statement. If you handle it by polymorphism, there are fewer places to make changes. You might argue that that's not the case in this particular example, but this is the general principle. This is what's known as the Liskov Substitution Principle, or closely related to it.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  12. #62
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots View Post
    There seems to be a misconception about the use of interfaces and typehints in this thread. Bringing up the TDD angle is specious because where TDD is a design tool, interfaces and typehints are meant to serve a different purpose altogether.
    I think you're misunderstanding the TDD point of view. If you're doing true TDD, every single line of code you write, you write to pass a test, and since type hints and interfaces don't help pass tests, you don't use them. They may serve a different purpose, but they just don't fit into the TDD mindset. Sure, you could write tests, and then add some type hints, but then it's not strictly TDD anymore.

    This isn't to say that strict TDD is the best way to develop software, but if you do use strict TDD in PHP, you very likely won't be using typehints.

    Quote Originally Posted by jayboots View Post
    They aren't necessarily used to help you better design your code -- in fact, for the case I gave, they are used to help ensure that user code will stay within the limits that you were able to test your supplied code under. Is it so hard to see the point that that distributed development ought not merely rely on a closed-loop design-testing regime?
    See, this is what I don't understand; why this worry about users staying within the limits of your code? I find it almost condescending. Unless the consequences of a typing error are very serious, the chances of the user making typing errors are so low that I don't find it's worth the extra complexity and loss of flexibility. If the danger really is great, then go ahead and use typehints, but if the users of your library are often making typing errors, maybe that's a sign of a problem with your design? Rather than force them into working in a specific way, maybe adjust your code so that it accepts a wider range of types?

  13. #63
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ...just when you think you are out, they drag you back in

    Quote Originally Posted by 33degrees View Post
    See, this is what I don't understand; why this worry about users staying within the limits of your code? I find it almost condescending.
    Because that is all that I tested for. Because when a user passes a misconstructed object, they automatically get a nice message that tells them what they will need to conform to (without breaking my code). Because in the long-run, it is a much easier and simpler solution. Staying within the limits here means that they simply have to adopt an interface so that my code knows for certain that the method signatures it will try to call will really be there. I am not forcing them into a jail cell where their every move is restricted. My library code that they are using (and relying on) is not intended to be refactored by them; it is like a black-box so TDD practices performed by them should not include coverage for the code which I delivered to them.

    Now how is it that hard-core testing advocates can so quickly dismiss errors that may arise? Please don't pretend these are just spelling errors. Users will pass wrong objects (or not even objects at all) at the worst possible time. You can rightly take the view that they should do their own testing but reasoning that through, it becomes apparent that they almost certainly will eventually have to write tests that covered my code -- and that isn't even nearly fair.

    BTW, TDD does not mandate what syntax, style or even semantics to use: in short, TDD does NOT say how to implement. So I can't see how you can assert that it bars typehints and interfaces.

    Best.

  14. #64
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots View Post
    Now how is it that hard-core testing advocates can so quickly dismiss errors that may arise?
    Because they don't think the errors you're referring to happen often enough to worry about? This is what the argument comes down to. You think type errors are worth putting in type hints to check for, I (and others) don't. I doubt we'll be able to change each other's minds about that, so we'll have to agree to disagree .

    Quote Originally Posted by jayboots View Post
    BTW, TDD does not mandate what syntax, style or even semantics to use: in short, TDD does NOT say how to implement. So I can't see how you can assert that it bars typehints and interfaces.
    Because typehints and interfaces are not the simplest thing that will work? TDD doesn't say how to implement, but it changes how you end up implementing anyway, as you will tend to implement the things that satisfy the methodology. If you can't see how TDD and typehints are incompatible, then you simply haven't drunk deeply from the TDD Koolaid.

  15. #65
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by jayboots
    TDD practices performed by them should not include coverage for the code which I delivered to them.
    They will however have integration tests with your code in the mix and these will fail if their own is not compatible. They might also have unit tests where they've mocked some of your objects.

    Personally I don't see the library code argument for hinting. Hints are a poor tool for making checks. Simultaneously they feel like too much and not enough. I think that's because they are fundamentally in the wrong place: the place to make checks is in the tests. What users really need is some documentation explaining how to write classes for use with your library. After that I think it's their responsibility to test their own code.

  16. #66
    SitePoint Addict
    Join Date
    Aug 2003
    Location
    Toronto
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    you simply haven't drunk deeply from the TDD Koolaid.
    Right you are. I try to keep an open mind (yes, that was a joke!)
    Quote Originally Posted by McGruff
    Personally I don't see the library code argument for hinting. Hints are a poor tool for making checks. Simultaneously they feel like too much and not enough. I think that's because they are fundamentally in the wrong place: the place to make checks is in the tests. What users really need is some documentation explaining how to write classes for use with your library. After that I think it's their responsibility to test their own code.
    No, I really disagree. You don't check your passed types in your tests--you somehow do it in the method (which is the point of the typehint). Passed objects are very much like user supplied data in that your code has to take responsibility for it: you can not test-case it away. As for documentation, that's an important feature of interfaces and typehints to begin with.

    Anyways, I really will bow out this time! Thanks for the discussion guys!

  17. #67
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Bogota
    Posts
    101
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for the late reply,

    Quote Originally Posted by Luke Redpath View Post
    Thats the whole point of TDD - you don't write code until you have a failing test. If its already passed without the type hint, you can stop.
    No, You might write code after the test passes. For example, to remove duplication. You refactor.

    I myself think that you can refactor for clarity, to make your intention clear to a 3rd party reading the code .

    I value clarity. I hated people playing "tdd perl golf".

    A
    If I have wings, why am I walking?

  18. #68
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Bogota
    Posts
    101
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    If you're doing true TDD, every single line of code you write, you write to pass a test
    Where can I read this?

    I understand you don't write code to meet a requirement that doesn't exist yet. But that does not imply that you stop the TDD cycle when you pass the test. You still need to refactor and that might mean writing new code.

    Or am I missing something?
    If I have wings, why am I walking?

  19. #69
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by otnemem View Post
    Sorry for the late reply,



    No, You might write code after the test passes. For example, to remove duplication. You refactor.

    I myself think that you can refactor for clarity, to make your intention clear to a 3rd party reading the code .

    I value clarity. I hated people playing "tdd perl golf".

    A
    Of course you refactor but I can't see why I'd ever want to refactor to using type hints.

  20. #70
    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 jayboots View Post
    Now how is it that hard-core testing advocates can so quickly dismiss errors that may arise? Please don't pretend these are just spelling errors. Users will pass wrong objects (or not even objects at all) at the worst possible time. You can rightly take the view that they should do their own testing but reasoning that through, it becomes apparent that they almost certainly will eventually have to write tests that covered my code -- and that isn't even nearly fair.
    I think I agree with you. Or maybe with the others. Or both.

    Here's my overall view of it. If you have good test coverage, type checking inside the part of the system that you control is usually not necessary. But checking at the boundaries may be a good idea. That goes both ways: at the top, checking data that's passed in; at the bottom, checking for errors from the file system, network or databases.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  21. #71
    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 dagfinn View Post
    I think I agree with you. Or maybe with the others. Or both.
    Pretty much the same here.

    I like this TDD argument, but what perplexes me about it is the assumption that getting the tests passed is the only purpose of a computer program. In fact, however, a program is not only a device, that should perform its function and nothing more, a program is also a communication medium, a text intended to be read by other people. While "the simplest possible" principle will work perfectly for devices, the readability is all about superfluity. In many languages, t's prfctl pssbl t skp vwls n wrtng, but would we do that? Why not to think about 'typehints' in php as a readability feature like proper formatting or sensible variable naming. Strictly speaking, we don't "need" this, but "allow not nature more than nature needs..."

  22. #72
    Put your best practices away. The New Guy's Avatar
    Join Date
    Sep 2002
    Location
    Canada
    Posts
    2,087
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    "A nerd who gets contacts
    and a trendy hair cut is still a nerd"

    - Stephen Colbert on Apple Users

  23. #73
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > If you're doing true TDD, every single line of code you write, you write to pass a test

    You test the classes behaviour, to be sure that what it does, is what it's meant to do; What is expected in jargon if you want.

    Wether you need to test the entire class or not is purely dependent on the class in my view, since there are times where the class has methods declared private, for example

  24. #74
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    a program is not only a device, that should perform its function and nothing more, a program is also a communication medium, a text intended to be read by other people
    Absolutely. If there's a choice between an easier to read implementation which is a couple of lines longer and a shorter, harder to understand one the former is the one to go for. Test-first isn't a form of perl golf it's more about not adding anything without good reason. Everything has to justify itself as an essential part of the program and clearer code should have no trouble doing that. The point is that unecessary complexity will make code harder to refactor. You could say that hints can help by making it easier for automated refactoring tools (although I don't think they're essential). On the other hand it's one more thing you might have to hunt down and edit...

  25. #75
    SitePoint Guru
    Join Date
    Feb 2006
    Location
    Pittsburgh, Los Angeles
    Posts
    706
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you want to deal with events in a GUI the way AWT actually invokes your event listeners is by checking the interface they implement:
    Java has to have interfaces, in a dynamically typed language you can just check if the class has a particular method which is easy. Generally if you have a bunch of "instanceof" statements in your code base its not very good (awt isn't very good).


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
  •