【问题标题】:Factory static methods and private constructors工厂静态方法和私有构造函数
【发布时间】:2013-07-24 19:07:04
【问题描述】:

我有一个类Foo 和一个类Bar,我想利用Bar 的静态方法来获取Foo 的单例实例,(类似于BitmapFactory.create() 返回@987654326 的方式@instance),但是 Foo 不应该使用 new Foo() 进行实例化,我该如何获得呢?

class Foo {
    $private Foo() {} // ??
}

class Bar {
    private static $foo = null;
    static function getFooInstance() {
         if(Bar::$foo == null) $foo = new Foo();               
         return Bar::$foo;
    }
} 



$foo = Bar::getFooInstance();

【问题讨论】:

    标签: php singleton static-methods


    【解决方案1】:

    您要做的是将Foo 设为单例并将Bar 通过Foo::getInstance(); 分配给bar 例如:

    class Foo {
        private static $instance;
        private function __construct(){}
        public static function getInstance(){
            if (!isset(self::$instance)){
                self::$instance = new Foo();
            }
            return self::$instance;
        }
        public function __clone(){
            throw new Exception("Cannot Clone Singletons... bad programmer");
        }
    }
    
    class Bar {
        static function getFooInstance() {
             return Foo::getInstance();
        }
    } 
    

    没有必要在 Bar 中重放单例模式,因为 Foo 已经控制了它自己的实例化。

    【讨论】:

    • 1) 你可以将它定义为 self::$instance = new self() 而不是 self::$instace = new Foo() 2) 你可以在这里遵守 DRY 原则,就像:$i =& self::$instance; if (is_null($i)){ $i = new self();} return $i;
    • @DaveJust 你这样做并没有得到任何好处......它总是会返回一个Foo......你必须使用static而不是self表示任何不同的东西(比如 foo 的子类)。
    【解决方案2】:

    这里真的没有必要使用单例模式。单例是一种不好的模式,应该避免。

    最好的解决方案是:在Bar 中创建一个静态工厂方法,保证只会创建一个Foo。你已经这样做了。

    对于Foo:不要在生产代码中单独实例化它。但是你真的想在你的测试中实例化几个Foo 的副本!因此,您不能将Foo 的构造函数设为非公开。

    通常只创建一次的对象应该在您的应用程序中发挥重要作用。它们很可能会在开始时创建一次,然后用于几件事。为此创建一个专用的工厂类(或者每个主题一个:用于模型、数据库和模板)。养成只使用这些工厂来创建对象的习惯。

    或者更好的是,将其作为配置添加到您的依赖注入框架中。获取对象时的用法基本相同。

    【讨论】:

      猜你喜欢
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 2014-02-18
      相关资源
      最近更新 更多