阻止直接绕过工厂创建类的可能性

she*_*iel 5 php factory base-class

在我们MVC系统中所有模型的基类中,我创建了一个工厂方法BaseCLass :: getNew(),它通过SomeChildClass :: getNew()调用时返回所请求子类的实例.

现在,我正在寻找一种方法来强制程序员使用这个工厂.也就是说,我喜欢任何直接创建的类,如下所示:

 new SomeChildClass
Run Code Online (Sandbox Code Playgroud)

将在创建时抛出异常,并且只有工厂创建的类才可用.

任何想法如何实现?

我们的代码是用PHP编写的,但即使您考虑使用其他语言,您的想法很有可能也很有价值.

编辑:我不能使我的构造函数私有,因为我继承的类中的框架构造函数是公共的,而且php不允许我这样做.

Jon*_*Jon 2

通过使类具有私有构造函数。

更新——满足您规定要求的解决方案

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

该解决方案利用对象相等规则,stdClass在基类上存储只有派生类可以访问的“神奇密码”对象。你可以根据口味调整它。

我不会说它像这个想法一样可怕debug_backtrace,但我仍然觉得事情应该采取不同的方式。

  • @gidireich:那么你应该重新思考你是否走在正确的道路上。我可以想到巫毒来实现你既定的目标,但它是“你不应该在这样做时被抓死”的那种。也许您不需要所有构建都经过工厂方法就可以满足您的业务需求? (2认同)
  • @gidireich:因为它在很多层面上都是*糟糕*。无论如何,如果我在面试中被问到这个问题,我会将其解释为“这个人愿意做任何事情,无论多么错误,以使代码运行”并且“立即”建议不雇用。好的一面是,我想出了一些没那么糟糕的东西。一探究竟。 (2认同)