Сведения о вопросе

rjevskii

16:03, 1st July, 2020

Теги

java   php   oop   theory    

Как получить доступ к свойствам объекта из метода объекта?

Просмотров: 470   Ответов: 19

Каков "purist" или "correct" способ доступа к свойствам объекта из метода объекта, который не является методом getter/setter?

Я знаю, что снаружи объекта вы должны использовать getter/setter,, но изнутри вы бы просто сделали это:

Java:

String property = this.property;

PHP:

$property = $this->property;

или ты бы так и сделал:

Java:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

Простите меня, если мой Java немного не в порядке, прошел год с тех пор, как я программировал в Java...

EDIT:

Похоже, люди предполагают, что я говорю только о частных или защищенных переменных / свойствах. Когда я узнал ОО, меня научили использовать геттеры/сеттеры для каждого отдельного свойства, даже если оно было общедоступным (и на самом деле мне сказали никогда не делать никакой переменной/свойство общедоступным). Итак, я, возможно, начинаю с ложного предположения с самого начала. Похоже, что люди, отвечающие на этот вопрос, возможно, говорят, что вы должны иметь общественные свойства и что они не нуждаются в геттерах и сеттерах, что противоречит тому, чему меня учили, и тому, о чем я говорил, хотя, возможно, это тоже нужно обсудить. Хотя это, вероятно, хорошая тема для другого вопроса...



  Сведения об ответе

SKY

18:03, 1st July, 2020

У этого есть потенциал религиозной войны, но мне кажется, что если вы используете getter/setter,, вы должны использовать его и внутри себя - использование обоих приведет к проблемам обслуживания в будущем (например, кто-то добавляет код к setter, который должен запускаться каждый раз, когда это свойство устанавливается, и свойство устанавливается внутри без вызова setter).


  Сведения об ответе

baggs

18:03, 1st July, 2020

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

Позже вы можете захотеть изменить способ работы этого поля. Возможно, он должен быть рассчитан on-the-fly или, возможно,вы хотели бы использовать другой тип для резервного хранилища. Если вы обращаетесь к свойствам напрямую,подобное изменение может сломать очень много кода за один раз.


  Сведения об ответе

qwerty101

18:03, 1st July, 2020

Я довольно удивлен тем, насколько единодушно мнение о том, что getters и сеттеры прекрасны и хороши. Я предлагаю вам зажигательную статью Аллена Голуба "добытчики и сеттеры-это зло". Конечно, название предназначено для шокового значения, но автор делает обоснованные замечания.

По сути, если у вас есть getters и setters для каждого частного поля, вы делаете эти поля такими же хорошими, как и публичные. Вам будет очень трудно изменить тип частного поля без эффекта пульсации для каждого класса, который вызывает этот getter .

Кроме того, с точки зрения строго OO, объекты должны отвечать на сообщения (методы), соответствующие их (надеюсь) единственной ответственности. Подавляющее большинство getters и setters не имеют смысла для их составляющих объектов; Pen.dispenseInkOnto(Surface) имеет для меня больше смысла, чем Pen.getColor() .

Геттеры и сеттеры также побуждают пользователей класса запрашивать у объекта некоторые данные, выполнять вычисления, а затем устанавливать в объекте другое значение, более известное как процедурное программирование. Вам было бы лучше просто сказать объекту, чтобы он сделал то, что вы собирались сделать в первую очередь; также известный как идиома эксперта по информации .

Добытчики и сеттеры, однако, являются необходимым злом на границе слоев-UI, настойчивость и так далее. Ограниченный доступ к внутренним элементам класса, таким как ключевое слово друга C++, защищенный доступ пакета Java, внутренний доступ .NET и шаблон класса друга , может помочь вам уменьшить видимость getters и сеттеров только для тех, кто в них нуждается.


  Сведения об ответе

FAriza

18:03, 1st July, 2020

Это зависит от того, как используется свойство. Например, предположим, что у вас есть объект student, который имеет свойство name. Вы можете использовать метод Get для извлечения имени из базы данных, если оно еще не было извлечено. Таким образом, вы уменьшаете количество ненужных вызовов к базе данных.

Теперь предположим, что у вас есть частный целочисленный счетчик в вашем объекте, который подсчитывает количество раз, когда имя было вызвано. Возможно, вы не захотите использовать метод Get внутри объекта, так как это приведет к недопустимому количеству.


  Сведения об ответе

ASER

18:03, 1st July, 2020

PHP предлагает множество способов справиться с этим, включая магические методы __get и __set , но я предпочитаю явные геттеры и сеттеры. Вот почему:

  1. Валидация может быть помещена в сеттеры (и геттеры, если уж на то пошло)
  2. Intellisense работает с явными методами
  3. Нет вопроса, Является ли свойство только для чтения, только для записи или только для чтения-записи
  4. Получение виртуальных свойств (т. е. вычисляемых значений) выглядит так же, как и обычные свойства
  5. Вы можете легко установить свойство объекта, которое на самом деле нигде не определено, а затем становится недокументированным


  Сведения об ответе

davran

18:03, 1st July, 2020

Может быть, я просто переборщил?

Возможно ;)

Другой подход заключается в использовании закрытого / защищенного метода для фактического получения (caching/db/etc) и публичной оболочки для него, которая увеличивает количество:

PHP:

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

protected function _getName() {
    return $this->name;
}

а затем изнутри самого объекта:

PHP:

$name = $this->_getName();

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


  Сведения об ответе

P_S_S

18:03, 1st July, 2020

Я, должно быть, упускаю из виду, почему вы используете getter внутри объекта, чтобы получить доступ к свойству этого объекта?

Принимая это к своему заключению, getter должен вызвать a getter, который должен вызвать a getter.

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


  Сведения об ответе

9090

18:03, 1st July, 2020

я бы сказал, что лучше использовать методы доступа даже внутри объекта. Вот те моменты, которые сразу приходят мне на ум:

1) это должно быть сделано в интересах поддержания согласованности с доступом, сделанными вне объекта.

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


  Сведения об ответе

Chhiki

18:03, 1st July, 2020

Если под "purist" вы подразумеваете "большую инкапсуляцию", то я обычно объявляю все свои поля как частные, а затем использую this.field из самого класса, но все остальные классы, включая подклассы, получают доступ к состоянию экземпляра с помощью геттеров.


  Сведения об ответе

lesha

18:03, 1st July, 2020

Пуристский путь OO состоит в том, чтобы избегать обоих и следовать закону Деметры , используя подход " скажи Не спрашивай ".

Вместо того, чтобы получить значение свойства объекта, которое тесно связывает два класса, используйте объект в качестве параметра, например

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

Если свойство было собственного типа, например int, используйте метод доступа, назовите его для проблемного домена, а не для домена программирования.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Это позволит вам поддерживать инкапсуляцию и любые постусловия или зависимые инварианты. Вы также можете использовать метод setter для поддержания любых предварительных условий или зависимых инвариантов,однако не попадайте в ловушку именования их сеттерами, вернитесь к голливудскому принципу именования при использовании идиомы.


  Сведения об ответе

JUST___

18:03, 1st July, 2020

Если я не буду редактировать свойство, я буду использовать открытый метод get_property() , если только это не особый случай, например объект MySQLi внутри другого объекта, в этом случае я просто открою свойство и буду ссылаться на него как на $obj->object_property .

Внутри объекта это всегда $this->property для меня.


  Сведения об ответе

SILA

18:03, 1st July, 2020

я обнаружил, что использование сеттеров / геттеров облегчает чтение моего кода. Мне также нравится контроль, который он дает, когда другие классы используют методы, и если я изменю данные, то свойство будет храниться.


  Сведения об ответе

#hash

18:03, 1st July, 2020

Частные поля с открытыми или защищенными свойствами. Доступ к значениям должен проходить через свойства и копироваться в локальную переменную, если они будут использоваться в методе более одного раза. Если и ONLY, если у вас есть rest вашего приложения, настолько полностью настроенного, раскачанного и оптимизированного для того, чтобы доступ к значениям, проходя через их ассоциированные свойства, стал узким местом (и это никогда не произойдет EVER, я гарантирую), вы даже должны начать рассматривать возможность того, чтобы позволить чему-либо, кроме свойств, непосредственно касаться их резервных переменных.

.NET разработчики могут использовать автоматические свойства для обеспечения этого, так как вы даже не можете видеть резервные переменные во время разработки.


  Сведения об ответе

KOMP

18:03, 1st July, 2020

Я могу ошибаться, потому что я автоидакт, но я никогда не использую общедоступные свойства в моих классах Java, они всегда частные или защищенные, так что внешний код должен получить доступ к getters/setters., это лучше для целей обслуживания / модификации. И для внутреннего кода класса... Если метод getter тривиален, я использую свойство напрямую, но я всегда использую методы setter, потому что я могу легко добавить код к событиям fire, если захочу.


  Сведения об ответе

lesha

18:03, 1st July, 2020

Это зависит. Это скорее вопрос стиля, чем что-либо еще, и нет никаких жестких правил.


  Сведения об ответе

appple

18:03, 1st July, 2020

Ну, похоже, с реализацией по умолчанию C# 3.0 properties решение принимается за вас; вы HAVE устанавливаете свойство, используя (возможно, частное) свойство setter.

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


  Сведения об ответе

pumpa

18:03, 1st July, 2020

Мне нравится ответ cmcculloh, но мне кажется, что самый правильный ответ-это ответ Грега Херлмана . Используйте getter / setters постоянно, если вы начали использовать их с getgo и / или привыкли работать с ними.

Кроме того, я лично считаю, что использование getter / setters облегчает чтение кода и последующую отладку.


  Сведения об ответе

repe

18:03, 1st July, 2020

Как сказано в некоторых комментариях: иногда вы должны, иногда нет. большая часть частных переменных заключается в том, что вы можете видеть все места, где они используются, когда вы что-то меняете. Если ваш getter/setter делает что-то, что вам нужно, используйте его. Если это не имеет значения, решайте сами.

Противоположный случай может быть сделан, если вы используете getter/setter и кто-то изменяет getter/setter, они должны проанализировать все места, где getter и setter используются внутренне, чтобы увидеть, если это что-то испортит.


  Сведения об ответе

Катя

16:06, 12th December, 2023

Вообще, хорошим тоном в ООП является делать все переменные или так называемые свойства приватные. Не ко всем из них нужен доступ извне - а для которых нужен, он будет предоставляться геттерами и сеттерами.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться