Здравствуйте, Аноним, Вы писали:
А>никогда не понимал конструкций вида А>
А>class Class1
А>{
А> int value;
А> public:
А> void SetValue(const int v) { value = v; }
А> const int GetValue(void) const { return value;}
А>};
А>
А> Class1 cl;
А> cl.SetValue(1);
А>
А>вопрос, а зачем такой изврат?
Кто знает? Например у меня многие изменения в параметрах класса, а как правило set|get это доступ к desc класса, влечет за собой "ребилд" его представления.
тоесть посути выставление флага "инвалидейшн"
для этого нужны set.
Ну а также для проверок, ассертов, логов, дебага по брек поинтам
Итого get|set в классах в принцыпе не должно быть , так же как и public members
*Не путать структуры и классы.
А>
А> Class1 cl;
А> cl.value = 1;
А>
А>и код будет более читабельным при использовании
Если бы мир был так прост.
S>Приходится либо заходить в гетер, либо открывать файл с функцией и ставить там брейкпоинт, что бы не заходить в ненужные функции
В Cтудии есть "Step Into Specific" Хотя без шортката тоже не очень удобно
Помимо всего вышесказанного (хотя, имхо, и так более чем достаточно), свойство может быть:
— вычисляемым (нету соответствующего филда)
— наследуемым (хотя бы потенциально) — интересно, как вы для филда virtual сделаете?
Re[3]: доступ к мемберам класса(getter'ы и setter'ы)
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, los puercos, Вы писали:
J>
LP>>А если ты в один прекрасный день захочешь
J>Вот это и есть ООП головного мозга J>Он же "overengineering".
Нет, это то, что вы предлагаете, является "недо-engeneering".
Вы почему-то пердполагаете, что будете всегда владеть всем кодом.
А это полная чушь — сейчас система плагинов есть в практически в любой программе.
Свой-то код вы всегда можете перекомпилить. Но требовать того же от стороннего кода, который от вашего зависит...
Как вы думаете, долго протянет производитель бытовой техники, который вдруг решит, что его приборы должны работать от 170 вольт, а разъем для наушников сделает квадратным?
Re[2]: доступ к мемберам класса(getter'ы и setter'ы)
Здравствуйте, Ocelot, Вы писали:
O>Вы почему-то пердполагаете, что будете всегда владеть всем кодом. O>А это полная чушь — сейчас система плагинов есть в практически в любой программе. O>Свой-то код вы всегда можете перекомпилить. Но требовать того же от стороннего кода, который от вашего зависит...
Ага, а еще "практически любая" программа работает с базой данных, сетью и DirectX. Это тоже стоит учесть, размышляя, делать ли в конкретном классе геттеры/сеттеры. Тоже одного уровня задачи.
Плагины — это особый случай.
Где есть плагины — там продумываются интерфейсы, но только там, где происходит взаимодействие. Потому что давать плагинам доступ вообще ко всему — это убить расширяемость на корню.
Зачем распространять приемы работы со сторонними плагинами на те части (а это может быть вся программа), где плагинов нет — я не понимаю.
Все равно что из-за того, что в программе есть пара классов, предназначенных для виртуального наследования, надо вообще все классы в программе осчастливить кучей виртуальных функций.
O>Как вы думаете, долго протянет производитель бытовой техники, который вдруг решит, что его приборы должны работать от 170 вольт, а разъем для наушников сделает квадратным?
Это к чему вообще было? Просто красивая фраза о пользе стандартизации вне связи с обсуждаемым предметом?
Здравствуйте, andrey_nado, Вы писали:
_>Здравствуйте, IROV.., Вы писали: IRO>>Итого get|set в классах в принцыпе не должно быть , так же как и public members
_>Поясните, пожалуйста, Вашу мысль.
Претензии к Get|Set высказанные в этом топике являются результатом недоООП головного мозга.
Простая замена доступа к публичным переменным на гет/сет, не более чем синтаксический сахар, и по сути ничем не отличается от публичных переменных, так как не скрывает реализации класса. И соответственно не является инкапсуляцией.
Правильно названные методы класса, действительно скрывающие реализацию, в большинстве случаев не должны иметь слов Get/Set в своем имени.
Большинство учебных примеров по инкапсуляции в ООП к сожалению заканчиваются простыми геттерами/сеттерами, и справедливо вызывают вопросы "зачем это надо".
А>вопрос, это такая религия? или это ООП головного мозга?
Из книжки Dewhurst-а
C++ Common Knowledge: Essential Intermediate Programming
"
Never, ever, simply provide a bunch of get/set operations on the data members of the implementation.
That’s not data abstraction; that’s laziness and lack of imagination.
"
Re[5]: доступ к мемберам класса(getter'ы и setter'ы)
J>Плагины — это особый случай.
Ага, вы начинаете сужать первоначальный случай
J>Где есть плагины — там продумываются интерфейсы, но только там, где происходит взаимодействие. Потому что давать плагинам доступ вообще ко всему — это убить расширяемость на корню. J>Зачем распространять приемы работы со сторонними плагинами на те части (а это может быть вся программа), где плагинов нет — я не понимаю.
Не в плагинах дело. Дело в любом зависящем от вашего коде.
В любом мало-мальски нетривиальном проекте никто не может сказать заранее, где, кем и когда будет использоваться ваш класс. И если вам вдруг находу придет в голову все-таки изсенить филд на геттер, весь зависимый код придется корректировать. Вряд ли все будут этому рады.
J>Это к чему вообще было? Просто красивая фраза о пользе стандартизации вне связи с обсуждаемым предметом?
Не стандартизации, а следованию контракту. Меняя филд на геттер, вы меняете не только имплементацию, вы меняете контракт класса. Это потенциально (на практике — практически всегда) тянет за собой изменения в остальном коде. Если сразу использовать геттер, имплементацию можно менять, не затрагивая остальной код.
Re[4]: доступ к мемберам класса(getter'ы и setter'ы)
DD>Претензии к Get|Set высказанные в этом топике являются результатом недоООП головного мозга. DD>Простая замена доступа к публичным переменным на гет/сет, не более чем синтаксический сахар, и по сути ничем не отличается от публичных переменных, так как не скрывает реализации класса. И соответственно не является инкапсуляцией.
Очень даже является.
Вы забываете, что геттер может получать значение путем "вычислений" или быть виртуальным.
С филдом такое не прокатит.
Re[6]: доступ к мемберам класса(getter'ы и setter'ы)
У меня ощущение, что это пришло из Багланд С++ Builder(или как там этот VCL-ный уродец назывался).
У них там были насильно введено понятие properties — чтобы можно было в гриде редактировать. И геттер-сеттер понадобился соответственно. Вот людям и показалось, что это красиво.
Кроме того, приятная поддержка со стороны IDE — нажимаешь кнопку "новое поле" — а она тебе сразу заводит и приватное поле, и публичный (ирландский) сеттер. 3 клика по клавишам — а размер программы увеличился на 10 строк! Начальство видит, как проект растет не по дням, а по часам.
Практической пользы в геттерах-сеттерах нет и никогда не было, только кривизна. Когда тебе надо, например, удалить пробелы из члена, и вместо того, чтобы писать
Это ненормально. Кстати, вот где раздолье для пост-коррекции — если однажды ты заменишь тип контейнера с одних строк на другие (чур, об auto ни словечка в этом контексте!).
Да здравствует мыло душистое и веревка пушистая.
Re[2]: доступ к мемберам класса(getter'ы и setter'ы)
Здравствуйте, Vamp, Вы писали:
V>У меня ощущение, что это пришло из Багланд С++ Builder(или как там этот VCL-ный уродец назывался).
Свойства и в MSVC есть... V>У них там были насильно введено понятие properties — чтобы можно было в гриде редактировать. И геттер-сеттер понадобился соответственно. Вот людям и показалось, что это красиво.
Не поясните, каким боком тут редактирование грида? Если вы про грид, привязанный к данным, то там есть датасет и датасурс, свойства тут не при чем. Если про обычный грид, то там надо отрабатывать события "редактирование"...
V>Практической пользы в геттерах-сеттерах нет и никогда не было, только кривизна. Когда тебе надо, например, удалить пробелы из члена, и вместо того, чтобы писать V>class.member.trim(),
А часто ли надо так писать? Вы уверены, что class.member можно безболезненно триммить? Может тогда это будет struct.member?
По теме — лично я в классах использую геттеры и сеттеры. Часто поле можно извне только читать, а меняется оно через специальный метод (возможно вместе с другими полями).
CC>Т.е. к каждой переменной надо ещё и sort и все остальные inplace алгоритмы приделывать, которые могут понадобится?
Мне почему-то кажется, что если класс содержит несколько разных контейнеров, то их крайне редко надо независимо изменять из клиентского кода. Обычно у такого класса есть несколько методов, которые вносят согласованные изменения во все контейнеры сразу и геттеры, которые возвращают константные ссылки на некоторые из таких контейнеров.
Ну а если это не так — то возможно нам просто нужен не класс, а обычная структура...
Re[4]: доступ к мемберам класса(getter'ы и setter'ы)
Здравствуйте, DesertDragon, Вы писали:
DD>Претензии к Get|Set высказанные в этом топике являются результатом недоООП головного мозга. DD>Простая замена доступа к публичным переменным на гет/сет, не более чем синтаксический сахар, и по сути ничем не отличается от публичных переменных, так как не скрывает реализации класса. И соответственно не является инкапсуляцией.
Проблема в том что доступ к филдам не должен быть, это раз. Изучи принцып интерфейсов.
Во вторых, публичных переменных нету. Смотри пункт первый. Есть публичный интерфейс.
DD>Правильно названные методы класса, действительно скрывающие реализацию, в большинстве случаев не должны иметь слов Get/Set в своем имени.
Только потомучто у тебя алергия на слово Get|Set?
DD>Большинство учебных примеров по инкапсуляции в ООП к сожалению заканчиваются простыми геттерами/сеттерами, и справедливо вызывают вопросы "зачем это надо".
Это школьный пример, ты же на таблице умножений математику изучение не закончил? надеюсь
я не волшебник, я только учусь!
Re[3]: доступ к мемберам класса(getter'ы и setter'ы)
Здравствуйте, andrey_nado, Вы писали:
_>Здравствуйте, IROV.., Вы писали: IRO>>Итого get|set в классах в принцыпе не должно быть , так же как и public members _>Поясните, пожалуйста, Вашу мысль.
Попробую
почему не должно быть public members я пояснять не буду, это зделали многие люди стоит только поискать.
А вот из не совсем очевидных (не надо get, set) поясню
что такое get|set в класике?
это так называемый setup object.
сетапить обьект нужно, только в начале его работы, дальнейшее сомнительно(разве что дебаг).
Если в начале, то почему это не сделать методами initialize|load?
другие методы должны быть связаны с его жизне-деятельностью, и они обычно в одну строчку как "Просто set|get" увы редко получаються, да и смысл у них другой.
Давай наверное так, ты покажешь пример, а я попробую обяснить как было бы по другому, ибо писарь из меня никакой
Здравствуйте, Vamp, Вы писали:
Ytz>>Я понял — ради небольшого удобства открываем дыру в защите. V>Я что-то не врубился, где здесь ЗАЩИТА? От чего ЗАЩИЩАЕМСЯ?
Молодец, что спросил
Вариант 1:
class Connection
{
public:
void SetPort(unsigned port)
{
if (!PortAllowed(port))
...
if (PortAlreadyInUse(port))
...
Port_ = port;
}
bool Connect();
private:
unsigned Port_;
};
Я понял вашу мысль.
IRO>Давай наверное так, ты покажешь пример, а я попробую обяснить как было бы по другому, ибо писарь из меня никакой
Например, имеется некий объект с многочисленными настройками. Например, какая-нибудь числодробилка, которой можно выставить параметры типа величины временного шага, максимальной дельты и пр. Каждый параметр имеет значение по умолчанию и, в принципе, не обязательно должен устанавливаться клиентом. Но для спокойствия и поддержки нестандартных ситуаций возможность изменения параметров должна быть. Как её обеспечить, если не пользоваться геттерами/сеттерами? Параметры могут меняться скопом, но чаще поодиночке.
Дискуссия, кажется, сместилась от неинтересного "публичные поля vs. геттеры/сеттеры" к более интересному "геттеры/сеттеры vs. бизнес-методы".
Выше высказано утверждение, что если класс открывает свои поля в чистом виде (даже посредством геттеров), это недоработка его интерфейса. Класс должно открывать функциональность, а поля — его сугубо личное дело.
Я согласен, но с оговоркой. Это правило не для всех классов, а только для тех, кто реализует бизнес-логику. То есть классы-"субъекты".
Но кроме них есть и классы "объекты", то есть то, с чем оперируют "субъекты". Простой пример: класс Account с данными банковского счёта. По сути это простая структура. Кроме сеттеров и геттеров он может иметь методы типа isValid() с проверкой целостности данных и пр. Но главная его задача: хранить и предоставлять данные.
По-моему, очевидная ошибка проектировки создавать некий класс SuperAccount, который не открывает поля, зато предоставлять кучу бизнес методов на все случаи жизни: от CRUD до печати. То есть, бизнес-логика реализуется многими классами. А поскольку оперируют они одной и той же логической сущностью, то эта сущность должна отразиться в простом классе Account с геттерами и сеттерами.