2

I see these classes quite often but i don't use them in my projects. I was checking these design patters from here and I noted they use static classes

From page above, sample code:

class AutomobileFactory
{
    public static function create($make, $model)
    {
        return new Automobile($make, $model);
    }
}

or in Singleton pattern:

  public static function getInstance()
    {
        static $instance = null;
        if (null === $instance) {
            $instance = new static();
        }

        return $instance;
    }
10
  • The main advantage in the case of these patterns is that they can be called from anywhere in your code: if they were non-static, you'd need to instantiate your factory class, and DI it into every class/method where you were likely to need it Commented Jul 30, 2013 at 14:22
  • There are no static classes in php. You simply can't use them. Commented Jul 30, 2013 at 14:22
  • Your question is not whether you "should" use them, it's "what are factories and singletons?" Commented Jul 30, 2013 at 14:23
  • @MarkBaker but why than using non-static classes anyway, regardless of design patters. For simple projects, why should i write new Class, i could just use these static classes? Commented Jul 30, 2013 at 14:24
  • 1
    @PLB Much simpler: final private function __construct() { } Optionally throw an exception here too. Commented Jul 30, 2013 at 14:32

3 Answers 3

2

I'd recommend you read How Not To Kill Your Testability Using Statics first as intro into what I'll talk about below.

The point of a factory is typically to allow dependency injection for methods/objects that need to instantiate other objects. E.g.:

public function foo() {
    $bar = new Bar;
}

This is bad, as discussed in aforelinked article. But this method must be able to instantiate a Bar object itself. Yet we still want dependency injection.
Enter a factory:

public function foo(BarFactory $factory) {
    $bar = $factory->create();
}

Therefore, a static factory is pretty pointless:

public function foo() {
    $bar = BarFactory::create();
}

There's virtually no advantage over directly instantiating new Bar here.

Singletons are a hotly discussed topic and they're often discouraged, for the same reason that global objects are discouraged. Singletons which are statically being referred to are bad again, as discussed at length in the article.

Sign up to request clarification or add additional context in comments.

Comments

1

The first example is a factory class. A factory is a piece of code that helps you to create and configure an object. A factory can be a function or method, a static class, or an instantiated class. Usually it is not necessary to instantiate a factory, so static classes are often used for that. But I think a factory might as well be instantiated. Doing that allows you to configure or extend the factory so it gives you even more flexibility over having a single static factory method.

Also, I think in most cases static classes are just an excuse. People often tend to promote global functions or variables to a static class to make 'clean' code, but it provides little improvement. It was a little useful before PHP supported namespaces, but nowadays, I think you should be careful when creating static classes.

The same applies to singletons, although it has its use, because in some cases you want to have only one instance of a class. Examples of this include connection pools, or hardware controllers. Having multiple instances of some object might cause problems, so that's a good reason to use singletons. But people often make an object a singleton when there is no need. In that case, I think it's just a way to hide the fact that you're using globals, and it's bad practise.

But a singleton is not a static class. It is just a class that hides its contructor and provides a static method to reach the single instance of the class. It is similar, but not the same as a static class.

I can recommend reading Head First Design Patterns. It explains both patterns (and many more) in a fun and accessible way. The code examples lean towards Java, but that's hardly a problem.

1 Comment

+1 for recognising that there is a time and a place where singletons are valid and appropriate
0

These classes have a definite use. Let's take an example of a logger.

    class Logger() {
        private __construct() {}

      public static function getInstance()
        {
            static $instance = null;
            if (null === $instance) {
                $instance = new static();
            }

            return $instance;
        }

    //other methods here

    }
}

Now after instantiating it once you can do something like

Logger::log(parameters)

where log is a method in that class.

That is just one example where such a class is very useful.

1 Comment

And if you want to have different kinds of loggers (log to file, to mail, to console, to dev/nul)? What if you want to log to two targets at the same time? This is just one example where I would consider using a different pattern than singleton.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.