【问题标题】:Using a single method for setting/getting values instead of two?使用一种方法来设置/获取值而不是两种?
【发布时间】:2012-11-15 12:32:22
【问题描述】:

将 getter 和/或 setter 方法替换为处理两者的单个方法是否是个好主意?

例如:

    function name($what = null){

      if(!$what)
        return $this->name;

      $this->name = $what;
    }

像这样使用:

    // get name
    print $obj->name();

    // set name
    $obj->name('bla');

我已经看到一些框架可以做到这一点。社区认为这是一种好的做法还是坏的做法? :P

它看起来效率更高,但看起来有点混乱,因为我习惯了 PHP 中的 getThing() 和 setThing()。这种风格让我想起了 jQuery。

【问题讨论】:

  • 如果我想将 var 设置为 falsenull?
  • 你是对的,它非常令人困惑和反直觉。我希望 PHP 能提供类似属性的东西。
  • jQuery 正是它所模仿的。显然,许多程序员很容易被双重用途的访问器方法弄糊涂。但在某些情况下它可以帮助 API 可用性,并且对于流畅的接口很常见。 (优先于应该不存在的浅层 getter 和 setter。)
  • @mario - 据我了解,流畅的接口总是返回一个值,你可以依赖它。上面示例中令人困惑的部分是,函数可能返回值,也可能不返回值,这只会带来麻烦。

标签: php class coding-style getter-setter


【解决方案1】:

将 getter 和/或 setter 方法替换为处理两者的单个方法是否是个好主意?

没有。

也许对于一个非常具体的用例。但不是。如果您需要将null 分配给$name,请考虑在您自己的代码中。您的代码不允许这样做。

高效性能而言,我不知道如何。最后,您仍然进行一个方法调用。 setget

如果您的意思是高效,因为代码更少,就您自己的观点而言,您牺牲了可读性。哪个效率更低。尤其是随着时间的推移。

【讨论】:

    【解决方案2】:

    一般来说,有一个函数一次返回一些东西,另一次设置一些东西并返回 void,这绝不是一个好主意(可读性和 findbug 原因)

    【讨论】:

      【解决方案3】:

      我也使用过类似 jQuery 的单一方法解决方案,并且确实喜欢它,但我读过一些帖子,出于某种原因,我认为其他人认为这是不好的做法。但现在我再次阅读并发现了这篇文章。

      我的解决方案有(免责声明:压缩格式)

      class Person {
          protected $name;
          protected $age;
          public function name($value = null) {
              if (null !== $value) {
                  $this->name = (string) $value;
                  return $this;
              }
              return $this->name;
          }
          public function age($value = null) {
              if (null !== $value) {
                  $this->age = (int) $value;
                  return $this;
              }
              return $this->age;
          }
      }
      

      我确实喜欢这种类型的课堂界面

      $person1 = new Person();
      $person1->name('Bob')->age(30);
      echo $person->name();
      

      一般的想法是,如果 $value 为空,则返回该属性,否则将属性设置为 $value,可能进行类型转换或通过其他过滤器运行它,然后返回该类的实例。

      现在我正在重新访问此内容,我不确定为什么会如此糟糕除了,因为您可能会将您的 IDE 与返回值混淆,因为它可能是您的属性数据类型或者你的班级。

      需要将值设置为 false 仍然可以在这里工作,在(对我而言)需要设置为 null 的边缘情况下,我只需一次性/逐个将默认/条件检查更改为适应。

      我确实很欣赏不必编写两个方法及其关联的 phpdoc 块的较少样板感觉。

      【讨论】:

        【解决方案4】:

        您可以做的是为对象中的所有变量创建一个Get和一个Set

        所以代替函数 getName() 和 getAge()

        您可以使用 get('name') 或 set('name', 'Foo Bar');

        函数如下所示:

            public function __set($name, $value) {
            $method = 'set' . $name;
            if (('mapper' == $name) || !method_exists($this, $method)) {
                throw new Exception('Invalid Client property');
            }
            $this->$method($value);
        }
        
        public function __get($name) {
            $method = 'get' . $name;
            if (('mapper' == $name) || !method_exists($this, $method)) {
                throw new Exception('Invalid Client property');
            }
            return $this->$method();
        }
        

        如果您正在寻找 getter 和 setter 的有效替代方法,那么这就是它。

        【讨论】:

        • 我会采用这种方式来实现 getter 和设置,最大的好处是这样做可以强制对象仅具有您希望它具有的属性。如果有人确实打错了字并分配了一些不应该存在的属性的值,那么您的代码会告诉您您的错误!帮助你抓住你的错字!!!
        • @JasonMcCreary 确实会,尽管获得有关您所做工作的直接反馈通常更可取。
        • @bkwint,所以在开发中启用display_errors。虽然魔术方法确实很有用,但用它们来识别错别字是我今天听到的最愚蠢的事情。
        • @JasonMcCreary,这是一个很好的副作用,仅此而已。
        【解决方案5】:

        我通常喜欢让使用我的代码的程序员在通过 __set() 和 __get() 直接访问受保护的变量和通过我的自定义 getter/setter 之间进行选择。我发现在我的 getter/setter 中使用 func_num_args() 是一个可以接受的解决方案。它比仅测试 null 稍慢,但允许我将值设置为 null。

        /**
         * Getter/Setter for Class::$someVar.
         * 
         * @access public 
         * @param mixed Value for Class::$someVar to be set to.
         * @return mixed If no parameter are passed it returns the current value for Class::$var.
         */
        public function someVar($value = null) {
            if (func_num_args() > 0) {
                $this->someVar = $value;
                return $this;
            } else {
                return $this->someVar;
            }
        }
        

        我们在编程中做出的每一个选择都是一种妥协。诀窍是找出可以妥协的地方和不应该妥协的地方。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-23
          • 2021-04-16
          • 1970-01-01
          • 2018-04-08
          • 1970-01-01
          相关资源
          最近更新 更多