2011-01-13 4 views
5

Итак, я знаю, что на геттерах и сеттерах есть много вопросов, но я не мог найти что-то точно так же, как мой вопрос. Мне было интересно, изменили ли люди использование get/set в зависимости от разных языков. Я начал учиться на C++ и учился использовать геттеры и сеттеры. Это то, что я понимаю:Использование геттеров и сеттеров для разных языков программирования

В C++ (и Java?) Переменная может быть общедоступной или частной, но мы не можем иметь микс. Например, я не могу иметь переменную только для чтения, которая все еще может быть изменена внутри класса. Он либо является общедоступным (может читать и изменять его), либо все частные (не могут читать и изменять только внутри класса). Из-за этого (и, возможно, других причин) мы используем геттеры и сеттеры.

В MATLAB я могу управлять свойствами «setaccess» и «getaccess» переменных, чтобы я мог делать вещи только для чтения (может напрямую обращаться к свойству, но не могу его перезаписать). В этом случае я не чувствую, что мне нужен геттер, потому что я могу просто сделать class.property.

Кроме того, в Python считается, что «Pythonic» не использует геттеры/сеттеры и только при необходимости помещает вещи в свойства. Я действительно не понимаю, почему его ОК, чтобы иметь все публичные переменные в Python, потому что это противоречит тому, что я узнал, когда начал с C++.

Мне просто интересно, что думают другие люди. Будете ли вы использовать геттеры и сеттеры для всех языков? Вы бы использовали его только для C++/Java и выполняли прямой доступ в MATLAB и Python (что я сейчас делаю)? Второй вариант считается плохим? Для моих целей я имею в виду только простые геттеры и сеттеры (просто верните/установите значение и ничего не делайте).

Спасибо!

+0

И не забывайте о свойствах C# ... – FrustratedWithFormsDesigner

+1

Возможный ответ: http://stackoverflow.com/questions/1554546/when-and-how-to-use-the-builtin-function-property-in-python/1555169 # 1555169 – unutbu

+1

Расширение такого рода обсуждений на «все языки» делает этот вопрос слишком широким, на мой взгляд. – gnovice

ответ

0

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

+0

Я знал, что вы можете контролировать «GetAccess» и «SetAccess» переменных, но я не знал, что вы могли бы писать getters/setters для свойств так же, как вы могли бы в Python (я просто узнаю об этом). Это довольно классный материал. Поэтому в отношении MATLAB мы можем добавить дополнительные функции getter без изменения кода клиента. Так вы предлагаете просто использовать все общедоступные переменные? Конечно, переменные, которые никогда не понадобятся вне класса I, станут частными. – leonhart88

+0

@ leonhart88: все, с чем можно было бы взаимодействовать снаружи, в идеале публично. Во время разработки я сохраняю все публично, потому что тогда он появится в завершении табуляции. – Jonas

+0

Разве это не зависит от переменных, с которыми я работаю? (То есть.если я хочу переменную только для чтения, я должен публиковать getaccess, private setaccess) ... или более выгодно оставить все это публичным? – leonhart88

2

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

Когда я действительно обдумываю их, я всегда создаю их, независимо от того, поддерживает ли язык смешанный доступ к переменным. Только время, которое я бы подумать не делал, - это такие языки, как VB, которые поддерживают «свойства», где функция может выглядеть так же, как доступ к переменной. Основная причина здесь заключается в том, что я не хочу, чтобы клиенты были связаны с тем, что свойство реализуется переменной.

+0

+1 для вашего первого предложения здесь. –

0

Python, являющийся динамическим языком сценариев, меньше связан с ограничениями времени компиляции и более гибкостью.

Getters and setters («свойство» - это просто геттер + сеттер) позволяют лучше инкапсулировать (проверка достоверности, только геттер, не сеттер, детали реализации не имеют значения - например, время имеет часы, минуты, секунды, но как данные на самом деле хранится? кто заботится?), и будущая расширяемость (например, код сеттера может измениться, потребители не заботятся).

В современных эффективных языках, таких как C++, есть inlining, поэтому для простых геттеров/сеттеров нет стоимости исполнения.

Точка, использование открытых полей для структурного и простого (мелкомасштабного) программирования, использование геттеров и сеттеров для крупномасштабных проектов ООП.

+0

Не знаете, что вы пытаетесь нам рассказать. Если вы подразумеваете, что более крупные проекты на Python должны использовать getters/seters, то нет. Если вы подразумеваете, что производительность является причиной этого, то нет. Если вы подразумеваете, что геттеры/сеттеры обеспечивают инкассуляцию, но простые члены данных этого не делают, нет, а не в долгосрочной перспективе (вы всегда можете поменять их на свойства). – delnan

0

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

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

Что касается разницы в свойствах и геттерах. В большинстве случаев, если оба доступны на языке, для этого есть некоторые правила. Например, в C# рекомендуется использовать свойства, когда свойство ведет себя как нормальная переменная, и обеспечивается, чтобы функция была только O(1). Если свойство имеет больше возможностей, например, дополнительная логика, вместо него следует создать функцию [Rules of properties in C#].

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

+0

Мне не нравится ваш пример с автомобилем: 1. Даже для переменных _public-domain_ часто бывает полезно использовать метод getter/setter, чтобы абстрагировать его от нескольких операций, которые могут потребоваться для доступа к переменной , 2. Языки (по крайней мере, те, о которых я знаю) не предлагают понятия _me_. Объект 'private' member может использоваться только его классом, а не _you _... – peoro

+0

Я бы скорее сравнил принудительное инкапсуляцию с замком, который блокирует двигатель для автомобиля. С другой стороны, несоблюдение инкапсуляции основывается на здравом смысле: все знают, что это абсурд, чтобы удалить двигатель с вашего автомобиля, поэтому вам не нужно защищаться от него. – Philipp

+1

Если они получают доступ к двигателю вашего автомобиля, они могут разрушить его. Как может кто-то, кто использует ваш класс, разрушить его, имея доступ к членам !? Теперь они могут злоупотреблять им в * своей машине, но это их проблема, не так ли? –

2

В зависимости от степени абстракции. Например, недавно мне понадобился getter и setter в C++ при абстрагировании объекта Text. Текстовый объект Direct3D просто содержал переменную типа Text. Объект Direct2D Text, однако, должен был быть воссоздан и переписан и что-то вроде этого. Если бы я выбрал публичные переменные при разработке исходной абстракции, мне пришлось бы перепроектировать интерфейс и изменить все зависимые коды. Хотя я согласен с тем, что геттеры и сеттеры над определенными классами классов бессмысленны, - это некоторые случаи, в которых они необходимы.

Конечно, языки со свойствами не нужны. Но концептуально они одинаковы. Определение свойства над переменной - это просто геттер и сеттер с синтаксическим сахаром, и, хотя я поддерживаю синтаксический сахар, он не меняет инкапсуляцию. Я бы не изменил свой дизайн инкапсуляции на языке по языковой основе. Конечно, мнение сообщества о том, является ли инкапсуляция хорошим, - это другое дело - это, вероятно, разница, которую вы видите. В C++ инкапсуляция оценивается очень высоко, тогда как сообщество Python меньше заботится об этом.

+0

+1: Мне нравится то, что геттеры/сеттеры абстрагируют то, что вам нужно сделать, чтобы получить доступ к тому, что фактически является переменной-членом. – peoro

+0

Я занимался чтением, и я считаю, что программистам на Python все равно, потому что они всегда могут написать метод getter/setter и использовать ключевое слово property, чтобы «прикрепить» методы get/set к переменной, чтобы клиентский код, который делает «class.variable» не прерывается. . Нужно ли создавать геттеры/сеттеры только в том случае, если для этой переменной может потребоваться дополнительная функциональность? Что делать, если переменной никогда не понадобится дополнительная функциональность? Допустимо ли использовать только переменную public? Но тогда пользователь может изменить значение этой переменной ... насколько важно ограничить это? – leonhart88

5

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

+0

Несколько более подробное обсуждение этого документа можно найти в комментарии к [этому] (http://stackoverflow.com/questions/4574479/what-are-the-alternatives-to-public-fields) вопросу. – sbi

0

Python и C++ имеют разные принципы. C++ и Java довольно «статичны» и имеют множество проверок времени компиляции, поэтому вы должны использовать их при использовании C++ и Java: public vs. private, const-correctness и т. Д. Кроме того, у них нет свойств, поэтому, если вы найдете что вы должны выполнить некоторую проверку параметров, вы не можете легко преобразовать переменную public-члена в пару с помощью getter-setter без изменения синтаксиса и нарушения существующего кода. Python, с другой стороны, является динамическим языком, который позволяет всем делать все: вы можете переопределить каждую переменную из каждого модуля, инкапсуляция не может быть принудительно применена, нет проверки статического типа и т. Д. Люди Python склонны говорить «мы все взрослые ", и что вы не должны полагаться на недокументированное поведение и использовать модульные тесты вместо проверки времени компиляции. Я не в состоянии судить о том, что лучше, но в целом вы должны придерживаться установленных правил вашего языка.

3

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

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

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

Например, много лет назад мне нужно было подклассифицировать виджет в Delphi, чтобы заставить его вести себя по-другому. Не много вы видите, немного. Но код, который мне нужно переопределить, называется методом, который был закрытым, поэтому я не мог его переопределить. Вместо этого мне нужно было переопределить оба метода. И, конечно, этот другой метод делал то, что было действительно внутренним, поэтому я в итоге не подклассифицировал виджет, но дублировал его, просто потому, что сделал одно небольшое изменение.

Теория OO утверждает, что так оно и должно быть, потому что ужас ужаса, может быть, в противном случае мой подкласс может прекратить работу со следующей версией Delphi, если суперкласс изменит что-то внутреннее! Ну и что? В этом случае я просто исправлю это.

Это моя проблема, если я использую части ваших внутренних данных. Вам не нужно заботиться. Что вам нужно сделать, так или иначе flag что «этот бит является внутренним и может меняться, использовать на свой страх и риск». Но когда вы как разработчик библиотеки активно мешают мне использовать внутренние биты, вы вызываете у меня проблемы.

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

Теория ОО на самом деле ошибается. Нет ничего полезного в том, чтобы иметь частных членов. Все должно быть общедоступным. И это касается любого языка, по моему опыту.

+1

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

+0

@ leonhart88: Для кого-либо, кроме человека, который это делает? Нет, я не знаю ни одного случая, когда это может быть плохо. –

+0

Хм ... скажем, например, если пользователь меняет переменную из своей собственной глупости, она имеет катастрофические эффекты (скажем, что она контролирует промах или что-то еще). В таких случаях я хотел бы сделать переменную только для чтения (не константой, потому что она будет изменена где-то внутри класса). Как вы это сделаете в Python, если вы оставите все переменные общедоступными? Не могли бы вы использовать методы свойств set/get в этом случае и просто вызвать метод set throw? – leonhart88

0

Вы правы - нет необходимости в «простых» геттерах и сеттерах в современном Matlab OOP; упомянутые вами модификаторы доступа - это «Правильный путь».

В новых классах MCOS Matlab синтаксис доступа к свойству класса тот же, независимо от того, задаете ли вы пользовательские getter/setters или нет. Клиенты всегда могут получить доступ к свойству foo как «obj.foo». Если вы решите добавить специальные методы «get.foo» и «set.foo», они неявно вызывают Matlab, когда клиент обращается к этому свойству с использованием синтаксиса «obj.foo». Таким образом, это не «прямой доступ к полям», как публичные поля в Java или C++. Это похоже на модель «Uniform Access» от Scala. (Я думаю "." синтаксические и декларативные элементы управления доступом, которые вы указываете, упрощают и упрощают добавление пользовательской логики, когда вам это нужно, без необходимости писать шаблонный код спереди. Вездесущность пользовательских геттеров и сеттеров в Java частично объясняется тем, что язык не обладает этими функциями.

В классах Matlab в старом стиле обратное верно: все поля являются частными, поэтому вы должны написать свои собственные getter/setters. Согласие, которое я видел, состоит в том, чтобы написать один метод с тем же именем, что и свойство, которое получает или устанавливает в зависимости от того, называете ли вы его «foo (obj)» или «foo (obj, NewValue)».

+0

Спасибо за информацию, я просто узнал о методах get/set property и, похоже, очень похож на Pythons. Я попробовал, и он работает только отлично. Если я хочу переменную только для чтения, я могу просто установить getaccess для public и setaccess для частного ... в будущем, если мне нужно добавить дополнительные функции для getter, я могу просто сделать метод get.foo! – leonhart88

0

Рассмотрим этот фрагмент C++:

class C { 
public: 
    const T &get_t() const { return t; } 
    void set_t(const T &value) { t = value; } 

private: 
    T t; 
}; 

В этом примере элемент «т» фактически часть общего интерфейса C, потому что функции аксессоры. Часто, однако, функции доступа более сложны, выполняют вычисления, управляют параллелизмом и т. Д. В этих случаях доступ к «t» инкапсулируется желаемыми операциями внутри функций доступа.

В C++ невозможно инкапсулировать операции доступа другими операциями с прямым доступом к элементам данных, поэтому мы используем функции доступа. На самом деле, мы используем функцию доступа, даже если простой доступ все, что нужно, потому что

  1. если смешать прямой доступ с функциями доступа, это трудно запомнить, какие член использовать какой вид доступа, а также

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

Благодаря свойствам, Python обеспечивает согласованность доступа, используя естественный, синтаксис прямого доступа, а также возможность добавлять функциональные возможности для доступа к членам данных, хотя (скрытые) методы получения и установки.

Кроме того, конфиденциальность данных достигается с помощью соглашения в python с использованием ведущих подчеркиваний имен участников, чтобы сигнализировать пользователям о том, что конкретный член не является частью открытого интерфейса класса. Пользователи нарушают соглашение, но затем они могут хранить обе части, если они ломаются. Программисты Python называют это «Мы все взрослые здесь».

class C: 
    def get_t(self): 
     return self._t 

    def set_t(self, t): 
     self._t = t 

    t = property(get_t, set_t) 

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

+0

Я вижу ... Я предполагаю, что это потому, что у C++ нет типов «Свойства», которые говорят, что MATLAB и Python имеют право? Я согласен с тем, что по-прежнему буду использовать геттеры/сеттеры в C++ для простых случаев, так как это будет поддерживать согласованность. – leonhart88

Смежные вопросы