1

I'm building a little framework, currently it is just for fun. I'm wondering how should I implement classes that should be instantiated by the framework and be passed to the controller to use?

For instance: I have an "input" class that houses functions which take POST and GET data and filter it. The class is also used by the framework for routing and similar things.

Should I make these methods static? Should I use the singleton pattern? Or maybe should I make something like Codeigniter has - a loader that stores instances of all instantiated classes?

2
  • 3
    stackoverflow.com/questions/52072/…
    – Jim G.
    Jan 6, 2013 at 22:09
  • 2
    Note that CI is trying to move away from a singleton (or at least, some of the core contributors are). Testing is just ... painful when using that pattern.
    – user131
    Jan 7, 2013 at 1:43

4 Answers 4

2

Most of these answers are suggesting using the Singleton pattern or using static, but I disagree with this. Yes, this will get the job done, but IMHO, it's a bad practice. It's harder to test and isolate code that uses your Singleton/static code so it's not ideal. I'd use the Inversion of Control pattern/Dependency Injection pattern. Basically it works like this (Note that I come from a Java background):

class INeedOneInstanceOfAClass {
    OneInstanceOfAClass oneInstanceOfAClass;

    public void setOneInstanceOfAClass(OneInstanceOfAClass oneInstanceOfAClass) {
        this.oneInstanceOfAClass = oneInstanceOfAClass;
    }
    // ...
}

Some other code is responsible for calling that setter. The code that calls the setter makes sure it only creates one instance of OneInstanceOfAClass and it passes that same instance into all the other classes you have with a setOneInstanceOfAClass method. As a result, there's only one instance of OneInstanceOfAClass but, OneInstanceOfAClass is not a Singleton and it doesn't need to use static anywhere. It's just a regular class that you only instantiate once.

Now it's really easy to isolate INeedOneInstanceOfAClass in a unit test. Your unit test creates INeedOneInstanceOfAClass and passes in a fake OneInstanceOfAClass that does whatever it needs to do to get out of the unit test's way.

4

what you looking for "A SINGLE instance of a class" the way to go is with a Singleton pattern.

basic implementation of a singleton pattern.

Class Test
{
    $private $testInstance;

    private function __construct() { };

    public static function getInstance();
    {
        if ($this->testInstance === null) {
            $this->testInstance = new self();
        }

        return $this->testInstance;
    }
}

and from other place you get that class instanciated with

$test = Test::getInstance();

every time you'll need the object you call the getInstance static method and it will return the object, or create it and return it.

hope it helps.

2

I suggest make them static if you can, that is if your class doesn't have to save it's state. If it does, I think you can better make some kind of framework class that has one member of type INPUT. When you want to use the framework you instantiate a framework object, which instantiates one INPUT object. You drag that framework object everywhere you need the methods from INPUT. It's better debuggable and maintainable than a singleton. also, this: https://stackoverflow.com/a/138012/640888

0

When utilizing Singleton pattern, you also need to make __clone() private

class Single
{
    ... some code here ...
    private function __clone(){}
}

so that you can't do something like this:

$instance = Single::getInstance();
$second = clone $instance;

when NOT done like this, you are getting two separate instances, and if __clone() is private this will produce error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.