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



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



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



Java:



String property = this.property;


PHP:



$property = $this->property;


или вы бы сделали:



Java:



String property = this.getProperty();


PHP:



$property = $this->getProperty();


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



EDIT:



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

606   18  

18 ответов:

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

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

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

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

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

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

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

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

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

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

Я просто переборщил здесь?

возможно ;)

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

PHP:

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

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

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

PHP:

$name = $this->_getName();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  doSomethingWithProperty( this.daysPerWeek() ) ;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Comments

    Ничего не найдено.