【问题标题】:PHP Setters/Getters and ConstructorPHP Setter/Getter 和构造函数
【发布时间】:2017-09-29 08:51:54
【问题描述】:

我一直在网上搜索这个,但我似乎找不到足够清晰的东西让我理解。我在这里看到了关于 Java 的“类似”问题。

class animal{
    private $name;

    // traditional setters and getters
    public function setName($name){
        $this->name = $name;
    }

    public function getName(){
        return $this->name;
    }

    // animal constructors
    function __construct(){
       // some code here
    }

    // vs

    function __construct($name){
        $this->name = $name;
        echo $this->name;
    }
}

$dog = new animal();
$dog->setName("spot");
echo $dog->getName();

// vs

$dog = new animal("spot");
  1. 我应该通过 setter 和 getter 还是通过构造函数声明和访问我的私有字段?
  2. 最佳做法是哪一种?
  3. 我了解构造函数的用途(也许不是),但是如果我可以通过 setter 和 getter 声明和访问我的私有字段,那么拥有构造函数的意义何在?

请注意...这是我第一次将 OOP 与 Web 开发和 PHP 一起使用,我正在尝试通过编写一些代码来“弄脏”我的手来学习,以便我理解 OOP 中的某些内容。请保持简单。

【问题讨论】:

    标签: php constructor architecture setter getter


    【解决方案1】:

    这更多是语义问题,而不是最佳实践。

    在您的示例中,您的业务逻辑可能会确定动物始终需要名称。 所以用名字来构造对象是有意义的。如果您不想让 一个动物的名字要改,那你就不用写setter了。

    class Animal 
    {
        private $name;
    
        public function __construct($name)
        {
            $this->name = $name;
        }
    
        public function getName()
        {
            return $this->name;
        }
    }
    

    您可能拥有动物不需要的其他属性,例如主人 你只为 i.e. 编写一个 getter/setter

    class Animal
    {
        private $name;
        private $owner;
    
        public function __construct($name)
        {    
            $this->name = $name;
        }
    
        public function getName()
        {
            return $this->name;
        }
    
        public function setOwner($owner)
        {
            $this->owner = $owner
        }
    }
    

    但是如果你发现你总是在同时创造一只动物和一个主人 为方便起见,您可能希望将其放在承包商签名中

    class Animal
    {
        private $name;
        private $owner;
    
        public function __construct($name, $owner = null)
        {    
            $this->name = $name;
            $this->owner = $owner;
        }
    
        public function getName()
        {
            return $this->name;
        }
    
        public function setOwner(Owner $owner)
        {
            $this->owner = $owner
        }
    
        public function getOwner()
        {
            return $this->owner;
        }
    }
    

    如果所有者是您应用程序中的另一个类,您可以键入提示您的构造函数 需要特定类型(类)的所有者。所有这些都是为了让您或其他开发人员更容易理解代码背后的一些要求/逻辑 - 以及可能在这里或那里发现错误

    class Owner 
    {
        private $name;
    
        public function __construct($name)
        {    
            $this->name = $name;
        }
    }
    
    class Animal
    {
        private $name;
        private $owner;
    
        public function __construct($name, Owner $owner = null)
        {    
            $this->name = $name;
            $this->owner = $owner;
        }
    
        public function getName()
        {
            return $this->name;
        }
    
        public function setOwner(Owner $owner)
        {
            $this->owner = $owner
        }
    
        public function getOwner()
        {
            return $this->owner;
        }
    }
    
    // Create a new owner!
    $dave = new Owner('Farmer Dave');
    
    // a standard php empty object
    $otherObj = new \stdClass();
    
    // Create a new animal
    $daisy = new Animal('Daisy');
    
    // Farmer dave owns Daisy
    $daisy->setOwner($dave);
    
    // Throws an error, because this isn't an instance of Owner
    $daisy->setOwner($otherObj);
    
    // Set up Maude, with Dave as the owner, a bit less code than before!
    $maude = new Animal('Maude', $dave);
    

    【讨论】:

    • 感谢您的示例...帮助很大。
    • 我从来不知道我可以在动物构造函数中使用 Owner $owner...谢谢
    【解决方案2】:

    我应该通过 setter 和 getter 还是通过构造函数声明和访问我的私有字段?

    在这种情况下,我问自己:

    • 为什么我要创建一个方法来保存一个单行函数? (+构造函数)

    • 与一个构造函数相比,重构两个、三个、四个、五个或更多的 getter/setter 会有多痛苦?(+Constructor)

    • 与一个构造函数相比,记录两个、三个、四个、五个或更多 getter/setter 有多难?(+Constructor)

    • 是否会有记录的默认值? (+构造函数)

    • 我喜欢文档并希望人们阅读吗? (+构造函数)

    • 初始值会不确定吗?(+Setter)

    • 是否有一组等效形式(速记、国际、昵称)都可以作为所需参数的语法正确接受? (+Setter)

    • 是否有一组带有默认值的可选参数? (+Setter)

    • 是否普遍需要对初始值进行字符串化和解析? (+Setter)

    • 我是否不喜欢文档并希望人们进行实验? (+Setter)

    哪一个是最佳实践?

    Date 对象似乎是大多数语言中最复杂的类,因此它的 PHP 实现将是最佳实践的一个很好的参考。

    如果我可以通过 setter 和 getter 声明和访问我的私有字段,那么拥有构造函数有什么意义?

    在对象实例化时隐式调用构造函数,以封装其类型的结果数据结构的默认状态。

    参考文献

    【讨论】:

      【解决方案3】:
      1. 视情况而定。通常有人说:如果是必需的依赖,使用构造函数,如果是可选的,使用getter/setter。
      2. 没有偏好或反对其中之一。
      3. 构造函数包含在对象创建后立即执行的代码,它应该使对象处于稳定和可用的状态。这就是构造函数背后的想法,它在任何情况下都不起作用,但它应该给你一个想法,应该包含什么。

      请注意,您甚至可以为同一个属性实现构造函数参数和设置器,例如,如果您想允许稍后替换属性。

      $bingo = new Dog;
      echo $bingo->getName(); // DogHasNoNameException <-- maybe better as constructor argument?
      
      $bingo = new Dog('Bingo');
      echo $bingo->getName(); // "Bingo"
      $spike = new Dog; // Missing argument 
      
      $bingo->setName('Spike'); // Or maybe "rename()" ;)
      echo bingo->getName(); // "Spike"
      

      【讨论】:

      • 谢谢谢谢谢谢!!!所以不只是我为此发疯吗?因此,如果需要,我使用构造函数;因此,我不需要使用或设置 setter 和 getter?
      • 我不会说你不需要它。在很多情况下,它们是有用的。显而易见的一个是提到的“可选依赖项”。
      【解决方案4】:

      我应该通过 setter 声明和访问我的私有字段吗? getter 还是通过构造函数?哪一个是最佳做法?

      两者兼而有之。这取决于您的需求。如果在某些字段中需要一个值,则将参数添加到 __construct()- 这样做的方法。或者您也可以在__construct 中添加一个可选参数,让用户可以选择设置属性

      我了解构造函数的目的(也许不是),但什么是 如果我可以声明和访问我的私人,那么有一个构造函数 通过 setter 和 getter 的字段?

      构造器应该初始化你需要初始化的属性。

      【讨论】:

      • 谢谢...您的回答很清楚,我可以理解。
      【解决方案5】:

      在我看来,写setter's & getter's更正确,从那时起,属性的数量只会增加。然后 __construct 可以获取键名(property => value)的属性数组,并将它们设置为属性。

      【讨论】:

        【解决方案6】:

        1> 那是你的选择:如果需要依赖,最好使用构造函数,否则,使用 getter。

        2> 最佳实践是第一位的,

        实际上,你有一个名字,你的动物,但如果你添加一个类型和性别?如果你想分别调用 type、sexe 或 name,第一种方法比第二种更好。

        class animal{
        private $name, $type, $sex;
        
        // traditional setters and getters
        public function setName($name){
            $this->name = $name;
        }
        
        public function setSex($sex){
            $this->sex = $sex;
        }
        
        public function setType($type){
            $this->type = $type;
        }
        
        public function getName(){
            return $this->name;
        }
        
        public function getSex(){
            return $this->sex;
        }
        
        public function getType(){
            return $this->type;
        }
        
        // animal constructors
        function __construct(){
           // some code here
        }
        
        }
        
        $dog = new animal();
        $dog->setName("spot");
        $dog->setSexe("male");
        $dog->setType("dog");
        echo $dog->getName().' is a '.$dog->getType().'('.dog->getSex().')';
        

        3 > 这取决于第一个问题......但在全球范围内,我们总是需要一个依赖项,例如:

        class animal{
        private $name, $type, $sex;
        
        // traditional setters and getters
        public function setName($name){
            $this->name = $name;
        }
        
        public function setSex($sex){
            $this->sex = $sex;
        }
        
        private function setType($type){
            // if type is string ( cat, dog, lion ) and you want
            // to linked string in an id in your database (1, 2, 3...). 
            // you want to call your database connection ( declared in you constructor) 
            // and search type id here. 
            $this->type = $type;
        }
        
        public function getName(){
            return $this->name;
        }
        
        public function getSex(){
            return $this->sex;
        }
        
        public function getType(){
            return $this->type;
        }
        
        // animal constructors
        public function __construct($type){
            // for sample you want to open your database here
            this->setType($type);
        }
        
        public function __destruct(){
            // and you want to close your connection here.
        }
        
        }
        

        【讨论】:

        • 您不应忽略 __construct__destruct 的可见性。
        猜你喜欢
        • 2013-07-30
        • 2017-03-05
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        • 1970-01-01
        相关资源
        最近更新 更多