Blocking the ability to create classes directly bypassing the factory

In the base class for all models of our MVC system, I created the factory method BaseCLass :: getNew (), which returns an instance of the requested child class when called through SomeChildClass :: getNew ().

Now I'm looking for a way to get a programmer to use this factory. Ie, idally, I would like any class to be created directly, for example:

 new SomeChildClass

throws an exception on creation, and only classes created by the factory will be used.

Any ideas how this can be achieved?

Our code is written in PHP, but a good chance your idea will be valuable even if you think in another language.

edit: I cannot make my constructor private, as the framework constructor in the class I inherit from is public, and php will not allow me this.

+5
source share
4 answers

After creating the class, create.

Update - a solution that covers your stated requirements

class Base {
    private static $constructorToken = null;

    protected static function getConstructorToken() {
        if (self::$constructorToken === null) {
            self::$constructorToken = new stdClass;
        }

        return self::$constructorToken;
    }
}

class Derived extends Base {
    public function __construct($token) {
        if ($token !== parent::getConstructorToken()) {
            die ("Attempted to construct manually");
        }
    }

    public static function makeMeOne() {
        return new Derived(parent::getConstructorToken());
    }
}

This solution uses the rules of equality of objects for stdClass, storing the object "magic password" in the base class, which can only be accessed by derived classes. You can customize it to your taste.

I would not call it terrible as an idea debug_backtrace, but still I got the impression that everything should be done differently.

+1
source

protected. . (..: new child) .

<?php

class factory
{

    static public function create()
    {
        return new child;
    }

}

class child extends factory
{

    protected function __construct()
    {
        echo 'Ok';
    }

}

$c = factory::create(); // Ok
$c2 = new child; // fatal error

?>

: (

, debug_backtrace() ( singleton GUID, factory ). , , "" === "" "" === "factory. , . , , debug_backtrace .

+2

, , , getNew().

0
source

there are several ways to implement it

  • make the parent class private using magic
  • custom magic function __autoload; check the class type and using an error with an invalid message

http://php.net/manual/en/function.is-a.php

0
source

All Articles