Page 1 of 1

How to Restrict Object Instantiation to Other Classes?

Posted: Sun Apr 11, 2010 2:58 am
by tomcatexodus
I'm looking for a way to restrict instantiation.

If I have a class named Machine, and a class named Widget, how can I prevent the Widget class from being instantiated unless it is performed by a method in the Machine class?

I know that nested classes are not valid, but this code exemplifies the functionality I'm looking to achieve:

Code: Select all

class Machine{

    private class Widget{
        //Widget properties and methods
    }

    public function makeWidget(){
        $newWidget = new Widget();
        return $newWidget;
    }

    //Machine properties and methods

}

$myMachine = new Machine();
$myWidget = $myMachine->makeWidget(); //would work fine

$myOtherWidget = new Widget(); //would fail
How can I achieve this?

Re: How to Restrict Object Instantiation to Other Classes?

Posted: Sun Apr 11, 2010 4:49 am
by requinix
First: realize that PHP does not have a perfect OOP implementation. You'll have to take a hit someplace.
Second: there is a way to figure out what just happened during execution, but unless you're looking for debugging purposes you shouldn't use it.

What I would do:
Give the Widget class a constructor that takes a Machine as an argument. It then asks the Machine for whatever information it needs to construct itself.

Code: Select all

public function __construct(Machine $machine) {
    // ...
}
Naturally the Machine class has a function to return a new Widget.

Code: Select all

public function getWidget() {
    return new Widget($this);
}
Yes, you could instantiate the Widget without using Machine::getWidget - that's the aforementioned hit you're taking. It's a good design so don't toss the idea out because it isn't exactly what you want.