Независимые методы получения / установки или комбинированные? - PullRequest
18 голосов
/ 13 июля 2011

Во время работы над проектом я вносил некоторые изменения и просматривал существующие документы по API-интерфейсам для понимания.

Просматривая документы по Kohana, я заметил, что методы получения / установки любого данного класса обычно объединяются:

public function someProperty($value = null){
    if(is_null($value){
        return $this->_someProperty;
    }
    $this->_someProperty = $value;
    return $this;
}

Вместо:

public function setSomeProperty($value){
    $this->_someProperty = $value;
    return $this;
}

public function getSomeProperty(){
    return $this->_someProperty;
}

Есть ли какое-либо значение в этом ( прежнее ), помимо уменьшения количества методов данного класса? Я всегда понимал, что методы ( функции в целом ) должны быть более описательными для действия. Неужели другие опытные разработчики даже немного съеживаются, когда видят это?

Я был просто удивлен, увидев, что популярный фреймворк использует такие соглашения ( Я, конечно, не использовал Kohana )

Ответы [ 7 ]

9 голосов
/ 13 июля 2011

Я считаю это плохой практикой, потому что она нарушает CommandQuerySeparation . Установка значения изменяет состояние (команда). Получение значения запрашивает состояние (Query). Метод не должен делать и то, и другое, а только одно.

Кроме того, не совсем очевидно, что делает метод, когда он просто называется username, например не имеет глагола, как получить или установить. Это становится еще хуже в вашем примере, потому что возвращаемое значение - это либо сам объект, либо значение свойства, поэтому оно не соответствует.

Более того, геттеры (и сеттеры) должны использоваться экономно , поскольку они быстро свернут ваш API. Чем больше у вас получателей и установщиков, тем больше знаний об объекте требуется сотрудникам этого объекта. Если вы обнаружите, что ваши объекты спрашивают другие объекты об их внутренностях, скорее всего, вы смещены со своих обязанностей.

3 голосов
/ 13 июля 2011

jQuery идет так же, как и Kohana. Однако я думаю, что лучше создать отдельные методы для установки и получения. Это более очевидно, что метод делает, и я думаю, что это более практично в завершении кода в вашем представлении. Например, вы набираете set и получаете список всех свойств, которые вы можете установить.

Еще один недостаток: что, если вы действительно хотите установить значение null? Это не будет работать, так как null является идентификатором для возврата значения, вы ограничены в установке определенных значений ...

Так что это хорошо, так как вам придётся писать меньше, но что за три буквы (set / get) перед вашими методами?

2 голосов
/ 13 июля 2011

Несмотря на то, что Kohana использует такую ​​необычную технику для ООП, я думаю, что вы должны сначала следовать соглашениям о кодировании. Но, конечно, лучше использовать отдельные методы получения и установки для каждого свойства в ваших классах. Так что, если есть возможность использовать их, не нарушая соглашений - просто сделайте это, и вы не ошибетесь;). Вы также можете прочитать здесь о хороших привычках в PHP ООП - http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/, если вы сомневались в использовании некоторой техники ООП. Надеюсь, что это поможет:)

1 голос
/ 28 февраля 2014

Почему бы не сделать это так?

public function someProperty($value = null)
{
    if (func_num_args() === 1) {
        $this->someProperty = $value;
        return $this;
    } else {
        return $this->someProperty;
    }
}

Это был бы единственный правильный способ реализации комбинированного метода получения / установки

1 голос
/ 13 июля 2011

Я бы скорее поверил, что у них было разумное объяснение, чтобы сделать это таким образом.Например, для более легкой реализации ArrayAccess.Единственный способ узнать наверняка - это задать их напрямую.

Чтобы ответить на ваш вопрос, да, я съеживаюсь, когда вижу первый метод.Идет вразрез с принципами ООП.

0 голосов
/ 02 июня 2015

Ради аргумента,

Комбинированный подход предлагает некоторые преимущества:

  1. Избегает магии __get и __set, все еще эмулируя публичную собственность (Я бы никогда не рекомендовал использовать magic для этих ситуаций в любом случае)
  2. Использование thing() менее многословно, чем использование getThing() setThing().
  3. Несмотря на то, что методы будут делать больше, их все равно можно рассматривать как «выполнение одного thing()», то есть обработку thing(). Свойства также делают больше, чем одно. Они позволяют вам устанавливать и получать значения.
  4. Утверждается, что thing() не дает глагола. Однако мы можем предположить, что thing() без глагола означает, что мы используем его как свойство (мы получаем и устанавливаем это). Для интерфейсов мы можем сказать, что thing() без аргумента - readonly , а thing($arg) с аргументом - read / write . Почему мы должны стесняться принять это? В какой-то момент мы приняли идею добавления геттеров и сеттеров не так ли?
  5. Если вы используете веб-язык (например, PHP), скорее всего, вы также можете использовать jQuery. JQuery уже делает этот тип thing(), и он сработал хорошо.
  6. Использование func_num_args(), как уже упоминалось, помогает идеально реализовать этот подход.

Лично я уже принял на себя значительную долю рисков в своих текущих приложениях на данный момент, поэтому я, вероятно, собираюсь использовать старые проверенные методы получения и установки ( см. Раздел «Поиск баланса» "поста Джимми Богарда относительно получателей / установщиков для операций с данными ). И я предполагаю, что мы уже обучены искать эти префиксы get / set (а также наши IDE), чтобы увидеть, с какими свойствами мы можем работать в классе. Это обсуждение, к которому я мог бы вернуться в какой-то момент.

0 голосов
/ 13 июля 2011

Если вы делаете это везде, это хороший способ, но чем это действительно нужно для всего , может быть, программисты этого фреймворка привыкли к (это немного похоже на jquery)

Однако это смутило бы меня

Для настройки и получения я всегда использую сеттеры и геттеры :

   public function __set($key, $value) {
      // assign value $value to $this->key
   }

   public function __get($key) {
      // return value of this->key
   }
...