Каков «пуристический» или «правильный» способ доступа к свойствам объекта из метода объекта, который не является методом получения / установки?
Я знаю, что извне объекта вы должны использовать геттер / сеттер, но изнутри вы бы просто сделали:
Ява:
String property = this.property;
PHP:
$property = $this->property;
или вы бы сделали:
Ява:
String property = this.getProperty();
PHP:
$property = $this->getProperty();
Простите, если моя Java немного не работает, прошел год с тех пор, как я программировал на Java ...
РЕДАКТИРОВАТЬ:
Кажется, люди предполагают, что я говорю только о частных или защищенных переменных / свойствах. Когда я изучал объектно-ориентированный подход, меня учили использовать геттеры / сеттеры для каждого отдельного свойства, даже если оно было общедоступным (и на самом деле мне сказали никогда не делать какие-либо переменные / свойство общедоступными). Итак, я могу исходить из ложного предположения с самого начала. Похоже, что люди, отвечающие на этот вопрос, возможно, говорят, что у вас должны быть общедоступные свойства и что им не нужны геттеры и сеттеры, что идет вразрез с тем, чему меня учили и о чем я говорил, хотя, возможно, это следует обсудить как хорошо. Возможно, это хорошая тема для другого вопроса ...
Лично я считаю важным оставаться последовательным. Если у вас есть геттеры и сеттеры, используйте их. Единственный раз, когда я обращаюсь к полю напрямую, - это когда у метода доступа много накладных расходов. Может показаться, что вы без надобности раздуваете свой код, но это, безусловно, может сэкономить массу головной боли в будущем. Классический пример:
Позже вы можете захотеть изменить способ работы этого поля. Может быть, его следует рассчитывать на лету, или, может быть, вы хотите использовать другой тип для резервного хранилища. Если вы обращаетесь к свойствам напрямую, подобное изменение может сломать очень много кода одним ударом.
источник
Я довольно удивлен, насколько это единодушное мнение,
getters
а сеттеры хороши и хороши. Предлагаю зажигательную статью Аллена Голуба « Геттеры и сеттеры - зло ». Конечно, заголовок рассчитан на шокирующую ценность, но автор делает обоснованные выводы.По сути, если у вас есть
getters
иsetters
для каждого частного поля, вы делаете эти поля такими же хорошими, как и общедоступные. Вам будет очень трудно изменить тип частного поля без эффектов пульсации для каждого класса, который это вызываетgetter
.Более того, с строго объектно-ориентированной точки зрения, объекты должны отвечать на сообщения (методы), которые соответствуют их (надеюсь) единственной ответственности. Подавляющее большинство
getters
иsetters
не имеют смысла для составляющих их объектов;Pen.dispenseInkOnto(Surface)
имеет для меня больше смысла, чемPen.getColor()
.Геттеры и сеттеры также побуждают пользователей класса запрашивать у объекта некоторые данные, выполнять вычисление, а затем устанавливать какое-либо другое значение в объекте, что более известно как процедурное программирование. Лучше просто сказать объекту сделать то, что вы собирались делать в первую очередь; также известный как идиома информационного эксперта .
Однако геттеры и сеттеры - необходимое зло на границе слоев - пользовательский интерфейс, постоянство и так далее. Ограниченный доступ к внутренним компонентам класса, таким как ключевое слово friend в C ++, защищенный доступ к пакетам Java, внутренний доступ .NET и шаблон Friend Class, могут помочь вам уменьшить видимость
getters
и сеттеры только для тех, кто в них нуждается.источник
Это зависит от того, как используется недвижимость. Например, предположим, что у вас есть объект ученика, у которого есть свойство name. Вы можете использовать свой метод Get для извлечения имени из базы данных, если оно еще не было получено. Таким образом вы сокращаете количество ненужных обращений к базе данных.
Теперь предположим, что у вас есть частный счетчик целых чисел в вашем объекте, который подсчитывает, сколько раз было вызвано имя. Вы можете не использовать метод Get изнутри объекта, потому что это приведет к неверному счету.
источник
PHP предлагает множество способов справиться с этим, включая магические методы
__get
и__set
, но я предпочитаю явные методы получения и установки. Вот почему:источник
Возможно;)
Другой подход заключался бы в использовании частного / защищенного метода для фактического получения (caching / db / etc) и общедоступной оболочки для него, которая увеличивает счетчик:
PHP:
а затем изнутри самого объекта:
PHP:
Таким образом, вы все еще можете использовать этот первый аргумент для чего-то еще (например, для отправки флага, чтобы указать, использовать ли здесь кэшированные данные).
источник
Я, должно быть, упускаю суть, зачем использовать геттер внутри объекта для доступа к свойству этого объекта?
Подводя итог этому, геттер должен вызвать геттер, который должен вызвать геттер.
Поэтому я бы сказал, что внутри метода объекта доступ к свойству напрямую, особенно учитывая, что вызов другого метода в этом объекте (который в любом случае будет напрямую обращаться к свойству, а затем вернуть его) - это просто бессмысленное, расточительное упражнение (или я неправильно понял вопрос ).
источник
Пуристский ОО-способ - избегать обоих и следовать Закону Деметры , используя « Говори, не спрашивай». подход .
Вместо получения значения свойства объекта, которое тесно связывает два класса, используйте объект в качестве параметра, например
Если свойство было собственным типом, например int, используйте метод доступа, назовите его для проблемной области, а не для области программирования.
Это позволит вам поддерживать инкапсуляцию и любые пост-условия или зависимые инварианты. Вы также можете использовать метод setter для поддержки любых предварительных условий или зависимых инвариантов, однако не попадайтесь в ловушку именования их сеттеров, вернитесь к Голливудскому принципу для именования при использовании идиомы.
источник
Лучше использовать методы доступа даже внутри объекта. Вот моменты, которые сразу приходят мне в голову:
Это должно быть сделано в интересах поддержания согласованности с доступом извне объекта.
В некоторых случаях эти методы доступа могут делать больше, чем просто получать доступ к полю; они могут выполнять дополнительную обработку (хотя это бывает редко). В этом случае прямой доступ к полю будет означать, что вам не хватает этой дополнительной обработки, и ваша программа может пойти не так, если эта обработка всегда должна выполняться во время этих обращений.
источник
Если вы имеете в виду «большую инкапсуляцию» под «пуристом», то я обычно объявляю все свои поля как частные, а затем использую «this.field» внутри самого класса. Для других классов, включая подклассы, я получаю доступ к состоянию экземпляра с помощью геттеров.
источник
Я обнаружил, что использование сеттеров / геттеров облегчило чтение моего кода. Мне также нравится контроль, который он дает, когда другие классы используют методы, и если я изменю данные, свойство будет хранить.
источник
Частные поля с общедоступными или защищенными свойствами. Доступ к значениям должен осуществляться через свойства и быть скопирован в локальную переменную, если они будут использоваться в методе более одного раза. Если и ТОЛЬКО если у вас есть остальная часть вашего приложения, полностью настроенная, измененная и иным образом оптимизированная для того, чтобы доступ к значениям путем прохождения их связанных свойств стал узким местом (и этого НИКОГДА не произойдет, я гарантирую), если вы даже начнете рассмотреть возможность того, чтобы что-либо, кроме свойств, напрямую касалось их поддерживающих переменных.
Разработчики .NET могут использовать автоматические свойства, чтобы обеспечить это, поскольку вы даже не можете видеть вспомогательные переменные во время разработки.
источник
Это зависит. Это больше вопрос стиля, чем что-либо еще, и здесь нет жесткого правила.
источник
Я могу ошибаться, потому что я самоучка, но я НИКОГДА не использую общедоступные свойства в своих Java-классах, они всегда являются частными или защищенными, поэтому внешний код должен получать доступ с помощью геттеров / сеттеров. Лучше для обслуживания / модификации. А для кода внутреннего класса ... Если метод получения тривиален, я использую свойство напрямую, но я всегда использую методы установки, потому что я могу легко добавить код для запуска событий, если захочу.
источник
Если я не буду редактировать свойство, я буду использовать общедоступный метод,
get_property()
если это не особый случай, такой как объект MySQLi внутри другого объекта, и в этом случае я просто сделаю свойство общедоступным и назову его$obj->object_property
.Внутри объекта для меня всегда свойство $ this->.
источник
Что ж, похоже, что с реализацией свойств C # 3.0 по умолчанию решение принимается за вас; вы ДОЛЖНЫ установить свойство, используя (возможно, частный) установщик свойств.
Лично я использую закрытый член позади только тогда, когда его невыполнение может привести к падению объекта в менее чем желаемое состояние, например, при инициализации или когда задействовано кеширование / ленивая загрузка.
источник
Мне нравится ответ cmcculloh , но кажется, что наиболее правильным является ответ Грега Херлмана . Всегда используйте геттер / сеттер, если вы начали использовать их с самого начала и / или привыкли с ними работать.
Кстати, я лично считаю, что использование геттера / сеттера упрощает чтение кода и его отладку в дальнейшем.
источник
Как указано в некоторых комментариях: иногда нужно, иногда нет. Самое замечательное в частных переменных заключается в том, что вы можете видеть все места, где они используются, когда вы что-то меняете. Если ваш геттер / сеттер делает что-то, что вам нужно, используйте его. Если это не важно, решать вам.
Противоположный случай может быть сделан, если вы используете геттер / сеттер, а кто-то меняет геттер / сеттер, они должны проанализировать все места, где геттер и сеттер используются внутри, чтобы увидеть, не испортил ли он что-то.
источник