Skip to main content

Static methods: are they still bad considering PHP 5.3 late static binding?


If you search on the reasons why static methods are bad the first thing you find it is because you can't override it when you are unit testing.



So is this still true considering in PHP 5.3 you can do whatever you want with the introduction of static:: ?



Add:



http://sebastian-bergmann.de/archives/883-Stubbing-and-Mocking-Static-Methods.html



Note he explains even how to use singleton without any testing problem:



Source: Tips4allCCNA FINAL EXAM

Comments

  1. If you have a static member function, it could usually be a free function. The usual reaction is then that the coder has opted for a static member function only because of the myth that "everything must be in an object".

    That's why people discourage them.

    And, because it's not a very convincing argument, those people pointed to unit testing instead. Not sure what they'll do now.

    ReplyDelete
  2. Static methods aren't bad in themselves. Sometimes certain operations don't make sense to require a particular object to do. For example, a function like square root would make more sense being static.

    Math::sqrRoot(5);


    rather than having to instantiate a Math 'object' and then call the function.

    $math = new Math();
    $result = $math->sqrRoot(5);

    ReplyDelete
  3. More difficult to test is a reason but not the only one. Static methods provide global access, and global access is bad.

    Of course, you'll find that there's another global access to objects and that's creating one with 'new'. Objects have to be created somewhere so we can't eliminate that (though minimizing it is a good idea). Static methods as global access to a class is bad, unless it is there to replace 'new' through higher level programming:

    $user = new User();
    $user->setPointsTo(100);

    // vs

    $user = User::with100StartingPoints();


    In this case I created code that is more readable while not misusing global access (the 'new' needed to be called anyway).

    Edit: Let me give you an example in the way static methods 'can' be the death of testability (note how in the example above you don't even need to mock the static method but can easily test the new and static method produces the same result). Let's use your logger example:

    class Logger {
    public static function log($text) { // etc }
    }

    class AccessControl {
    public function isAllowed(User $user, $action) {
    // do stuff, determine if $allowed
    if (!$allowed) {
    Logger::log('user X was not allowed to do Y');
    }
    // do stuff
    }
    }


    There is no way we can test this method cleanly because of the global call to Logger::log. It will depend on the correct working of the Logger class.

    ReplyDelete

Post a Comment

Popular posts from this blog

Why is this Javascript much *slower* than its jQuery equivalent?

I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later): $('#filter').keyup( function() { var jqStart = (new Date).getTime(); var search = $(this).val().toLowerCase(); var $list = $('ul.ablist > li'); $list.each( function() { if ( $(this).text().toLowerCase().indexOf(search) === -1 ) $(this).hide(); else $(this).show(); } ); console.log('Time: ' + ((new Date).getTime() - jqStart)); } ); However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each function is particularly slow). Here's my JS equivalent: document.getElementById('filter').addEventListener( 'keyup', function () { var jsStart = (new Date).getTime()...

Is it possible to have IF statement in an Echo statement in PHP

Thanks in advance. I did look at the other questions/answers that were similar and didn't find exactly what I was looking for. I'm trying to do this, am I on the right path? echo " <div id='tabs-".$match."'> <textarea id='".$match."' name='".$match."'>". if ($COLUMN_NAME === $match) { echo $FIELD_WITH_COLUMN_NAME; } else { } ."</textarea> <script type='text/javascript'> CKEDITOR.replace( '".$match."' ); </script> </div>"; I am getting the following error message in the browser: Parse error: syntax error, unexpected T_IF Please let me know if this is the right way to go about nesting an IF statement inside an echo. Thank you.