0

I am confused whether to use static method or just simple method.

Lets me give an example, I am using Zend framework 1 project.
I have class like

class Example1
{
    public static function getVariable() {
       return is_numeric(Zend_Registry::get('config')->Variable) ? Zend_Registry::get('config')->Variable : 0;
    }

    public function calculateSome($param1, $param2) {
        $response = array();
        if($param2 == 0) { 
              $response = number_format(($param1 * self::getvariable()) /100);
        } else {
              $response = $param1;
        }
        return $response;
    }
}

Usage :

  1. Currently i'm getting variable value like Example1::getVariable() in whole project.
  2. And Calculating like first instantiating a class $class1 = new Example1(); and then calling the function like $class1->calculateSome(1, 0);

I am confused whether it is good to change calculateSome() to public static and call like this Example1::calculateSome(1, 0) or left as it is.

I Have found link when to use static => When to use static vs instantiated classes

But I can't understand what it says.

Community
  • 1
  • 1
udgeet patel
  • 439
  • 1
  • 7
  • 23
  • 3
    Long answer: [How Not To Kill Your Testability Using Statics](http://kunststube.net/static/) – deceze Aug 21 '14 at 11:19

2 Answers2

3

You can find the long answer here: How Not To Kill Your Testability Using Statics

The TL;DR version of it is:

  • A static method is nothing more than a namespaced function, Foo::bar() does not significantly differ from foo_bar().
  • Whenever you call a static method, or a function for that matter, you're hardcoding a dependency. The code that reads $bar = Foo::bar(); has a hardcoded dependency to a specific Foo class. It is not possible to change what Foo refers to without changing that part of the source code.
  • An object is a "soft" dependency. $bar = $foo->bar(); is flexible, it allows room to change what $foo refers to. You use this with dependency injection to decouple code from other code:

    function baz(Foo $foo) {
        $bar = $foo->bar();
        ...
    }
    
  • You can call Foo::bar() anytime from anywhere. If Foo::bar has some dependency it depends on, it becomes hard to guarantee that this dependency is available at the time you're calling the method. Requiring object instantiation requires the object's constructor to run, which can enforce requirements to be set up which the rest of the methods of the object can depend on.

  • Constructors together with dependency injecting objects into other functions are very powerful to

    1. create seams in your codebase to make it possible to "take it apart" and put it together in flexible ways
    2. put checks into strategic places to ensure requirements are met for certain parts of the code (at object instantiation time the constructor enforces a sane state of its little part of the world, its object), which makes it a lot easier to localise and contain failures.

    Think of it like compartmentalising your app and putting firewalls between each compartment with a supervisor in charge of each one; instead of everyone just running around in the same room.

  • Any time you write new Class, you may as well write Class::staticMethod(), the hardcoded dependency is the same.

So the decision comes down to:

  • What are the requirements of this class? Does it need to ensure certain preconditions are met before any of its code can run (e.g. a database connection needs to be available), or are all methods just self-contained little helper methods?
  • How likely are you to maybe want to substitute this class for another class? Does this class produce side effects (e.g. writing to a file, modifying some global state) which may not always be desirable and hence a different version of it may be useful under some circumstances?
  • May you need more than one instance of this class at the same time, or is the nature of the class such that there are no individual instances needed?

Start using unit tests, which require you to take your app apart and test each little part individually to ensure it works, and you'll see where the advantage of object instantiation and dependency injection lie.

deceze
  • 510,633
  • 85
  • 743
  • 889
0

When the method involve instance-based properties/changes u should keep it non-static.

If its a method that is needed for the whole type then use static.

For example u can keep tracks of created instances by this snippet:

class Product {
 static $count;
 private $name;

 public function __construct($name) {
    $this->name = $name;
    self::$count++;
 }
 public function getName() {
    return $this->name;
 }
 public static function getCount() {
     return self:$count;
 }
}

$productA = new Product('A');
$productB = new Product('B');

echo $productA->getName(). ' and ' . $productB->getName(). '<br />'. PHP_EOL;
echo 'Total made products :' . Product::getCount();
DarkBee
  • 16,592
  • 6
  • 46
  • 58
  • From my above code, Whether i should change my function to `public static function calculateSome(1,0)` , because this function process some calulation based on parameters passed. – udgeet patel Aug 21 '14 at 11:36
  • If the class was called 'Calculator´ and u don't need the store any instance based members then u could leave it as ´static´ imo – DarkBee Aug 21 '14 at 11:38