В чем преимущество использования геттеров и сеттеров - которые только получают и устанавливают - вместо простого использования открытых полей для этих переменных?
Если геттеры и сеттеры когда-либо делают больше, чем просто получают / устанавливают, я могу понять это очень быстро, но я не на 100% уверен в том, как:
public String foo;
хуже чем:
private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }
В то время как первый занимает гораздо меньше стандартного кода.
Ответы:
На самом деле есть много веских причин, чтобы рассмотреть возможность использования методов доступа, а не непосредственного раскрытия полей класса - помимо просто аргумента инкапсуляции и облегчения будущих изменений.
Вот некоторые из причин, которые мне известны:
источник
public
методы доступа вызывают дублирование кода и раскрывают информацию. Публичные средства доступа не нужны для сортировки (сериализации). В некоторых языках (Java)public
методы доступа get не могут изменять тип возвращаемого значения, не нарушая зависимые классы. Более того, я считаю, что они противоречат принципам ОО. Смотрите также: stackoverflow.com/a/1462424/59087plane.turnTo(dir); plane.setSpeed(spd); plane.setTargetAltitude(alt); plane.getBreaks().release();
чтобы сказатьplane.takeOff(alt)
. Какие внутренние поля данных необходимо изменить, чтобы перевести плоскость вtakingOff
режим, это не мое дело. И какие другие объекты (breaks
) метод уведомляет, я тоже не хочу знать.Поскольку через 2 недели (месяцы, годы), когда вы поймете, что вашему установщику нужно делать больше, чем просто установить значение, вы также поймете, что свойство использовалось непосредственно в 238 других классах :-)
источник
Открытое поле не хуже пары получатель / установщик, которая ничего не делает, кроме как возвращает поле и присваивает ему значение. Во-первых, ясно, что (в большинстве языков) функциональной разницы нет. Любая разница должна быть в других факторах, таких как ремонтопригодность или удобочитаемость.
Часто упоминаемое преимущество пар геттер / сеттер - это не так. Есть утверждение, что вы можете изменить реализацию, и ваши клиенты не должны перекомпилироваться. Предположительно, сеттеры позволяют вам добавлять функциональность, такую как проверка позже, и вашим клиентам даже не нужно знать об этом. Однако добавление проверки к установщику является изменением его предварительных условий, нарушением предыдущего контракта , который, по сути, заключался в том, что «вы можете положить сюда что-нибудь, и вы можете получить то же самое позже от получателя».
Итак, теперь, когда вы нарушили контракт, изменение каждого файла в кодовой базе - это то, что вы должны хотеть делать, а не избегать. Если вы избегаете этого, вы делаете предположение, что весь код предполагал, что контракт для этих методов был другим.
Если это не должно было быть контрактом, то интерфейс позволял клиентам переводить объект в недопустимые состояния. Это полная противоположность инкапсуляции. Если это поле не может быть действительно установлено с нуля с самого начала, почему не было проверки с самого начала?
Этот же аргумент применим и к другим предполагаемым преимуществам этих пар сквозных методов получения / установки: если вы позже решите изменить установленное значение, вы нарушаете контракт. Если вы переопределяете функциональность по умолчанию в производном классе, выходя за рамки нескольких безобидных изменений (таких как ведение журнала или другое ненаблюдаемое поведение), вы нарушаете контракт базового класса. Это является нарушением принципа замещаемости Лискова, который рассматривается как один из принципов ОО.
Если у класса есть эти тупые методы получения и установки для каждого поля, то это класс, который не имеет никаких инвариантов, никаких контрактов . Это действительно объектно-ориентированный дизайн? Если все, что есть в классе, это те геттеры и сеттеры, это просто тупой держатель данных, и тупые держатели данных должны выглядеть как тупые держатели данных:
Добавление пар сквозного геттера / сеттера к такому классу не имеет значения. Другие классы должны обеспечивать значимые операции, а не только операции, которые уже предоставляют поля. Вот как вы можете определить и поддерживать полезные инварианты.
Есть причины использовать геттеры и сеттеры, но если этих причин не существует, создание пар геттер / сеттер во имя ложных богов инкапсуляции не очень хорошая вещь. Допустимые причины для создания или получения включают в себя такие вещи, которые часто упоминаются как потенциальные изменения, которые вы можете сделать позже, такие как проверка или другие внутренние представления. Или, может быть, значение должно быть доступно для чтения клиентами, но не доступно для записи (например, чтение размера словаря), поэтому простой метод получения - это хороший выбор. Но эти причины должны быть, когда вы делаете выбор, а не просто как потенциальная вещь, которую вы можете захотеть позже. Это пример ЯГНИ ( Тебе это не нужно ).
источник
private
поля. Если у класса нет сеттеров, его легко сделать неизменным.Многие говорят о преимуществах добытчиков и сеттеров, но я хочу сыграть в адвоката дьявола. Прямо сейчас я отлаживаю очень большую программу, в которой программисты решили сделать все, что нужно: методы получения и установки. Это может показаться хорошим, но это кошмар обратного инжиниринга.
Допустим, вы просматриваете сотни строк кода и сталкиваетесь с этим:
Это красивый кусок кода, пока вы не поймете, что это сеттер. Теперь вы следуете за этим установщиком и обнаруживаете, что он также устанавливает person.firstName, person.lastName, person.isHuman, person.hasReallyCommonFirstName и вызывает person.update (), который отправляет запрос в базу данных и т. Д. где произошла утечка памяти.
Понимание локального фрагмента кода на первый взгляд является важным свойством хорошей читабельности, которое склонны нарушать методы получения и установки. Вот почему я стараюсь избегать их, когда могу, и минимизирую то, что они делают, когда я их использую.
источник
person.name = "Joe";
вызывается. Нет никакой информации о способе получения информации, выделение синтаксиса показывает, что это поле, а рефакторинг проще (нет необходимости в рефакторинге двух методов и поля). Во-вторых, все эти потраченные впустую мозговые циклы, думающие «getIsValid ()» или «isValid ()» и т. Д., Могут быть забыты. Я не могу вспомнить ни одного раза, когда я был спасен от ошибки получателем / установщиком.Есть много причин. Мой любимый, когда вам нужно изменить поведение или регулировать то, что вы можете установить для переменной. Например, допустим, у вас был метод setSpeed (int speed). Но вы хотите, чтобы вы могли установить максимальную скорость только 100. Вы бы сделали что-то вроде:
Теперь, что если ВЕЗДЕ в своем коде вы используете открытое поле, а затем поняли, что вам нужно вышеуказанное требование? Получайте удовольствие, охотясь за каждым использованием публичного поля, а не просто изменяя ваш сеттер.
Мои 2 цента :)
источник
while(speed < 200) { do_something(); accelerate(); }
)myCar.setSpeed(157);
и после нескольких строкspeed = myCar.getSpeed();
И теперь ... Я желаю вам счастливой отладки, пытаясь понять, почему,speed==100
когда это должно быть157
В чистом объектно-ориентированном мире геттеры и сеттеры это страшный анти-паттерн . Прочитайте эту статью: Getters / Setters. Злой. Период . Короче говоря, они поощряют программистов думать об объектах как о структурах данных, и этот тип мышления является чисто процедурным (как в COBOL или C). В объектно-ориентированном языке нет структур данных, а есть только объекты, демонстрирующие поведение (не атрибуты / свойства!)
Вы можете найти больше о них в Разделе 3.5 « Элегантных объектов» (моя книга об объектно-ориентированном программировании).
источник
new Dog()
не собака. Это объект, который содержит информацию о собаке. И для этого использования естественно иметь возможность исправить неправильно записанный вес.Одним из преимуществ аксессоров и мутаторов является то, что вы можете выполнять валидацию.
Например, если бы он
foo
был общедоступным, я мог бы легко установить его,null
а затем кто-то другой мог бы попытаться вызвать метод объекта. Но его больше нет! С помощьюsetFoo
метода я мог убедиться, чтоfoo
никогда не был установлен вnull
.Средства доступа и мутаторы также допускают инкапсуляцию - если вы не должны видеть значение после его установки (возможно, оно установлено в конструкторе, а затем используется методами, но никогда не должно изменяться), оно никогда не будет никем замечено. Но если вы можете позволить другим классам видеть или изменять его, вы можете предоставить надлежащий метод доступа и / или мутатор.
источник
Зависит от вашего языка. Вы пометили это как «объектно-ориентированный», а не «Java», поэтому я хотел бы отметить, что ответ ChssPly76 зависит от языка. Например, в Python нет причин использовать геттеры и сеттеры. Если вам нужно изменить поведение, вы можете использовать свойство, которое заключает в себе метод получения и установки базового доступа к атрибутам. Что-то вроде этого:
источник
obj.set_attr('foo')
) по своей природе превосходят знаки равенства (obj.attr = 'foo'
). Публичный доступ - это публичный доступ.obj.attr = 'foo'
просто устанавливает переменную без чего-либо еще происходящегоobj.setAttr('foo')
«просто устанавливает переменную без чего-либо еще происходящего»? Если это общедоступные методы, то это публичный метод. Если вы используете его для достижения какого-либо побочного эффекта, и он общедоступен, тогда вам лучше рассчитывать на все, что работает, как если бы только тот побочный эффект имел место (со всеми другими деталями реализации и другими побочными эффектами, использованием ресурсов, чем угодно , скрытый от забот пользователя). Это абсолютно не отличается от Python. Синтаксис Python для достижения эффекта просто проще.Ну, я просто хочу добавить, что даже если иногда они необходимы для инкапсуляции и безопасности ваших переменных / объектов, если мы хотим закодировать реальную объектно-ориентированную программу, нам нужно ОСТАНОВИТЬ ПРЕОДОЛЕНИЕ АКСЕССОРОВ , потому что иногда мы сильно зависимы на них, когда это действительно не нужно, и это делает почти то же самое, как если бы мы сделали переменные общедоступными.
источник
Спасибо, это действительно прояснило мое мышление. Теперь вот (почти) 10 (почти) веских причин НЕ использовать геттеры и сеттеры:
Последние три я просто ухожу (N / A или D / C) ...
источник
Я знаю, что уже немного поздно, но я думаю, что есть люди, которые заинтересованы в производительности.
Я сделал небольшой тест производительности. Я написал класс "NumberHolder", который, ну, в общем, содержит целое число. Вы можете прочитать это Integer, используя метод getter,
anInstance.getNumber()
или напрямую получить доступ к номеру, используяanInstance.number
. Моя программа читает число 1 000 000 000 раз обоими способами. Этот процесс повторяется пять раз, и время печатается. Я получил следующий результат:(Время 1 - прямой путь, Время 2 - получатель)
Видите ли, геттер (почти) всегда немного быстрее. Затем я попробовал с разным количеством циклов. Вместо 1 миллиона я использовал 10 миллионов и 0,1 миллиона. Результаты:
10 миллионов циклов:
С 10 миллионами циклов времена почти одинаковы. Вот 100 тысяч (0,1 миллиона) циклов:
Также с разным количеством циклов геттер немного быстрее обычного. Я надеюсь, что это помогло вам.
источник
Не используйте установщики-получатели, если они не нужны для текущей доставки. Т.е. не стоит слишком много думать о том, что произойдет в будущем, если что-либо изменить, это запрос на изменение в большинстве производственных приложений, систем.
Думайте просто, легко, добавляйте сложность, когда это необходимо.
Я бы не воспользовался незнанием владельцев бизнеса глубоких технических ноу-хау только потому, что я думаю, что это правильно, или мне нравится подход.
У меня есть огромная система, написанная без методов установки геттеров, только с модификаторами доступа и некоторыми методами для проверки логики выполнения biz. Если вам абсолютно необходимо. Используйте что угодно.
источник
Мы используем геттеры и сеттеры:
Методы получения и установки являются открытыми интерфейсами для доступа к закрытым членам класса.
Инкапсуляционная мантра
Мантра инкапсуляции - сделать поля приватными, а методы - открытыми.
Хотя методы getter и setter не добавляют новую функциональность, мы можем передумать вернуться позже, чтобы сделать этот метод
Везде, где может использоваться значение, может быть добавлен метод, который возвращает это значение. Вместо:
использование
С точки зрения непрофессионала
Предположим, нам нужно хранить детали этого
Person
. ЭтоPerson
имеет полеname
,age
иsex
. Делать это предполагает создание методовname
,age
иsex
. Теперь , если нам нужно создать еще один человек, становится необходимым для создания методовname
,age
,sex
снова и снова.Вместо этого мы можем создать компонент
class(Person)
с помощью методов получения и установки. Поэтому завтра мы можем просто создавать объекты этого Бинаclass(Person class)
всякий раз, когда нам нужно добавить нового человека (см. Рисунок). Таким образом, мы повторно используем поля и методы класса bean, что намного лучше.источник
Я потратил некоторое время на обдумывание этого случая с Java, и я считаю, что настоящие причины:
Другими словами, единственный способ указать поле в интерфейсе - это предоставить метод для записи нового значения и метод для чтения текущего значения.
Эти методы являются печально известными методами получения и установки ....
источник
Это может быть полезно для отложенной загрузки. Скажем, рассматриваемый объект хранится в базе данных, и вы не захотите получить его, если он вам не нужен. Если объект получен получателем, то внутренний объект может быть нулевым, пока кто-то не запросит его, тогда вы можете получить его при первом обращении к получателю.
У меня был класс базовой страницы в проекте, который мне передали, который загружал некоторые данные из пары разных вызовов веб-службы, но данные в этих вызовах веб-службы не всегда использовались на всех дочерних страницах. Веб-сервисы, несмотря на все преимущества, являются пионерами новых определений «медленных», поэтому вы не хотите делать вызовы веб-сервисов, если в этом нет необходимости.
Я перешел из открытых полей к получателям, и теперь получатели проверяют кеш, и если его там нет, вызывают веб-службу. Таким образом, с небольшой упаковкой было предотвращено множество вызовов веб-служб.
Таким образом, получатель спасает меня от попыток выяснить на каждой дочерней странице, что мне понадобится. Если мне это нужно, я вызываю получателя, и он находит его для меня, если у меня его еще нет.
источник
Один аспект, который я пропустил в ответах, - спецификация доступа:
источник
РЕДАКТИРОВАТЬ: Я ответил на этот вопрос, потому что есть множество людей, изучающих программирование, спрашивающих об этом, и большинство ответов очень технически компетентны, но их не так легко понять, если вы новичок. Мы все были новичками, поэтому я решил попробовать свои силы в более дружелюбном ответе новичка.
Двумя основными из них являются полиморфизм и валидация. Даже если это просто глупая структура данных.
Допустим, у нас есть этот простой класс:
Очень простой класс, который определяет, сколько в нем жидкости и какова ее емкость (в миллилитрах).
Что происходит, когда я делаю:
Ну, ты не ожидал, что это сработает, верно? Вы хотите, чтобы была какая-то проверка здравомыслия. И что еще хуже, что если бы я никогда не указывал максимальную вместимость? О, дорогой, у нас есть проблема.
Но есть и другая проблема. Что, если бутылки были всего лишь одним типом контейнера? Что если бы у нас было несколько контейнеров, все с емкостями и количеством жидкости, заполненной? Если бы мы могли просто создать интерфейс, мы могли бы позволить остальной части нашей программы принять этот интерфейс, и бутылки, канистры и все виды вещей будут работать взаимозаменяемо. Разве это не было бы лучше? Поскольку интерфейсы требуют методов, это тоже хорошо.
Мы бы получили что-то вроде:
Большой! И теперь мы просто изменим бутылку на это:
Я оставлю определение BottleOverflowException в качестве упражнения для читателя.
Теперь обратите внимание, насколько это надежнее. Теперь мы можем иметь дело с любым типом контейнера в нашем коде, приняв LiquidContainer вместо Bottle. И то, как эти бутылки справляются с такими вещами, может отличаться. У вас могут быть бутылки, которые записывают свое состояние на диск при его изменении, или бутылки, которые сохраняются в базах данных SQL или GNU знает, что еще.
И все это может иметь разные способы справиться с различными возгласами. Бутылка просто проверяет, и если она переполнена, она генерирует исключение RuntimeException. Но это может быть неправильно. (Есть полезная дискуссия об обработке ошибок, но я намеренно держу ее здесь очень просто. Люди в комментариях, скорее всего, укажут на недостатки этого упрощенного подхода.;))
И да, похоже, что мы перешли от очень простой идеи к быстрому получению гораздо лучших ответов.
Обратите внимание также, что вы не можете изменить емкость бутылки. Это сейчас в камне. Вы можете сделать это с помощью int, объявив его окончательным. Но если бы это был список, вы могли бы очистить его, добавить в него новые вещи и так далее. Вы не можете ограничить доступ к прикосновению к внутренностям.
Также есть третья вещь, к которой обращаются не все: геттеры и сеттеры используют вызовы методов. Это означает, что они везде выглядят как обычные методы. Вместо того, чтобы иметь странный специфический синтаксис для DTO и прочего, у вас везде одно и то же.
источник
В языках, которые не поддерживают «свойства» (C ++, Java) или требуют перекомпиляции клиентов при изменении полей на свойства (C #), использование методов get / set легче изменить. Например, добавление логики проверки в метод setFoo не потребует изменения открытого интерфейса класса.
В языках, которые поддерживают «реальные» свойства (Python, Ruby, может быть Smalltalk?), Нет смысла получать / устанавливать методы.
источник
Один из основных принципов ОО дизайна: инкапсуляция!
Это дает вам много преимуществ, одним из которых является то, что вы можете изменить реализацию метода получения / установки за кулисами, но любой потребитель этого значения будет продолжать работать, пока тип данных остается тем же.
источник
Вы должны использовать геттеры и сеттеры, когда:
Так что это очень редко общий вопрос ОО; это вопрос конкретного языка, с разными ответами для разных языков (и разных вариантов использования).
С точки зрения теории ОО, геттеры и сеттеры бесполезны. Интерфейс вашего класса - это то, что он делает, а не его состояние. (Если нет, вы написали неправильный класс.) В очень простых случаях, когда то, что делает класс, это просто, например, представляет точку в прямоугольных координатах, * атрибуты являются частью интерфейса; геттеры и сеттеры просто заволакивают это. Но в любом другом случае, кроме очень простых, ни атрибуты, ни методы получения и установки не являются частью интерфейса.
Другими словами: если вы считаете, что потребители вашего класса даже не должны знать, что у вас есть
spam
атрибут, тем более, что вы можете изменить его произвольно, тогда предоставление имset_spam
метода - это последнее, что вы хотите сделать.* Даже для этого простого класса, вы не обязательно хотите , чтобы настройки
x
иy
значения. Если это действительно класс, разве не должно быть таких методов, какtranslate
,rotate
и т. Д.? Если это только класс, потому что ваш язык не имеет записей / структур / именованных кортежей, то это на самом деле не вопрос ОО…Но никто никогда не делает общий дизайн ОО. Они занимаются дизайном и реализацией на определенном языке. А в некоторых языках геттеры и сеттеры далеко не бесполезны.
Если ваш язык не имеет свойств, то единственный способ представить что-то, что концептуально является атрибутом, но на самом деле вычисляется или проверяется и т. Д., - это через методы получения и установки.
Даже если у вашего языка есть свойства, могут быть случаи, когда они недостаточны или неуместны. Например, если вы хотите разрешить подклассам управлять семантикой атрибута, в языках без динамического доступа подкласс не может заменить вычисленное свойство для атрибута.
Что касается "что если я захочу изменить свою реализацию позже?" вопрос (который повторяется несколько раз в разных формулировках как в вопросе OP, так и в принятом ответе): если это действительно чистое изменение реализации, и вы начали с атрибута, вы можете изменить его на свойство, не затрагивая интерфейс. Если, конечно, ваш язык не поддерживает это. Так что это опять тот же случай.
Кроме того, важно следовать идиомам языка (или структуры), который вы используете. Если вы пишете красивый код в стиле Ruby на C #, любой опытный разработчик C #, кроме вас, будет испытывать трудности при его чтении, и это плохо. Некоторые языки имеют более сильные культуры в своих соглашениях, чем другие. И это может быть не совпадением, что Java и Python, которые находятся на разных концах спектра того, насколько идиоматическими получателями являются, имеют две из самых сильных культур.
Помимо читателей-людей, будут библиотеки и инструменты, которые ожидают, что вы будете следовать соглашениям, и, если вы этого не сделаете, сделаете вашу жизнь тяжелее. Привязка виджетов Interface Builder к чему угодно, кроме свойств ObjC, или использование определенных библиотек Java-макетов без геттеров только усложняет вашу жизнь. Если инструменты важны для вас, не боритесь с ними.
источник
С точки зрения проектно-ориентированного проектирования обе альтернативы могут повредить обслуживанию кода, ослабляя инкапсуляцию классов. Для обсуждения вы можете заглянуть в эту прекрасную статью: http://typicalprogrammer.com/?p=23
источник
Методы получения и установки являются методами доступа, что означает, что они, как правило, являются открытым интерфейсом для изменения закрытых членов класса. Вы используете методы getter и setter для определения свойства. Вы получаете доступ к методам получения и установки как к свойствам вне класса, даже если вы определяете их в классе как методы. Эти свойства вне класса могут иметь имя, отличное от имени свойства в классе.
Есть несколько преимуществ использования методов получения и установки, таких как возможность создавать элементы со сложной функциональностью, к которой у вас есть доступ как к свойствам. Они также позволяют создавать свойства только для чтения и только для записи.
Несмотря на то, что методы getter и setter полезны, вы должны быть осторожны, чтобы не использовать их чрезмерно, поскольку, в частности, они могут усложнить обслуживание кода в определенных ситуациях. Кроме того, они предоставляют доступ к реализации вашего класса, как публичные члены. Практика ООП препятствует прямому доступу к свойствам в классе.
Когда вы пишете классы, вам всегда рекомендуется делать как можно больше ваших переменных экземпляра закрытыми и соответственно добавлять методы getter и setter. Это связано с тем, что в некоторых случаях вы не можете позволить пользователям изменять определенные переменные в ваших классах. Например, если у вас есть закрытый статический метод, который отслеживает количество экземпляров, созданных для определенного класса, вы не хотите, чтобы пользователь изменял этот счетчик с помощью кода. Только оператор конструктора должен увеличивать эту переменную всякий раз, когда она вызывается. В этой ситуации вы можете создать личную переменную экземпляра и разрешить метод получения только для переменной счетчика, что означает, что пользователи могут получать текущее значение только с помощью метода получения и не могут устанавливать новые значения. используя метод установки.
источник
Код развивается .
private
отлично подходит, когда вам нужна защита членов данных . В конце концов, все классы должны быть своего рода «минипрограммами», которые имеют четко определенный интерфейс, который вы не можете просто испортить .Тем не менее, разработка программного обеспечения не сводится к установке окончательной версии класса, как будто вы нажимаете на чугунную статую с первой попытки. Пока вы работаете с ним, код больше похож на глину. Он развивается по мере того, как вы его разрабатываете и узнаете больше о проблемной области, которую вы решаете. Во время разработки классы могут взаимодействовать друг с другом, чем они должны (зависимость, которую вы планируете выделить), объединяться или разделяться. Поэтому я думаю, что дискуссия сводится к людям, которые не хотят писать религиозно
Так что у тебя есть:
Вместо
Это не только
getVar()
визуально шумно, но и создает иллюзию, котораяgettingVar()
является более сложным процессом, чем на самом деле. То, как вы (как писатель класса) относитесь к святости,var
особенно сбивает с толку пользователя вашего класса, если у него есть промежуточный установщик - тогда похоже, что вы устанавливаете эти ворота, чтобы «защитить» то, на чем настаиваете, что-то ценное, (святостьvar
), но, тем не менее, даже если вы признаете,var
что защита не стоит того, чтобы кто-то просто мог прийти иset
var
получить какую-то ценность, даже если вы не взглянули на то, что они делают.Поэтому я программирую следующим образом (предполагая подход «гибкого» типа - то есть когда я пишу код, не зная точно, что он будет делать / не имеет времени или опыта для планирования сложного набора интерфейсов стилей водопада):
1) Начните со всех открытых членов для основных объектов с данными и поведением. Вот почему во всем моем «примерном» коде на C ++ вы заметите, что я использую
struct
вместо этогоclass
везде2) Когда внутреннее поведение объекта для члена данных становится достаточно сложным (например, ему нравится сохранять внутреннее
std::list
в некотором порядке), пишутся функции типа средства доступа. Поскольку я сам программирую, я не всегда устанавливаю членprivate
сразу, но где-то вниз по эволюции класса член будет «повышен» доprotected
илиprivate
.3) Классы, которые полностью проработаны и имеют строгие правила в отношении своих внутренних элементов (то есть они точно знают, что они делают, и вы не должны «трахать» (технический термин) с его внутренними компонентами), получают
class
обозначение, частные члены по умолчанию, и только несколько избранных членов могут бытьpublic
.Я считаю, что этот подход позволяет мне не сидеть и не религиозно писать геттеры / сеттеры, когда многие члены данных перемещаются, перемещаются и т. Д. На ранних этапах развития класса.
источник
Есть веская причина рассмотреть использование аксессоров, если нет наследования свойств. Смотрите следующий пример:
Вывод:
источник
Геттеры и сеттеры используются для реализации двух фундаментальных аспектов объектно-ориентированного программирования:
Предположим, у нас есть класс Employee:
Здесь детали реализации полного имени скрыты от пользователя и недоступны непосредственно пользователю, в отличие от публичного атрибута.
источник
Еще одно использование (в языках, которые поддерживают свойства) состоит в том, что сеттеры и геттеры могут подразумевать, что операция является нетривиальной. Как правило, вы хотите избегать делать что-либо, что вычислительно дорого в собственности.
источник
execute
илиbuild
метод.Одно относительно современное преимущество методов получения / установки состоит в том, что он облегчает просмотр кода в редакторах теговых (индексированных) кодов. Например, если вы хотите увидеть, кто устанавливает участника, вы можете открыть иерархию вызовов установщика.
С другой стороны, если член является общедоступным, инструменты не позволяют фильтровать доступ для чтения / записи к члену. Таким образом, вы должны пройти через все виды использования члена.
источник
В объектно-ориентированном языке методы и их модификаторы доступа объявляют интерфейс для этого объекта. Между конструктором и методами доступа и мутатора разработчик может контролировать доступ к внутреннему состоянию объекта. Если переменные просто объявлены как public, то нет никакого способа регулировать этот доступ. И когда мы используем сеттеры, мы можем ограничить пользователя для ввода, который нам нужен. Означает, что канал для этой самой переменной будет проходить через правильный канал, и канал предопределен нами. Так что безопаснее использовать сеттеры.
источник
Кроме того, это «будущее» вашего класса. В частности, переход от поля к свойству является разрывом ABI, поэтому, если позже вы решите, что вам нужно больше логики, чем просто «установить / получить поле», то вам нужно разбить ABI, что, конечно, создает проблемы для чего-либо еще уже скомпилировано против вашего класса.
источник
Я просто хотел бы бросить идею аннотации: @getter и @setter. С @getter вы должны иметь возможность obj = class.field, но не class.field = obj. С @setter, наоборот. С @getter и @setter вы сможете сделать оба. Это сохранит инкапсуляцию и сократит время, не вызывая тривиальные методы во время выполнения.
источник