SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 52
  1. #26
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by LastCraft
    If a method doesn't involve properties or methods in that class, what the heck is the method doing in that class? Move it to the caller.

    If it's duplicated in several client classes then you probably have a design problem. If it's so generic it still appears in several classes, and there is too much code to simply duplicate it (more than a one liner), you'll still probably want to have an instance. That way you can test the client code more easily
    Honestly, I agree entirely. Those functions don't belong there - in fact their only reasoning is the naming.

    But my point is that if you are going to have a function which doesn't involve the object, why instantiate the object in the first place?

    The ultimate solution would be to move them to the global namespace. But my point is, its better (IMO) to have a method static within a class than having to instantiate an object where it isn't needed.


    As for frameworks, personally I find nothing beats writing your own.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  2. #27
    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 arkinstall View Post
    The ultimate solution would be to move them to the global namespace.
    Yes, and that's exactly what a static member is -- Bound to a global scope. While it is a solution, it's only ultimate in the sense that it's the worst possible solution; The global scope is by definition the most general scope there is, so consequently it's also the most meaningless (As in - devoid of meaning). In effect, any other solution is more precise. Since one of the most fundamental goals of application design (And really, in any kind of communication) is to strike the proper balance between being specific and being abstract, using the global scope is a fail, in the same way that using no abstraction at all is it (But at the other end of the scale).

  3. #28
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This old good fear of global ...

    If I have different helper functions utilizable within whole application, why should I close them to instantiated class? In this case are classes with static methods suitable solution.
    PHP Code:
    Validator::IsEmail($string)
    Validator::IsZIP($string);

    DBStructure::TableExists($table)
    DBStructure::IsDateField($field$table
    etc. etc.

  4. #29
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mastodont View Post
    This old good fear of global ...
    Ah, the good old lack of understanding why using the global scope is bad.

    Quote Originally Posted by Mastodont View Post
    If I have different helper functions utilizable within whole application, why should I close them to instantiated class? In this case are classes with static methods suitable solution.
    PHP Code:
    Validator::IsEmail($string)
    Validator::IsZIP($string);

    DBStructure::TableExists($table)
    DBStructure::IsDateField($field$table
    etc. etc.
    Because you can't mock the object, or replace them with objects with slightly different behaviour, which is a key aspect of object oriented programming.

    But seriously, this is not what this topic is about. Shouldn't we open a new topic to get this settled?

  5. #30
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Shouldn't we open a new topic to get this settled?
    I think that we already have got flame threads about this here, but I agree that we are out of topic here.

    good old lack of understanding why using the global scope is bad
    Native PHP functions are global. Constant are global. UDF are global. Why not classes? I am fine with global space, used to choose different hammer for each type of task. There is no wrong hammer.
    By the way, there MUST be some global context, mustn't it? How could you use some factory for generating objects, if this factory is not globally visible? Even Zend has
    PHP Code:
    Zend_Registry::getInstance()
    Zend_Controller_Front::getInstance()
    Zend_Db::factory() 
    Wow, global and static evil! How could they do it?

    you can't mock the object
    Well, I do never plan to mock these simple helpers. They can be tested directly.

  6. #31
    Use The Cloud
    Join Date
    Jan 2006
    Location
    Boise, ID
    Posts
    556
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wysiwyg View Post
    Brad,
    let's say you have two classes. One class uses the other class and calls it's methods, something like this:
    PHP Code:
    <?php
    class Foo {
      function 
    __construct() {
        
    Bar::someDestructiveMethod();
        
        
    $this->setup();
      }
      function 
    setup() {

      }
    }
    ?>
    Suppose you'd want to test this with a unit test, and you realize that Bar::someDestructiveMethod() performs some destructive logic that you don't want to run every time you want to run your test. You would either have to add a conditional inside that method, or you could solve it by removing the static call:
    PHP Code:
    <?php
    class Foo {
      function 
    __construct($bar) {
        
    $bar->someDestructiveMethod();
        
        
    $this->setup();
      }
    }

    class 
    MockBar extends Bar {
      function 
    someDestructiveMethod() {
        return 
    false;
      }
    }

    // Real world
    new Foo(new Bar());

    // Testing
    new Foo(new MockBar());
    ?>
    The code becomes more flexible when you can change which objects you want to pass in during runtime. With static calls, you can't do that. You could always add logic to the static methods so you get increased flexibility, but then those methods would get bloated really quickly. But then you lose the power of polymorphism, and you would still be stuck with the hard coded class, whereas passing in an instance instead allows you to pass in whatever class you want, as long as it implements the correct interface.
    It becomes more flexible because you designed it to be more flexible, NOT because you simply removed static. The logic you provided to explain your example is a fallacy.

    An equivalent to the "hardcoded" static Foo you provided would be:

    PHP Code:
    <?php
    class Foo {
      function 
    __construct() {
        
    $bar = new Bar();
        
    $bar->someDestructiveMethod();
        
        
    $this->setup();
      }
      function 
    setup() {

      }
    }
    ?>
    Which still has the exact same limitation. This limitation is caused by a design flaw and has nothing to do with declaring static.

    In the second example where you pass in an object, that also has nothing to do with declaring static. That code will work exactly the same whether or not someDestructiveMethod() is declared static, except when you remove static you're limiting the scope for which the method can be applied.

    Declaring static does not mean you should use it in a static context all of the time, I thought I made that clear in my last post.
    Brad Hanson, Web Applications & Scalability Specialist
    ► Is your website outgrowing its current hosting solution?
    ► PM me for a FREE scalability consult!
    ► USA Based: Available by Phone, Skype, AIM, and E-mail.

  7. #32
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    A method I've been trying out lately to allow fluid relationships between objects is, rather than pass an object it's containing object, or pass the object to its container to be stored in an array, the object is given an ID of its container (in this case its container's container, a MapperCollection).

    This MapperCollection allows the CommentMapper, PageMapper, ArticleMapper and TopicMapper to be accessed with a simple call.

    So, when an article is instantiated it saves the ID of this mapper collection and a method is defined for getting it's mappercollection. Each Mappercollection is stored in a static array to be retrieved by an ID (i.e. a static registry).

    So, the article gets its mappercollection by:
    PHP Code:
    MapperCollection::get($this->id); 
    Are you seriously suggesting that the mappercollections be stored in an instantiated object's array rather than stay static?

    There can be a time when you want multiple databases, which is what my system seemlessly allows for... how much further do we need to go with this?

    Oh, and there are great results from my method. Using two versions, exactly the same other than the relationships are solid - there is a 86&#37; speed increase.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  8. #33
    SitePoint Zealot Amenthes's Avatar
    Join Date
    Oct 2006
    Location
    Bucharest, Romania
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bhanson View Post
    In the second example where you pass in an object, that also has nothing to do with declaring static. That code will work exactly the same whether or not someDestructiveMethod() is declared static, except when you remove static you're limiting the scope for which the method can be applied.
    I don't really understand this. Could you give an example.

    @Mastodont, you know, not everyone knows how to extend
    Zend_Controller_Front, and this is due to the protected constructor (which
    as far as I know was private in the beginning), the static method
    getInstance() and Late Static Binding. Honestly, it makes no sense to impose
    such restrictions on the creation of Zend_Controller_Front, my guess is that
    it is a Singleton mainly because a few years ago, when the PHP community
    found about design patterns, Singleton was by far the easiest to grasp. Even
    today, every developer starting to learn about patterns will spread all over
    his code lots of singletons (been there, done that).

    The main reason I avoid static function calls is because of late static binding.
    (IMHO) The only reasonable use for static methods and properties is when
    you want some state to be shared by all instances and you really know it's
    gonna be multiple instances. Nevertheless, this can be avoided too in order
    to facilitate testing. One example inside ZF using a static method which I
    found it to be useful is Zend_Db_Table_Abstract::setDefaultAdapter(). And
    supposing you have a peculiar table which needs some other adapter, you
    have the possibilities to do just that.

    On the same note, I really don't like Zend_Controller_Action_HelperBroker

    A static member is pretty much as the prototype inside JS. I said "pretty
    much" because we don't yet have all the means to achieve this. The idea is
    that we may have state (properties) shared by all the instances of the class.
    If you find yourself using a static method just because your framework is
    "fully OOP" then there's something wrong in there.
    I'm under construction | http://igstan.ro/

  9. #34
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:

    @Amenthes, is there a reason that you newline after a certain line length? On my monitor the text is squished in the left half rather than filling the space.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  10. #35
    SitePoint Zealot Amenthes's Avatar
    Join Date
    Oct 2006
    Location
    Bucharest, Romania
    Posts
    143
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Off Topic:

    @arkinstall, yes. It's like the 79/80 char print line in editors. IMO makes text easier to read. Do you find it annoying?
    I'm under construction | http://igstan.ro/

  11. #36
    Use The Cloud
    Join Date
    Jan 2006
    Location
    Boise, ID
    Posts
    556
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Amenthes View Post
    I don't really understand this. Could you give an example.
    PHP Code:
    <?php

    class Foo
    {
        public static function 
    staticMethod()
        {
            
    // Code that doesn't need $this
        
    }

        public function 
    method()
        {}
    }

    // Calling staticMethod() statically
    Foo::staticMethod();

    // This still works, since $foo is an instance of Foo!  Except since it's
    // declared statically you're not forced to create an instance of Foo if all you
    // need to do is call staticMethod().
    $foo = new Foo();
    $foo->staticMethod();

    // This is bad!  I think PHP may "let" you attempt to call the function this way
    // because of legacy reasons, but should never, ever do this.  If method uses
    // $this at all then calling it like this will fail.  If it needs $this then it
    // also shouldn't be static and should never be called like this anyway.  If it
    // does not need $this, then it SHOULD be declared static as usage like this is
    // possible and is a much clearer definition.
    Foo::method();
    Brad Hanson, Web Applications & Scalability Specialist
    ► Is your website outgrowing its current hosting solution?
    ► PM me for a FREE scalability consult!
    ► USA Based: Available by Phone, Skype, AIM, and E-mail.

  12. #37
    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 bhanson View Post
    PHP has global scope, but it doesn't have namespaces. In PHP singletons help from trashing your global namespace.
    Namespaces are overrated. What is the functional difference between, say, Namespace::function() and namespace_function()? I know that, with namespaces, you can declare the namespace you use and then call methods without declaring their namespace each time, but personally I'd always rather have the namespace explicit on each call.

    Also, OOP is all about behavior, which is implemented through instance method calls. As Marcus has said above, if method is generic enough that it doesn't use any of an instance's state, it really don't belong to that object. The point of OOP are objects -- as opposed to classes -- and their interaction; a few weeks working with Javascript will teach you that.

  13. #38
    Use The Cloud
    Join Date
    Jan 2006
    Location
    Boise, ID
    Posts
    556
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac View Post
    Namespaces are overrated... a few weeks working with Javascript will teach you that.
    On any large project, namespaces or at least pseudo-namespace functionality is pretty much required. Have you ever worked on a large project? Or perhaps a project in another language such as C++?

    What is the functional difference between, say, Namespace::function() and namespace_function()?
    PHP doesn't implement true namespaces anyway (yet). It does have autoclass loading and a very common design technique is one class per file. Do you suggest one function per file? Do you know how much of a mess it would be to include a file for every function used? Not to mention you'd either be passing a rediculous number of variables by reference or using the global keyword and getting your geek card taken away.
    Brad Hanson, Web Applications & Scalability Specialist
    ► Is your website outgrowing its current hosting solution?
    ► PM me for a FREE scalability consult!
    ► USA Based: Available by Phone, Skype, AIM, and E-mail.

  14. #39
    SitePoint Guru
    Join Date
    Nov 2003
    Location
    Huntsville AL
    Posts
    706
    Mentioned
    4 Post(s)
    Tagged
    1 Thread(s)
    Readers should be aware that calling a static method dynamically can generate warnings. Probably something to avoid.

    ===
    I stand corrected. No warnings are generated with PHP 5.2.x though they used to be under PHP 5.1.x
    Last edited by ahundiak; Jan 7, 2009 at 08:38.

  15. #40
    Use The Cloud
    Join Date
    Jan 2006
    Location
    Boise, ID
    Posts
    556
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    Readers should be aware that calling a static method dynamically can generate warnings. Probably something to avoid.
    Show us one case where calling a static method dynamically will generate a warning.
    Brad Hanson, Web Applications & Scalability Specialist
    ► Is your website outgrowing its current hosting solution?
    ► PM me for a FREE scalability consult!
    ► USA Based: Available by Phone, Skype, AIM, and E-mail.

  16. #41
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Actually, it's the other way around: calling a non-static method statically will result in a notice:

    berry@berry:~&#37; cat sp-test.php
    <?php
    error_reporting( E_ALL ^ E_STRICT );
    class Foo
    {
    public static $a = 'test';
    static public function bar( )
    {
    return self::$a;
    }

    public function test( )
    {
    return 'another test';
    }
    }

    $foo = new Foo( );
    echo $foo->bar( );
    echo Foo::test( );
    ?>

    berry@berry:~% php sp-test.php
    test
    Strict Standards: Non-static method Foo::test() should not be called statically in /home/berry/sp-test.php on line 19
    another test

  17. #42
    Use The Cloud
    Join Date
    Jan 2006
    Location
    Boise, ID
    Posts
    556
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ahundiak View Post
    though they used to be under PHP 5.1.x
    Pretty sure they didn't, can you find a case where it does?

    No warning on 5.1.4
    Brad Hanson, Web Applications & Scalability Specialist
    ► Is your website outgrowing its current hosting solution?
    ► PM me for a FREE scalability consult!
    ► USA Based: Available by Phone, Skype, AIM, and E-mail.

  18. #43
    SitePoint Addict
    Join Date
    Feb 2007
    Posts
    251
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wysiwyg View Post
    Suppose you'd want to test this with a unit test, and you realize that Bar::someDestructiveMethod() performs some destructive logic that you don't want to run every time you want to run your test. You would either have to add a conditional inside that method, or you could solve it by removing the static call:
    PHP Code:
    <?php
    class Foo {
      function 
    __construct($bar) {
        
    $bar->someDestructiveMethod();
        
        
    $this->setup();
      }
    }

    class 
    MockBar extends Bar {
      function 
    someDestructiveMethod() {
        return 
    false;
      }
    }

    // Real world
    new Foo(new Bar());

    // Testing
    new Foo(new MockBar());
    ?>
    Another way to isolate such a dependency would be to wrap it in a Foo method...

    PHP Code:
    class Foo {
      function 
    __construct() {
        
    $this->someDestructiveMethod();
        
    $this->setup();
      }
      protected function 
    someDestructiveMethod() {
        return 
    Bar::someDestructiveMethod();
      }

    Then you would override the dependencies in your test case...

    PHP Code:
    class FooWithTestDeps extends Foo {
      protected function 
    someDestructiveMethod() {
        
    $bar = new MockBar();
        return 
    $bar->someDestructiveMethod();
      }

    Not the prettiest solution obviously, but it works.

  19. #44
    SitePoint Zealot
    Join Date
    Dec 2007
    Location
    Baltimore, MD
    Posts
    103
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cuberoot View Post

    Not the prettiest solution obviously, but it works.
    That's not at all pretty. If I had to do that when writing a test, I would quit writing tests. So, you're not really testing Foo at this point. You're testing a class that inherits from Foo.

    Further, Foo now has a hidden dependency on Bar. That makes me cringe.

    static methods have their uses, but I avoid the singleton pattern as much as possible. And globals are OK? Some of you love hiding all kinds of things in your code.
    Shane Bauer
    .NET and Ruby on Rails

  20. #45
    SitePoint Zealot
    Join Date
    Dec 2007
    Location
    Baltimore, MD
    Posts
    103
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arkinstall View Post

    The ultimate solution would be to move them to the global namespace.
    Not sure how that's the ultimate solution. Instead of finding a truly meaningful place for something, your goal is to dump it off in some global god area for later confusion.

    Quote Originally Posted by arkinstall View Post
    As for frameworks, personally I find nothing beats writing your own.
    Except for the fact that you have to maintain it going forward. Nothing beats writing it at the time, but I would rather not write an MVC Framework or an IoC container when someone has already created one that suits my needs.
    Shane Bauer
    .NET and Ruby on Rails

  21. #46
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    True, however as we all know, Frameworks are built to work with a large variety of applications - which means there can be alot of stuff you just don't need in there.

    Not sure how that's the ultimate solution. Instead of finding a truly meaningful place for something, your goal is to dump it off in some global god area for later confusion.
    Yes, but the question is - where is that?

    Here's my point with a little more clarification:

    Very bad:
    PHP Code:
    class SomeClass{
        public 
    $One$Two$Three;
        function 
    __Construct(){
            
    $this->One 1;
            
    $this->Two 2;
            
    $this->Three 3;
            echo 
    $this->HelloWorld();
        }
        function 
    HelloWorld(){
            return 
    'Hello World'//Nothing to do with members or methods
        
    }

    Not quite so bad:
    PHP Code:
    class SomeClass{
        public 
    $One$Two$Three;
        function 
    __Construct(){
            
    $this->One 1;
            
    $this->Two 2;
            
    $this->Three 3;
            echo 
    self::HelloWorld();
        }
        static function 
    HelloWorld(){
            return 
    'Hello World'//Nothing to do with members or methods
        
    }

    Better:
    PHP Code:
    class SomeClass{
        public 
    $One$Two$Three;
        function 
    __Construct(){
            
    $this->One 1;
            
    $this->Two 2;
            
    $this->Three 3;
            echo 
    HelloWorld();
        }
    }
    function 
    HelloWorld(){
        return 
    'Hello World'//Nothing to do with members or methods

    (Btw, it's an example - I know such a function wouldn't be in the class in the first place, but there can be occurances where this isn't the case)
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  22. #47
    SitePoint Zealot
    Join Date
    Dec 2007
    Location
    Baltimore, MD
    Posts
    103
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arkinstall View Post
    True, however as we all know, Frameworks are built to work with a large variety of applications - which means there can be alot of stuff you just don't need in there.
    Well, don't use it. They're not forcing you to use it. Castle Windsor is a beast of an IoC container. I don't use all of its features, but that's not going to stop me from using it. If something was overly complicated and/or had a lot of friction to it, I would then look at other options.

    Quote Originally Posted by arkinstall View Post
    Yes, but the question is - where is that?
    That depends on what it's doing. Since I don't know the role "Hello World" is actually playing in the system, then I really can't tell you. Do you have a real life example of something?

    I think we're all caught up in these very random, obtuse examples. Instead of trying to prove something based on code that's not real, we should post real examples of problems and try to figure out how we would improve them.
    Shane Bauer
    .NET and Ruby on Rails

  23. #48
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Do you have a real life example of something?
    Not personally, because I don't use any static other than a register of mappercollections as explained above - and that's just there for monitoring; it doesn't effect the application itself.

    My point is it can be justified in certain situations.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  24. #49
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm just reading Robert C. Martin's Clean Code. On static methods:
    In general you should prefer nonstatic methods to static methods. When in doubt, make the function nonstatic. If you really want a function to be static, make sure that there is no chance that you'll want it to behave polymorphically.
    A workaround or alternative in some cases might be to have an instantiated object hiding behind a static method. That would make it possible to keep the option of configuring behavior by replacing the object.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  25. #50
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dagfinn View Post
    I'm just reading Robert C. Martin's Clean Code.
    Off topic: I've just bought this book after reading a sample online, it seemed really well written and held my attention, how are you finding it dagfinn?
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.


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
  •