LINUX.ORG.RU

Структура vs класс


0

0

Часто замечаю вот такое. Вместо

struct Name { int param1; int param2; }

используют класс с доступом к переменным через функции (set, get). В той же Qt я вообще ни разу не видел «прямой» доступ к переменным. Чем это объясняется? Почему использование функций предпочтительнее? Всё таки количества кода во втором случае явно больше.

Ответ на: комментарий от legolegs

Это да, кстати... Программирование - опасное дело! В программах иногда случаются ошибки! :D

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> И нужно быть совершенно клиническим идиотом, чтобы не видеть последствий от замены прямого вывода на тяжёлый запрос и не заметить такой особенности

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

Ты виляешь из стороны в сторону. У тебя уже не осталось никаких аргументов кроме совершенно детского и бессмысленного упрямства.

Это сказал ты, несущий бред с самого начала? То у тебя по условиям ТЗ тут должны быть сеттеры и геттеры, то вообще нам это надо, чтобы сегодня быстро запустить хоть как-то, а завтра быстренько переделать на загрузку из базы, когда туда всё забьют. Отличные примеры, не спорю.

kemm
()
Ответ на: комментарий от KRoN73

> Для объектов, для использования в шаблонах, требуется возвращать название страны.

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Поэтому я и сказал, что задача специально сделана для демонстрации необходимости геттера.

нет. Выбор между полем и геттером лежит на программисте.

legolegs ★★★★★
()
Ответ на: комментарий от jtootf

> учитывая, что свою позицию я изложил ровно полтреда назад

Лукавишь. Твоя позиция была изложена в третьем комменте этого треда:

никакой полезной абстракции геттеры не предоставляют


jtootf (*) (21.01.2010 16:10:52)

По части продолжения нашей дисскуссии, я согласен. Она вроде как закончена. Во всяком случае, лично я не вижу, _что_ продолжать.

P.S. Да, я её тоже вел исключительно из человеколюбия и желания потрындеть. )))

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Лукавишь

вот зануда, ну. полтреда назад было дано развёрнутое изложение

По части продолжения нашей дисскуссии, я согласен. Она вроде как закончена

и потому давайте все дружно писать хороший код, а плохого кода не писать вовсе. и будет всем счастье :)

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

[толсто]А хороший код - это с геттерами, исключениями, snake_case, отступами в два пробела и комментариями на английском[/толсто]

legolegs ★★★★★
()
Ответ на: комментарий от legolegs

> [толсто]А хороший код - это без геттеров, с исключениями, snake_case, отступами в 1 таб и комментариями на языке команды разработчиков[/толсто]

fxd

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>>> Поэтому я и сказал, что задача специально сделана для демонстрации необходимости геттера.

нет.

Да


MVC-подход подразумевает разделение кода и визуализации. При чём в общем случае кодом и визуализацией занимаются разные люди. Это уже автоматически подразумевает унификацию интерфейсов и сокрытие структуры объекта.

Если такая формулировка для тебя означает «задача сформулирована так, что требует наличия геттеров» - то и славненько. В очередной раз повторюсь, что я не за то, чтобы геттеры были всюду. Я против утверждения о том, что геттеры не нужны вообще.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Если такая формулировка для тебя означает «задача сформулирована так, что требует наличия геттеров»

Нет. Вот это:

предлагаешь делать сейчас прямое обращение к public-полю класса, а завтра переписать всё на использование метода? А если объектов в шаблон подаётся более одного вида и часть может возвращать строку как есть, а часть - генерировать?

означает «задача сформулирована так...»

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Если твой шаблонизатор требует от объекта реализации конкретного интерфейса

Это не мой шаблонизатор, это, как бы, правило хорошего тона в отрасли. Без которой год считается говном :)

то и выхода какбэ нет


Ну и славненько. Значит, глобальный тезис «геттеры не нужны» уже опровергнут.

KRoN73 ★★★★★
()
Ответ на: комментарий от tailgunner

>означает «задача сформулирована так...»

Просто задача показывает типовую ситуацию в любом развивающимся со временем проекте.

...

И, возвращаясь к исходной посылке, с которой начался спор, похоже, разработчики Qt тоже уже усвоили этот опыт.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Значит, глобальный тезис «геттеры не нужны» уже опровергнут.

А его никто и не выдвигал. Геттеры, которые сделаны «про запас», на всякий случай - не нужны. И есть мнение, что это подавляющее большинство геттеров.

tailgunner ★★★★★
()
Ответ на: комментарий от KRoN73

> Опять голый троллинг. Ну, как знаешь...

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

kemm
()
Ответ на: комментарий от tailgunner

>А его никто и не выдвигал.

Здрасьте. Всё начало темы было в этом:
- http://www.linux.org.ru/jump-message.jsp?msgid=4464779&cid=4464788
- http://www.linux.org.ru/jump-message.jsp?msgid=4464779&cid=4464792

и т.д.

Геттеры, которые сделаны «про запас», на всякий случай - не нужны.


А это - другой случай. Вот, в моей практике - они себя окупают. Учитывая, насколько я ленив - это показательно :)

KRoN73 ★★★★★
()
Ответ на: комментарий от kemm

>Да я уже понял, что с вебостатистикой я угадал

Нет, не угадал. Вообще, в этой темы ты, сорри за тавтологию, совсем не в теме.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>>А его никто и не выдвигал.

Здрасьте. Всё начало темы было в этом:

- http://www.linux.org.ru/jump-message.jsp?msgid=4464779&cid=4464788

- http://www.linux.org.ru/jump-message.jsp?msgid=4464779&cid=4464792

Там по контексту ясно, что речь идет об избыточных геттерах:

класс с доступом к переменным через функции (set, get)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Там по контексту ясно, что речь идет об избыточных геттерах

Мне не ясно. Когда я вижу высказывания, типа «никакой полезной абстракции геттеры не предоставляют», то я понимаю это толко как то, что геттеры не нужны :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Нет, не угадал

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

Даже если я ошибся, это не отменяет остальной части комментария. Твои крайне узкие условия ничем не лучше QProperty.

kemm
()
Ответ на: комментарий от jtootf

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

интересный наивно-радикальный ООП (или это стиль хаскеля?)

минимальные воспоминания о Кодде и нормализации подсказали бы вопрос: а что, если функция функционально зависит от одного поля, а не от всего АТД?

допустим у нас есть user-а в разных городах, которые могут друг другу продавать всякую фигню

вариант 1: p = postal_delivery_price(user1, user2)

вариант 2: p = postal_delivery_price(user1.get_town(), user2.get_town())

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

в варианте 1 postal_delivery_price необходимо сделать приватной для класса User; в реальном проекте таких функций наберется немеряно (вспоминаем о популярности реляционных СУБД)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

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

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от jtootf

А разве при реализации абстракции нельзя использовать ее собственный интерфейс? Например, размер контейнера — это интерфейс или деталь реализации?

eugine_kosenko ★★★
()
Ответ на: комментарий от www_linux_org_ru

интересный наивно-радикальный ООП (или это стиль хаскеля?)

вообще-то это очевидный факт. не особо зависящий от парадигмы

функция функционально зависит от одного поля, а не от всего АТД?

и что?

в варианте 1 postal_delivery_price необходимо сделать приватной для класса User

а в варианте 2? и какое это вообще имеет отношение к обсуждаемой теме?

jtootf ★★★★★
()
Ответ на: комментарий от eugine_kosenko

А разве при реализации абстракции нельзя использовать ее собственный интерфейс?

не понял. что имеется в виду?

размер контейнера — это интерфейс или деталь реализации?

интерфейс

jtootf ★★★★★
()
Ответ на: комментарий от eugine_kosenko

Например, размер контейнера — это интерфейс или деталь реализации?

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

jtootf ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

интересный наивно-радикальный ООП

http://martinfowler.com/bliki/GetterEradicator.html

http://typicalprogrammer.com/?p=23

этот интересный наивно-радикальный ООП, внезапно, является доминирующим подходом в объектном проектировании. тебя это не смущает, нет? вбей в своём любимом поисковике «getters encapsulation» и оцени количество критических статей. Фаулера, Голуба, Мейерса. наивных и радикальных

jtootf ★★★★★
()
Ответ на: комментарий от KRoN73

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

eugine_kosenko ★★★
()

Кстати, в каноническом ООП есть понятие аксессора, которое кое-кто пытается выдать за определение геттера.

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

>Есть еще примеры?

В других популярных языках всё решается проще на уровне синтаксиса. И поэтому сам вопрос не возникает.

KRoN73 ★★★★★
()
Ответ на: комментарий от eugine_kosenko

само использование getX чисто по Фрейду как бы намекает, что в объекте уже как бы есть X и мы как бы можем его get

проектирование с точки зрения психоанализа - это интересно :)

jtootf ★★★★★
()
Ответ на: комментарий от eugine_kosenko

>Вообще, само использование getX

Кстати, в тех проектах, где я задаю стиль, я отказался от использования префикса «get». Он подразумевается по умолчанию и эргономичность выражений, типа getInstance()->getWorlds()->getObject(id)->getCoords()->getX() сильно повышается :)

А в редких случаях, когда нужно отличить существительное от глагола использую префиксы do или on. Типа, do_job() (а, да, ещё предпочитаю snake_style :) - это ближе к естественному языку)

KRoN73 ★★★★★
()
Ответ на: комментарий от eugine_kosenko

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

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

И вся эта ересь ползет из Явы, которая, в отличие от C++, не исповедует принципов суворого проектирования.

eugine_kosenko ★★★
()
Ответ на: комментарий от jtootf

И кстати, да, хороший тест. Ведь в примере с getCountry наверняка не было симметричного setCountry, а это значит, что достаточно было обойтись country, если этого явно требовал спроектированный интерфейс.

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

>Ведь в примере с getCountry наверняка не было симметричного setCountry

Обязательно был. Как же без него данные-то вводить? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от eugine_kosenko

Единственное оправданное использование я видел только в Эйфеле, где поля класса синтаксически неотличимы от вызова функций без аргументов, а прямое присваивание полям класса, в отличие от Паскаля, запрещено в принципе для защиты абстракции.

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

>Присваиванием, вестимо.

Даже если перед сохранением требуется обрабатывать результат. Или, там, проверять на корректность?

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

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

eugine_kosenko ★★★
()
Ответ на: комментарий от eugine_kosenko

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

eugine_kosenko ★★★
()
Ответ на: комментарий от Booster

Да, свойства решают проблему, но там всплывает проблема автомагического поведения, из-за которой многим так не нравится C++.

eugine_kosenko ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.