Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не пользуйтесь функциями типа get/set, объясните смысл написанного 
V
    Опции темы
Rockie
Дата 7.7.2006, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



Цитата
ВЕРЕВКА ДОСТАТОЧНОЙ ДЛИНЫ, 
ЧТОБЫ ВЫСТРЕЛИТЬ СЕБЕ В НОГУ 
Правила программирования на С и С++ 
Ален И. Голуб


не понимаю предпоследний абзац. что хотел сказать автор этим правилом?

Цитата
110.1. Не пользуйтесь функциями типа get/set (чтения и присваивания значений). 

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

struct xxx 

{ 

int x; 

}; 


и: 

class xxx {

private: 

int x; 

public

void setx  ( int ix ){ x = ix;      } 

int    getx ( void )  { return x; } 

}


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

Сообщение реализует свойство. Открытая (public) функция реализует обработчик сообщения. Поля данных - лишние во внешнем мире; вы добавляете их лишь для того, чтобы иметь возможность реализовать свойство. Доступ к ним должен быть невозможен. 

Заметьте, что вы будете изредка видеть обработчик сообщений, который ничего не делает, кроме возврата содержимого поля или помещает в поле значение, переданное в виде аргумента. Этот обработчик тем не менее не является функцией типа get/set. Вопрос в том, как возникает такая ситуация. Нет абсолютно ничего плохого в том, если вы начинаете с ряда сообщений и затем решаете, что самым простым способом реализации сообщения является помещение специального поля в определение класса. Другими словами, этот обработчик сообщений не является усложненным способом доступа к полю; скорее, это поле является простым способом реализовать сообщение. Хотя вы попали в то же место, вы попали туда совершенно другим путем. 

Конечно, эта организация означает, что С++ не может быть эффективно использован в гибридной среде С/С++, потому что интерфейс между двумя половинами программы уничтожает инкапсуляцию, которой вы так сильно старались добиться. В известном смысле жаль, что С++ создан на основе С, потому что это просто подстрекает нас к ошибкам.
 


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
bsa
Дата 7.7.2006, 21:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Думаю, автор имел в виду, что если у тебя член класса x методами get и set только читается и изменятся, то эти методы не имеют смысла, так как компилятор все равно при оптимизации будет просто подставлять значение данного члена (без вызова метода).
Вот только я не уверен, что неиспользование это хорошо. По-моему, лучше get/set использовать, так как в случае если при изменении данного параметра придется еще выполнять ряд действий, то не придется менять интерфейс класса (проще говоря, не придется переписывать уже написанные программы, использующие этот класс).
А читабельность можно повысить правильным форматированием. smile 
PM   Вверх
Fazil6
Дата 7.7.2006, 22:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



bsa, 
нет совсем не это имел в виду автор. В этой книге автор несколько раз приводится пример про календарь.
на самом деле имеется в виду, что данные класса в правильно спроектированном классе не представляют инттереса вне класса. Нужно рассматривать класс, как самодостаточную вещь и оперрировать не данными класса, а его интерфейсом. Подход в том, что данные закрыты не для того чтобы просто затруднить к ним доступ, а в первую очередь потому, что в правильном классе нет необходимости в доступе к данным извне класса, а есть функции типа "сделай что-то" , "создай это" и тд. 
а set и get на самом деле  по сути  нарушают инкапсуляцию 
PM MAIL   Вверх
DeadSoul
Дата 7.7.2006, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1217
Регистрация: 25.9.2005
Где: Москва

Репутация: 2
Всего: 11



Цитата(bsa @  7.7.2006,  21:44 Найти цитируемый пост)
Думаю, автор имел в виду, что если у тебя член класса x методами get и set только читается и изменятся, то эти методы не имеют смысла, так как компилятор все равно при оптимизации будет просто подставлять значение данного члена (без вызова метода).

В этом автор ошибается. 
1. С течением времени смысл этих методов может изменится
2. С getter-ами\setter-ами проще отлаживатся, т.е. найти то место где туда устанавливается не очень корректное значение
 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
Fazil6
Дата 7.7.2006, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

А читабельность можно повысить правильным форматированием.

про читабельность там с иронией говорится.

Добавлено @ 22:19 
Цитата

С getter-ами\setter-ами проще отлаживатся, т.е. найти то место где туда устанавливается не очень корректное значение
весь смысл в том, что установка 
Цитата

не очень корректное значение
по сути и есть нарушение инкапсуляции и в хорошо спроектированной программе данные классов не устанавливаются и не считываются 
PM MAIL   Вверх
bsa
Дата 7.7.2006, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Fazil6
Тебе бы книжки писать - объяснение намного понятнее. smile 
PM   Вверх
sergejzr
Дата 7.7.2006, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 19
Всего: 360



Fazil6, хорошо обьяснил.

Я тоже так понял, что автор не призывает "ни в коем случае не использовать геттеры и сеттеры". А хочет сказать, что если они в программе вдруг станут необходимы - класс спроектирован плохо. 


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Fazil6
Дата 7.7.2006, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



вообще-то я советую всем, кто не читал эту книжку, прочитать, хоть она и не первой свежести. Автор четко знает о чем пишет, все с прекрасными примерами из жизни и юмором. Читается очень увлекательно  
PM MAIL   Вверх
Rockie
Дата 7.7.2006, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



Цитата(Fazil6 @  7.7.2006,  22:09 Найти цитируемый пост)
 в правильном классе нет необходимости в доступе к данным извне класса, а есть функции типа "сделай что-то" , "создай это" и тд. 
а set и get на самом деле  по сути  нарушают инкапсуляцию 


Ага! Если я правильно понял, то, к примеру, вместо set использовать инициализацию в конструкторе, а заместо get использовать к примеру методы "Распечататься",  "Записаться в файл" и др. Таким образом, необходимость в методах set и get должна отпасть сама собой. 

bsa, 
Fazil6, 
DeadSoul, 
sergej.z, 
всем участникам большое спасибо! 


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
En_t_end
Дата 8.7.2006, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



А почему нельзя get'ы использовать ?(c set'ами все понятно...)

Добавлено @ 11:45 
допустим, мне нужно собрать статистику со всех классов. В каждом классе есть метод GetOccupied. Неужели этот метод нарушает инкапсуляцию ? То есть технологию аксессоров нельзя применять ?  
PM MAIL ICQ Skype GTalk Jabber   Вверх
ivashkanet
Дата 8.7.2006, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(sergej.z @  7.7.2006,  22:20 Найти цитируемый пост)
 автор не призывает "ни в коем случае не использовать геттеры и сеттеры". А хочет сказать, что если они в программе вдруг станут необходимы - класс спроектирован плохо. 

А как передавать настройки новому классу?
Через методы, или может в конструкторе?
Цитата(Rockie @  7.7.2006,  22:55 Найти цитируемый пост)
а заместо get использовать к примеру методы "Распечататься",  "Записаться в файл" и др.

То же, ИМХО, ерунда. Невозможно учесть все возможные стороны применения нашего класса. Что если через год нам понадобиться метод которого нет? Переписывать класс?

P.S. Стандартные классы направо и налево используют открытые свойства. 
Врятли программисты не знали свое дело, когда проектировали их. Даже больше -- они же и создавали стандарты языка smile 
Представьте что бы было если бы "самый главный" класс Form не имел открытых свойств. Что бы тогда было. Заголовок, положение, размеры, ... все передавать через конструктор?
+ Обясните мне разницу между методом Form.SetCaption("Название формы") и Form.Caption = "Название формы" с точки зрения работы программы? ... Да ее просто НЕТ smile 
P.P.S. Я сам .Net-чик, поэтому не знаю как в С++ называется свойство заголовка формы smile

Добавлено @ 13:51 
Продолжу smile 
Несомненным плюсом Сеттеров является то, что мы можем провести валидацию данных и в случае несоответствия выкинуть исключение. Именно поэтому не стоит использовать открытые поля классов. Они не поддерживают валидацию.
У Геттеров такого явного преимущества нет  smile Кроме как запрета на чтение значения поля.
 smile P.S. Автор может и знает свое дело, но, ИМХО, писать не умеет  smile . Сполшные сложные предложения, обороты... Пришлось дважды перечитывать, прежде чем войти в курс дела.
Перечитайте этот отрывок. Все ли понятно после первого прочтения?
Цитата(Rockie @  7.7.2006,  21:28 Найти цитируемый пост)
Заметьте, что вы будете изредка видеть обработчик сообщений, который ничего не делает, кроме возврата содержимого поля или помещает в поле значение, переданное в виде аргумента. Этот обработчик тем не менее не является функцией типа get/set. Вопрос в том, как возникает такая ситуация. Нет абсолютно ничего плохого в том, если вы начинаете с ряда сообщений и затем решаете, что самым простым способом реализации сообщения является помещение специального поля в определение класса. Другими словами, этот обработчик сообщений не является усложненным способом доступа к полю; скорее, это поле является простым способом реализовать сообщение. Хотя вы попали в то же место, вы попали туда совершенно другим путем. 


 
PM MAIL WWW ICQ   Вверх
Daevaorn
Дата 8.7.2006, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(ivashkanet @  8.7.2006,  14:38 Найти цитируемый пост)
поэтому не знаю как в С++ называется свойство заголовка формы 

Хорошая шуткаsmile

Цитата(ivashkanet @  8.7.2006,  14:38 Найти цитируемый пост)
Стандартные классы направо и налево используют открытые свойства. 

Можно пример? Ещё привлекает внимаение слово "свойства"...

Цитата(ivashkanet @  8.7.2006,  14:38 Найти цитируемый пост)
То же, ИМХО, ерунда. Невозможно учесть все возможные стороны применения нашего класса. Что если через год нам понадобиться метод которого нет? Переписывать класс?

Да. Если такое произошло - значит существет ошибка в проекитировании этого самого класса. 
PM MAIL WWW   Вверх
Fazil6
Дата 8.7.2006, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

А как передавать настройки новому классу?
Через методы, или может в конструкторе?

именно через методы или в конструкторе.
Цитата

То же, ИМХО, ерунда. Невозможно учесть все возможные стороны применения нашего класса. Что если через год нам понадобиться метод которого нет? Переписывать класс?
это ты ерунду пишешь. Реализовывать надо то, что нужно, а не то, что когда-нибудь может пригодиться. 

Не думай, что гуишные классы NET, VCL или MFC являются стандартом программирования и речь идет о ООП в теории, а не конкретной реализации конкретных классов.
Свойство - это интерфейс класса, а не данные класса и именно об этом говорит автор. 
PM MAIL   Вверх
ivashkanet
Дата 8.7.2006, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(Daevaorn @  8.7.2006,  14:36 Найти цитируемый пост)
Хорошая шутка

Цитата(ivashkanet @  8.7.2006,  13:38 Найти цитируемый пост)
Form.Caption

Я что угадал? У нас (в .Net) заголовок формы устанавливается через Form.Text  smile 

Цитата(Daevaorn @  8.7.2006,  14:36 Найти цитируемый пост)
Ещё привлекает внимаение слово "свойства"...

Поля класса -- конретные "переменные" класса, т.е. его данные.
Свойства -- "обертки" для полей класса, сделанные с помощью get и set.
Врятли от языка к языку эти понятия меняются.  smile 
Цитата(Daevaorn @  8.7.2006,  14:36 Найти цитируемый пост)
Можно пример?

Я ведь дал пример 
Цитата(ivashkanet @  8.7.2006,  13:38 Найти цитируемый пост)
Заголовок, положение, размеры, ...

А вообще зайди IDE, выдели любой класс и любуйся открытыми СВОЙСТВАМИ в закладке Propertes.
Там перечисленны только они, полей нет smile 
Цитата(Fazil6 @  8.7.2006,  14:46 Найти цитируемый пост)
Свойство - это интерфейс класса, а не данные класса и именно об этом говорит автор. 

А я что спорю  smile 
Цитата(Fazil6 @  8.7.2006,  14:46 Найти цитируемый пост)
это ты ерунду пишешь. Реализовывать надо то, что нужно, а не то, что когда-нибудь может пригодиться. 

После нас хоть потоп. Да?
Представьте ситуацию: 
Мы спроектировали класс, который что-то обрабатывает, а потом выводит на экран (ShowOnScreen()). 
Мы продали этот класс. Его используют другие люди. Всем нравится, все в восторге.
Через некоторое время понадобился вывод на принтер. Они связваются с нами, мы лезем в код добавляем метод (SendToPrinter()). Через время понадобился вывод еще на что-нибудь...
Это выход? Вместо того чтобы открыть результат вычислений, после чего любой сможет написать свой вывод на что угодно.
О  smile придумал еще пример:
Вы вешаетесь на событие формы Resize, вам нужно перепозиционировать контролы на форме. Как это сделать, если размеры формы закрыты?

Обожаю когда люди критикуют только часть сообщения, а не всё полностью
Почему не было комментариев по этому поводу:
Цитата(ivashkanet @  8.7.2006,  13:38 Найти цитируемый пост)
Обясните мне разницу между методом Form.SetCaption("Название формы") и Form.Caption = "Название формы" с точки зрения работы программы?

или
Цитата(ivashkanet @  8.7.2006,  13:38 Найти цитируемый пост)
Представьте что бы было если бы "самый главный" класс Form не имел открытых свойств. Что бы тогда было. Заголовок, положение, размеры, ... все передавать через конструктор?

 
PM MAIL WWW ICQ   Вверх
En_t_end
Дата 8.7.2006, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Цитата(En_t_end @  8.7.2006,  15:42 Найти цитируемый пост)
А почему нельзя get'ы использовать ?(c set'ами все понятно...)
Добавлено @ 15:45 
допустим, мне нужно собрать статистику со всех классов. В каждом классе есть метод GetOccupied. Неужели этот метод нарушает инкапсуляцию ? То есть технологию аксессоров нельзя применять ?  

Мне ответьте smile пожалуйста...
 
PM MAIL ICQ Skype GTalk Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0745 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.