在啥情况下我们应该将类构造函数设为私有[重复]

Posted

技术标签:

【中文标题】在啥情况下我们应该将类构造函数设为私有[重复]【英文标题】:Under what circumstances should we make a class constructor private [duplicate]在什么情况下我们应该将类构造函数设为私有[重复] 【发布时间】:2012-09-15 05:03:52 【问题描述】:

可能重复:In a php5 class, when does a private constructor get called?

我最近一直在阅读有关 OOP 的内容,并遇到了这个私有构造函数场景。我进行了谷歌搜索,但找不到与 PHP 相关的任何内容。

在 PHP 中

什么时候必须定义私有构造函数? 使用私有构造函数的目的是什么? 使用私有构造函数的优缺点是什么?

【问题讨论】:

这个问题展示了一个你可能想要这样的场景:In a PHP5 class, when does a private constructor get called?。 它是私有的构造函数。改变你的搜索,你应该会找到你需要的。 您能否添加一些链接或描述术语“私人承包商方案” 代表什么?同样在标题中您要求 Constructor,但在您谈到私人承包商的问题中。 在标题中我特别问“我们什么时候应该将构造函数设为私有”。它包含“私有构造函数”这个词。 【参考方案1】:

在几种情况下,您可能希望将构造函数设为私有。常见的原因是在某些情况下,您不希望外部代码直接调用您的构造函数,而是强制它使用另一种方法来获取您的类的实例。

单例模式

你只希望你的类存在一个实例:

class Singleton

    private static $instance = null;

    private function __construct()
    
    

    public static function getInstance()
    
        if (self::$instance === null) 
            self::$instance = new self();
        

        return self::$instance;
    

工厂方法

您想提供几种方法来创建类的实例,和/或您想控制实例的创建方式,因为需要构造函数的一些内部知识才能正确调用它: em>

class Decimal

    private $value; // constraint: a non-empty string of digits
    private $scale; // constraint: an integer >= 0

    private function __construct($value, $scale = 0)
    
        // Value and scale are expected to be validated here.
        // Because the constructor is private, it can only be called from within the class,
        // so we can avoid to perform validation at this step, and just trust the caller.

        $this->value = $value;
        $this->scale = $scale;
    

    public static function zero()
    
        return new self('0');
    

    public static function fromString($string)
    
        // Perform sanity checks on the string, and compute the value & scale

        // ...

        return new self($value, $scale);
    

BigDecimal 实现 brick/math 的简化示例

【讨论】:

如果你想防止一个对象被实例化,工厂方法也很有用,例如如果缺少一个或多个参数,您可以返回 null 而不是无效对象 / 而不是引发异常。【参考方案2】:

什么时候必须定义私有构造函数?

class smt 

    private static $instance;
    private function __construct() 
    
    public static function get_instance() 
        
            if (! self::$instance)
                self::$instance = new smt();
            return self::$instance;
        
    

使用私有构造函数的目的是什么?

它确保一个类只能有一个实例,并为该实例提供一个全局访问点,这在单例模式中很常见。

使用私有构造函数的优缺点是什么?

Are Singletons really that bad?

What is so bad about singletons?

【讨论】:

【参考方案3】:

私有构造函数主要用在Singleton pattern中,你不希望你的类被直接实例化,但你想通过它的getInstance()方法访问它。

这样你就可以确定没有人可以在课堂之外调用__construct()

【讨论】:

你应该提到它不推荐。【参考方案4】:

私有构造函数用于两种情况

    使用单例模式时 在这种情况下,只有一个对象,并且该对象通常由getInstance() 函数创建

    使用工厂函数生成对象时 在这种情况下会有多个对象,但对象将由静态函数创建,例如

    $token = 令牌::generate();

这将生成一个新的 Token 对象。

【讨论】:

【参考方案5】:

私有构造函数在大多数情况下用于实现单例模式,或者如果您想强制使用工厂。 当您想确保只有一个对象实例时,此模式很有用。 它是这样实现的:

class SingletonClass
    private static $instance=null;
    private function __construct()

    public static function getInstance()
        if(self::$instance === null)
            self::$instance = new self; 

        
        return self::$instance;

【讨论】:

以上是关于在啥情况下我们应该将类构造函数设为私有[重复]的主要内容,如果未能解决你的问题,请参考以下文章

不可变类/对象、私有构造函数、工厂方法

Java中的构造函数可以是私有的吗?

为啥我们需要私有构造函数?

在 PHP5 类中,何时调用私有构造函数?

如何在基类中将默认构造函数设为私有?

如果构造函数在私有部分,为啥我们不能创建对象?