panthro
panthro

Reputation: 24061

Instantiated classes vs static classes?

I'm struggling to know whether I should use a static or instantiated class.

I'm not sure I understand why you would use either apart from, a static class should be used to work on data where as a instantiated class has its own data.

I'm not sure how this apples to my work, for example, I have a model that gets data from a database (a list of products).

If my above assumption is correct then I should instantiate the model, as the class has it's own data.

And for example, if I then had a helper class that converted dates, this should be static, as it just returns data in a different format.

Is all of this correct, can anyone explain to me clearer or any sort of rules I should use when deciding between a static and instantiated class?

Upvotes: 2

Views: 196

Answers (2)

deceze
deceze

Reputation: 522024

I've written about this extensively here: How Not To Kill Your Testability Using Statics. To summarise it:

  • static class methods are nothing more than regular functions
  • if you do not instantiate your classes, you may as well not be using classes in the first place, since you're not working with objects and OOP without objects is just P, regular old procedural programming
  • objects are there to decouple and abstract parts of your application; those parts include "data entities" as well as things like a database connector and business logic parts, everything can and should be an object
  • static properties and methods are mostly helpers and used for some special cases, they are not the main focus in object oriented programming and should not be the overarching design philosophy

Choice quote from the linked article:

Obligatory car analogy:

Class Oriented Programming is like buying a car to let it sit in the driveway, opening and closing its doors repeatedly, jumping around on the seats, occasionally turning on the windshield wipers, yet never once turning the ignition key and taking it for a drive. It is missing the point entirely.

Upvotes: 1

kojiro
kojiro

Reputation: 77089

A static class isn't really a thing. You may be talking about a class, as distinguished from an instance of that class. A class can have properties and methods that are declared static using the static keyword. The static keyword applied to a property means you cannot access that property using an instance.

class Foo {
    public static $prop = 123;
}

php > echo Foo::$prop
123
php > $f = new Foo(); $f->prop;
PHP Strict standards:  Accessing static property Foo::$prop as non static in php shell code on line 1

However, you can access static methods either way:

class Bar {
    public static function meth() { echo "Hello, World\n"; }
}
php > Bar::meth()
Hello, World
php > $b = new Bar();
php > $b->meth();
Hello, World

In spirit, a static method is a good thing. It's a commitment that this method's output doesn't depend on the state of the object. But that's not to say it's guaranteed to be stateless, because there's another use for the static keyword: Static variables:

class Baz {
    public static function m() {
        static $callCount = 0;
        echo ++$callCount;
    }
}
php > Baz::m();
1
php > Baz::m();
2
php > $x = new Baz(); $y = new Baz();
php > $x->m();
3
php > $y->m();
4
…

So statics are a way you can store state in the class itself, independent of the instance. You can even use them for message-passing between instances of the same class. To be honest, the valid uses for that are few and far between, and it is hard to cover stateful statics directly with behavioral tests.

Another use for statics is carrying class-specific information. Let's say you want a whole bunch of classes to have a log method that always includes some class-specific information in the log message.

trait Xyzzy {
    public static function log($msg) {
        printf('[%s] %s', static::$_identifier, $msg);
    }
}
class Fuzzy {
    use Xyzzy;
    private static $_identifier = __CLASS__;
}
php > $f = new Fuzzy();
php > $f->log('hello, world');
[Fuzzy] hello, world

So if you feel a static is the right approach, because a method is

  1. Contextually appropriate for the class and stateless, or
  2. Carries state for the class.

Then you should use a static. It can make testing harder, but the tests are here to support you, not get in your way.

By the way, recent versions of PHPUnit can test a subset of static methods using late static bindings.

Upvotes: 2

Related Questions