【问题标题】:PHP OO Cancel ConstructionPHP OO 取消构建
【发布时间】:2010-11-01 07:28:52
【问题描述】:

这实际上是一个有趣的问题,并且有一个简单(但丑陋)的解决方法(见下文)。

所以我在问是否有更好的方法来做到这一点。

我想做的是让对象构造函数返回其他东西而不是新实例。

这是我想要实现的一个示例:

$GLOBALS['object_cache']=array();

class Test {
    public function __construct($id=0){
        if(isset( $GLOBALS['object_cache'][$id] ))
            return $GLOBALS['object_cache'][$id];
        $GLOBALS['object_cache'][$id]=$this;
    }
}

$t0=new Test(0);
$t1=new Test(1);
$t01=new Test(0);
// modifying $t01 would presumably also modify $t0

简单(但丑陋?)的修复:

$GLOBALS['object_cache']=array();

class Test {
    public static function create($id=0){
        if(isset( $GLOBALS['object_cache'][$id] ))
            return $GLOBALS['object_cache'][$id];
        $new=new Test();
        $GLOBALS['object_cache'][$id]=$new;
        return $new;
    }
}

$t0=Test::create(0);
$t1=Test::create(1);
$t01=Test::create(0);
// modifying $t01 would presumably also modify $t0

你们怎么看?顺便说一句,示例 1 不起作用;无论返回语句如何,它都会返回一个新实例。

所以我错过了什么,还是第二个更好的方法?

PS:无需说明模式(工厂/单例)的明显...

【问题讨论】:

    标签: php oop caching constructor


    【解决方案1】:
    1. 天哪。构造函数不能返回任何东西。
    2. 它被称为工厂方法模式http://en.wikipedia.org/wiki/Factory_method_pattern,实例化对象是一种常见的做法。

    ps:将实例存储在 static 类变量中,第二个解决方案不会像现在这样奇怪。

    【讨论】:

    • 1.这取决于语言。就此而言,它确实返回了一些东西。新实例。 2. 我知道这一点,但我专注于编码,因为问题在于我的代码而不是理论设计模式。
    • @Christian Sciberras:要清楚 - 它返回,是的,但你不能明确地写 return。我想知道是否有任何编程语言允许它。
    • @Christian Sciberras:2. 好吧,你别无选择 ;-) 你必须选择好的学术解决方案,甚至 有效 ;-)
    • zerkms - 我要问的是,有没有更好的方法?正如埃米尔所说,学术上的答案并不那么明显......en.wikipedia.org/wiki/Singleton_pattern#PHP我注意到他们专门禁用了构造函数......虽然在他们的情况下这是一个好主意,但我宁愿使用更清洁的方法。
    • @Christian 1. 它碰巧返回了一个新实例,但不是因为你是 returning 它来自构造函数。新实例被返回是因为您使用 new 关键字来调用构造函数。
    【解决方案2】:

    您也可以使用程序版本:

    class Test {
        function __construct($i) {}
    }
    function Test($i) {
        static $cache;
        if (isset($cache[$i])) {
            return $cache[$i];
        }
        else { 
            return $cache[$i] = new Test($i);
        }
    }
    

    它在眼睛上稍微好一点,并且允许例如即时流畅的Test(1)->do()->else() 通话。

    【讨论】:

    • 虽然我之前考虑过,但在我看来这是迄今为止最好的方法。哦,谢谢你的重点......
    【解决方案3】:

    基本上,您要做的是实现Singleton patternFactory method pattern。如果您在技术文档(和 cmets)中记录它,任何人都应该能够知道它是如何工作的,因此可以使用第一种方法。

    第二个解决方案对我来说实际上不太显而易见。

    【讨论】:

    • 第二个(工厂方法)还不够明显?! O_o。第一个可以用吗?!?!?如何? ;-)
    • 您好。那是正确的;第一个的问题是它不起作用。
    • @zerkms - 从某种意义上说,您使用 静态方法 构造 实例并不明显。
    猜你喜欢
    • 2012-07-15
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 2011-11-16
    • 2014-03-24
    • 2010-11-25
    • 2011-02-09
    • 1970-01-01
    相关资源
    最近更新 更多