LINUX.ORG.RU

Как избавляться от длинных цепочек xxx.yyy.zzz и надо ли?

 


0

2
...
warehouse.elem[window].data.win.eventsmask
warehouse.elem[button].data.btn.window
warehouse.elem.elements[index].properties[WIDTH].value
warehouse.elem[index].data.btn.geometry.height
warehouse.elem[image16].data.img.image->data
...

Нужно ли избавляться от таких цепочек в ущерб читаемости?
Как дело с этим обстоит у вас?

Сабж.

★★

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

minakov ★★★★★
()

Нужно ли избавляться от таких цепочек в ущерб читаемости?

Если нормально называть, то читаемость будет только повышаться.

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

Просто когда вижу что-то типа

warehouse.elem[window].data.win.eventsmask = warehouse.elem[window + 1].data.win.eventsmask + warehouse.elem[window - 1].data.win.eventsmask;
// Пример из головы
мне кажется, что это перегиб.

sambist ★★
() автор топика

с помощью указателей можешь избавиться

а так же выносить изменение параметров в отдельные инлайн функции.

dimon555 ★★★★★
()

Нужно ли избавляться от таких цепочек в ущерб читаемости?

Это гогно сдеать ещё менее читабельным довольно проблематично. Избавляться от него нужно методом разбиения данных на логические кучки (~объекты) и кода на небольшие операции над ними. Как в этом случае сделать это не ясно, мало данных, с ходу можно только вынести warehouse.elem в отдельный указатель

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

Называть надо нормально. Единственный минус - долго набирать. А читать просто. Компилятор вообще оптимизирует такие цепочки до одного обращения по адресу.

ziemin ★★
()

Почитайте LDD (linux device drivers), а ещё лучше любой сетевой драйвер, например из 802.11 стека - там как раз отлично видно, как с этим бардаком работать. Как выше уже писали - приводить к указателю на самый нижний элемент структуры и обращаться уже к его элементам проще, а самое главное наглядно.

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

да что вы говорите!

у нас такое говно невозможно, т.к. private: не даёт доступ.

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

warehouse.elem(window).data().win().eventsmask()
warehouse.elem(button).data().btn().window()
warehouse.elem(index).data().btn().geometry().height()
warehouse.elem(image16).data().img().image()->data
Stil ★★★★★
()

У тебя слишком высокая связность кода.

Нужно ли избавляться от таких цепочек в ущерб читаемости?

Будто эта каша хоть сколько-нибудь читаема.

Redrum
()
Ответ на: комментарий от z00ke

Для питона это ещё даёт большой оверхед по производительности, он принципиально не умеет оптимизировать такие вещи.

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

а нахрена это писать? Не, я просто не понимаю, объясни пожалуйста.

Твой пост был о:

у нас такое говно невозможно, т.к. private: не даёт доступ.

невозможно, т.к. private

Так вот private никак не влияет на возможность городить такие цепочки. Зачем так делать мне наплевать.

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

Так вот private никак не влияет на возможность городить такие цепочки. Зачем так делать мне наплевать.

так вот, private не даст пользователю класса залезть в кишки класса. Т.е. можно только foo.bar, даже если bar что-то там своё имеет. Это AFAIK называется «инкапсуляция», хотя конечно я быдлокодер, и возможно пацаны меня не поймут. Но мне так проще, ибо связанность классов не слишком сильна, и их проще поддерживать.

Всё ИМХО.

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

И? Расскажите, как инкапсуляция избавляет вас от таких цепочек. Если класс простой (foo.bar), то само собой ничего такого не произойдёт. Но если поля класса сложные объекты (другие классы) со своими геттерами/сеттерами, то получается то же самое. Или же вы отслеживаете подобные вещи и приводите их к простому виду (foo.bar.get.set.add к виду foo.bagetAdd)? Речь ведь о доступе к «кишкам» класса не шла. Речь о цепочках, возникающих из-за сложной структуры.

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

Или же вы отслеживаете подобные вещи и приводите их к простому виду (foo.bar.get.set.add к виду foo.bagetAdd)? Речь ведь о доступе к «кишкам» класса не шла. Речь о цепочках, возникающих из-за сложной структуры.

да, отслеживаю. bar делается private, потому к нему не обратится напрямую. Только косвенно. Потому что bar.get.set.add(int) может стать bar.get.set.add(double) и всё поломать на много уровней выше.

Я не говорю, что я всегда так делаю, но ИМХО к этому надо стремиться.

emulek
()

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

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

так вот, private не даст пользователю класса залезть в кишки класса. Т.е. можно только foo.bar, даже если bar что-то там своё имеет. Это AFAIK называется «инкапсуляция», хотя конечно я быдлокодер, и возможно пацаны меня не поймут. Но мне так проще, ибо связанность классов не слишком сильна, и их проще поддерживать.

private не даёт пользователю залезть в кишки класса, да. Но зачастую акцессоры это свойство как раз таки нарушают. Замена `public: int x;` на `private: int x; public: int getX(); void setX(int)` не меняет ровным счётом ничего. Статейка на тему - why getters and setters are evil. Да, а за байки типа «а мы вдруг внезапно когда-нибудь захотим это поле брать из бд» предлагаю сразу жечь на кострах.

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

Статейка на тему - why getters and setters are evil. Да, а за байки типа «а мы вдруг внезапно когда-нибудь захотим это поле брать из бд» предлагаю сразу жечь на кострах.

Статью, учитывая мои знания английского, буду мучить долго. Но основной смысл геттеров-сеттеров в проверке вводимого значения, единообразии и расширяемости. И почему жечь на кострах? БД, не БД, но ведь с расширением системы поле может поменять тип, стать куда более сложным. А интерфейс должен остаться интерфейсом.

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

Замена `public: int x;` на `private: int x; public: int getX(); void setX(int)` не меняет ровным счётом ничего.

меняет.

Статейка на тему - why getters and setters are evil.

может в этой вашей яве и так. Ваши явапроблемы. Да и никто не предлагал на каждый int x делать getters.

Да, а за байки типа «а мы вдруг внезапно когда-нибудь захотим это поле брать из бд» предлагаю сразу жечь на кострах.

жечь нужно за не поддерживаемый говнокод, который ты пишешь.

emulek
()
Ответ на: комментарий от Weres

И почему жечь на кострах?

потому что видимо ява не умеет это инлайтить. И всё тупит.

emulek
()
Ответ на: комментарий от drSchur

Не, ну можно форматировать, чуть понятней будет:

warehouse.elem[window].data.win.eventsmask = 
   warehouse.elem[window + 1].data.win.eventsmask + 
   warehouse.elem[window - 1].data.win.eventsmask;

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

Сделай макросом

#define EVENTMASK(w) warehouse.elem[w].data.win.eventsmask

/* ... */

EVENTMASK(window) = EVENTMASK(window + 1) + EVENTMASK(window - 1);

/* ... */
#undef EVENTMASK
anonymous
()
Ответ на: комментарий от Laz

Никогда не понимал людей, дающих ссылку на английскую википедию, при наличии нормальной статьи в русской.

vzzo ★★★
()

Нормальный код.

Deleted
()
Ответ на: комментарий от emulek

у нас такое говно невозможно, т.к. private: не даёт доступ.

Автор вроде бы хотел поговорить о C, а не о C++? Или он тег поставил, не подумавши?

sambist, ты ведь Си имел в виду?

hobbit ★★★★★
()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

ну в Pure C это ИМХО тоже быдлокод, т.к. нельзя выпячивать наружу внутренности структур. ИМХО в этом случае всё должно делаться через структуру-интерфейс, а лучше через нестатические функции-интерфейс. А если это вредит производительности, то обработка должна быть реализована в одном модуле сборки. В одном *.c/*.obj файле. Тогда компилятор инлайтит внутренние статические функции, и в итоговом машинном коде нет никакого оверхеда от инкапсуляции.

Опять: ИМХО. Если кто не согласен, то пожалуйста приведите пример, в котором я не прав. А лолки стройными рядами идут прочь.

emulek
()
Ответ на: комментарий от vzzo

Никогда не понимал людей, дающих ссылку на английскую википедию, при наличии нормальной статьи в русской.

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

emulek
()
Ответ на: комментарий от anonymous

Сделай макросом

нахрена, если можно сделать статическую функцию? Сейчас не 20й век, компилятор её заинлайтит даже лучше твоего макроса.

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

нахрена, если можно сделать статическую функцию? Сейчас не 20й век, компилятор её заинлайтит даже лучше твоего макроса.

Э? У вас контекст в голове держится? Напоминаю, вопрос был про то как сделать длинные «цепочки» более читаемыми. Это можно делать макросами, например, о чем я и написал. И привел небольшой пример

anonymous
()
Ответ на: комментарий от sambist

Давай, покажи мне реализацию того же самого по Деметре на сях.

а вот как раз на сях это ещё более важно. В C++ это само собой получается, а в сишечке нужно усилия прилагать. Можно не прилагать, вот только ничего сложнее хэлловорлда на 100 строк ты не напишешь. Увы.

emulek
()
Ответ на: комментарий от anonymous

Э? У вас контекст в голове держится? Напоминаю, вопрос был про то как сделать длинные «цепочки» более читаемыми. Это можно делать макросами, например, о чем я и написал. И привел небольшой пример

это НЕЛЬЗЯ делать макросами. Потому что макросы только заметают мусор под ковёр. Тут проблема совсем не в читаемости. Читаемость(нечитаемость точнее) только одно из следствий проблемы. Если хреново с английским, я проверил, на русской вике есть годная статья про LoD.

У концепции LoD есть недостатки, но если пользоваться современным gcc, то это мелочи, и на них не стоит обращать внимание. За счёт более лучшей и удобной архитектуры код будет работать на порядок быстрее, невзирая на какие-то потери каких-то трёх тактов.

К тому же, отход от LoD это преждевременная оптимизация, ещё один 146% детектор говнокодера.

emulek
()
Ответ на: комментарий от Weres

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

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

с расширением системы поле может поменять тип, стать куда более сложным

Например, было int, стало float? Сомневаюсь, что акцессоры здесь помогут.

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

Например, было int, стало float?

Например, было int стало struct. С использованием акцессоров и перегрузки операций (в си её нет, но я не про него) можно оставить как старый вариант, только снабдить его умолчательными значениями, так и новый используемый, например, для более тонкой настройки.

К сожалению, зачастую акцессоры этому воспрепятствуют.

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

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

Гм. Неловко спрашивать, но вы вообще на С программировали?

а вы? Уверен — нет. Ибо поиск ошибки в макросе — вам это не знакомо. А её хрен найдёшь, т.к. код отлично собирается, и даже работает. Но работает НЕ ТАК. Потому что макрос не так развернулся. И за макросом этого НЕВИДНО.

Ну ничего, вы ещё попомните, если в профессии останетесь...

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

Гм. Неловко спрашивать, но вы вообще на С программировали?

а вы?

Ясно. Простите, больше не буду вас беспокоить

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