- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
Люди, помогите решить такой вопрос. Приведу пример:
Есть программист Петя. Он прочитал очень много книг по программированию,
и вообще умный парень :). И, так как, Петя прочитал много умных книг (Александреску к примеру),
он соответственно пишет умный код, используя различные фишки с++, например,
очень любит шаблоны (такие вещи типа статического полиморфизма и еще много
всего связанного с шаблонами и обобщенным программированием) или использует
сложные тернарные операторы… ну и т.д. … Соответственно код работает и все хорошо.
Как-то в разговоре с Петей ему сказали, что если так прогать, то может получиться
непрозрачный код.
На что он ответил: «Если алгоритм написан верно, и Каму-то непонятен код, то
проблема в том что человек просто плохо образован в плане программирования.
Ибо кто-то, например, не знает что такое классы и ему будет не прозрачен код,
в котором используют классы или обычное наследование. И соответственно не
писать же все процедурно, из-за того, что кто-то не знает что такое классы.
А само понятие прозрачности кода - ерунда ».
От сюда вопрос, Прав ли Петя и что такое вообще «Прозрачность кода»?
Или действительно код не может быть написан «Заумно», а тот, кто так
считает, просто плохо знает стандарт языка.
Вопрос совершенно серьёзный. //Не холивар.
в самом деле, ну что можно сказать нового о паттернах после GoF?
я это всё знаю сказал я себе и машинально поставил книгу обратно на полку
потом спустя какое-то время до меня начали доходить отголоски и мнения касательно этой книги, что это действительно новое слово в программировании
ну новое так новое, надо бы ознакомиться
книга была куплена, вдохновенные предисловия прочитаны одним махом и...
дальше я встрял на первой же главе, обилие "жёстких" шаблонов в тексте напомнило мне о студенческих временах, когда мне приходилось делать вид, что я понимаю разнообразные закорючки в учебниках по матану
неприятие было ровно такое же
какие-то абстрактные заумные закорючки
поэтому дальше я просто заставил себя всё это прочитать...
но без практики (вернее без сопряжения с ней, тогда на работе хреначил какой-то очередной ударный ОО код) увы, чтение это оказалось бесполезным и всё быстренько повыветрилось
мол прикольно, но непонятно как это использовать, где это использовать и главное, зачем это использовать?
но некоторые идеи мне показались прикольными
особенно в части разумной альтернативы ОО подходу, с ортогональными стратегиями и всеобщей идеологией переноса всего что только можно на стадию компиляции
на работе я пытался "ошаблонить" некоторые текущие задачки, но получалось как-то громозко неклюже, и главное совсем не к месту, код прекрасно смотрелся и работал без этого
Хотя, боюсь, обрывков в гк-форме не хватит, чтобы оценить его как следует.
так продолжалось до тех пор, пока я не перешёл в контору, где лид-архитект работал в парадигме GP
признаться я и раньше заглядывал в исходники STL и boost и обилие шаблонов всегда вымораживало
какие-то вещи казались просто магией, например пустые шаблоны, содержащие в себе лишь typedef
если такую пустую конструкцию убрать,
то компилятор начинал выдавать километры невнятных сообщений
а тут я увидел прямо в коде игрового сервера феерический веер шаблонов
отступать было некуда
пришлось сесть и разбираться
и тут я увидел на практике КАК это работает
первую же мою задачу я старался выдержать в духе увиденного, параллельно сверяясь с Александреску, я честно нахреначил две стратегии, одна из которых так потом и не пригодилась, и постарался написать код, просто визуально похожий, лаконичный, с кучей угловых скобочек и двойных двоеточий, благо что исходными "кубиками" послужил boost где такого добра навалом
дальше больше и вуаля, я взял барьер непонимания обобщённого программирования, и это РАБОТАЛО
сейчас честно скажу, я разумно-осознанно (а не механически как раньше) дочитал Александреску лишь до конца третьей главы
и этого вполне достаточно:
списки типов
шаблонные шаблонные параметры шаблонов которые есть только в С++
и два генератора GenScatterHierarchy и GenLinearHierarchy
с этим нехитрым набором (+ ассерты, в т.ч. статические) можно и впрямь перекладывать львиную долю работы на компилятор : ))*/
Крестошаблоны не предназначались для подобных фишечек, поэтому подобное их использование выглядит как говно.
Если шаблоны С++ для этого не предназначены, то для чего они предназначены?
Какую вы бы посоветовали замену?
Шаблоны в качестве генериков - это нормальное применение.
Частичная специализация - это уже фишка хитрее, её надо использовать только по жёсткой необходимости.
Рекурсивность - вообще не знаю, нафига.
А всякие там факториалы на шаблонах - это уже изъёбы мозга. Просто случайно вышло, что на шаблонах можно и так, если постараться. Только делать так не надо.
В качестве замены я бы посоветовал другие языки, содержащие эти навороты в более читаемом виде.
во вторых, ты я вижу против compile-time вычислений и compile-time полиморфизма. да?
про compile-time полиморфизм что-нибудь скажете?
Вместо полиморфизма периода компиляции предлагаю тупой код на условных операторах и компилятор, умеющий откидывать ненужные ветки.
пример кода?
http://govnokod.ru/8040
"Один" класс ведёт себя по разному. Понятно, что это не совсем полиморфизм. Но очень часто именно в таком контексте используют динамический полиморфизм, хотя такого статического здесь достаточно выше крыши.
Плюсы этого подхода :
1)Создаётся объект в стеке, значит быстро, а не в куче. Хотя можно и не в стеке.
2)Используется шаблон, значит компиль будет инлайнить.
Минус:
1)Если понадобится резкой перейти от статического полиморфизма к динамическому - придётся переписывать на виртуальные функции или на истинный статический полиморфизм.
void do ()
{
printf("Mega");
if type(this) = Strategy1 then {Strategy1.do} else {Strategy2.do};
}
лишние ветвления на сравнении типа с чем-то должны быть обрублены компилятором, если тип известен. Если нет - то при выполнении.
Мне нравится идея, но нужно как то не так.
А если пользователь передаст стратегию Strategy3, то вызовется лишь Strategy2.
То что вы сделали - это специализация шаблонов, но при этом не осталось самого шаблона.
То есть в вашем коде нельзя добавить новую стратегию, не изменив "полиморфный" класс.
Это чревато такими ошибками. А именно ошибками забыть добавить новую стратегию Strategy3 во все методы класса MegaClass (или хотя бы во все методы класса MegaClass добавили, а в один забыли добавить).
Да и как-то многословно пока... Вам нужно как-то это исправить.
Короче, опять приходим к виртуальным функциям, только с требованием для каждого наследника создавать свой экземпляр функции родителя, в которой вместо указательного вызова сидит простой.
А многословность вообще не проблема.
Как видно, без лишних слов в С++ получаем статический "полиморфизм" без виртуальных функций, не тратя время на вызов по указателю. Вам всегда же не нравились вызовы по указателю... Даже помню по этому вопросу целую тему на 100+ комментов.
В С++ же мы видим лишние слова и лишние угловые скобочки.
Функции уже не будут виртуальными без вызова по указателю. Ваш, КО.
Можно вызывать по ссылке
template<typename _type_, template<typename> class _traits_>
class _string_t {
public:
typedef _type_ value_type;
typedef _traits_<value_type> traits;
typedef _type_ * iterator;
typedef const _type_ * const_iterator;
public:
iterator begin() { return nullptr; }
const_iterator begin() const { return nullptr; }
iterator end() { return nullptr; }
const_iterator end() const { return nullptr; }
/* ... */
};
template<typename _type_>
struct string_traits {
/* .... */
static bool less(const _type_ <, const _type_ &rt) { return lt < rt; }
static bool equal(const _type_ <, const _type_ &rt) { return lt == rt; }
};
template<typename _type_, template<typename> class _traits_>
inline bool operator<(const _string_t<_type_, _traits_> &ls, const _string_t<_type_, _traits_> &rs)
{
typedef _string_t<_type_, _traits_> string_t;
typedef typename string_t::traits traits;
/* if lengths do not equal, ret immediately */
const bool equal_length = std::distance(ls.begin(), ls.end()) == std::distance(rs.begin(), rs.end());
if(!equal_length)
return std::distance(ls.begin(), ls.end()) < std::distance(rs.begin(), rs.end());
string_t::const_iterator ls_it = ls.begin();
string_t::const_iterator rs_it = rs.begin();
/* lengths of strings are equal -> no need to check for 'rs_begin != rs.end()' */
while(ls_it != ls.end() && traits::equal(*ls_it, *rs_begin))
++ls_it, ++rs_it;
return (ls_it != ls.end())? traits::less(*ls_it, *rs_it): false;
}
func "<"(l,r: _type_): boolean
{
if _type_ = _string_t<_type_,_traits_> then
{
ну ты понел
} else {
return Standard."<"(l,r);
};
}
}
В такой код, правда, будет трудно добавить ещё частный случай. Тогда - вирт.функции. Которые раскрываются через перегрузку без указателей.
это не есть главное. главное - что отделена логика от данных
В такой код, правда, будет трудно добавить ещё частный случай. Тогда - вирт.функции. Которые раскрываются через перегрузку без указателей.
паттерн визитор чтоле? впрочем там все-равно один вирт. вызов будет полюбому
Тупой код на условных операторах невозможен из-за несовместимости типов и требования эффективности.
Ну и пусть повиснет. Результат будет получен за то же время. Ну и понятно, эта фича должна быть отрубаемой.
Кроме того, есть такая штука, как кросскомпиляция.
Ну и надо ещё, чтобы при компиляции в окошечке отображалось что-то типа "вычисление значения f(2, 5)..."
тупой кодер == тупой код. параллель не находите?
Независимо от кодера.
1:
что можно сказать о кодере написавшем такое?
2:
http://liveworkspace.org/code/e2367a190546ec68012040bff9289c8f
ну или такое?
Ты все-таки зарегался на говнокоде?
Это был нахрюк на шаблоны сейчас, да?
Лабрадор
--а, и так и так говорят
C от C++
И github от gitlabs
Ну, наверное лет 15 уже не видал как минимум
касательно Пети, он должен писать соответственно кодинг стандартам, принятым в коллективе. об этих самых стандартах нужно ессно узнавать при приёме на работу
Если алгоритм написан верно, и Каму-то непонятен код, то
проблема в том что человек просто плохо образован в плане программирования.
неверно конечно. нарушается принцип КИСС, да и тех, кто будет твой гениальный код поддерживать надо тоже думать, хоть иногда
далее, тебя взяли в контору, где цэпэпэ с шаблонами, но с шаблонами, как я понял, ты до этого работал мало. лол или хуита?
Тернарные операторы очень сложные, ага.
Однозначно сказать мудак ли Петя - невозможно. Выкладывай говнокоды Пети и мы посмотрим уже.
Если "говнокод" Пети - "коммерческая тайна", вопросов нет.
1) Некий абстрактный Петя-программист паттерно-Андреску-осилятор, с приподнятым ЧСВ, пишет некий абстрактный код;
2) Некий приёмщик кода, предъявивший Пете по хреноватой читабельности абстрактного кода оного;
3) Используя некую абстрактную методологию оценки абстрактного кода, нужно получить очень даже конкретный ответ: Петя - мудаг, пишет так, что хер сам потом поймёт не без пол-литры крепкого чая или ниосилятору приёмщику кода нужно бы сходить на ... повышение ЧСВ - квалификации?
Тщательно изучив все исходные данные, получаем закономерный ответ на это всё:
ГДЕ КОД ПЕТИ, БЛЕАТЬ!?
-- Петя...
-- ой, прости, брат!
1. Архитектура приложения должна быть подробно и качественно задокуметирована.
2. code conventions - псалтырь кодера в составе команды.
3. Не документируешь !качественно! свой код - пидарас по-умолчанию.
Если хотя бы эти требования выполняются - Петя может писать как ему угодно и всё будет всем понятно.
ИМХО.
Простота кода во многом зависит от его оформления, отсутствия "велосипедов", человеческого именования.
Иными словами, простой код - это форма, а не содержание.
Я тоже верю в то, что любую задачу можно повернуть так, что её решение будет выглядеть просто. Однако сделать это не всегда получается. :(
Жду конца споров тимлида VS Петя с пачкой попкорна.
P. S.
Передай привет Петюне.
Я даже согласен с его переходом на личности и оскорбления. Мы все здесь это заслужили.
страшно даже подумать, что случится с Петей если он таки освоит "Современное проектирование на цэпэпэ" до конца
А Пете передай путевку в пешее эротическое путешествие.
Это он сказал, зная что вы тут сидите?
Да, он всегда рубит правду матку несмотря ни на что.
Что-то мне подсказывает, что "хуй ты угадал" :))))
АА <Андрей Александреску> - root of all evil.
Похоже теперь почитатель и последователь Андрейки последует за своим учителем и гуру в затворнические кельи писать на D.
Он сказал, что уедет покорять Москву.
Театральное?
Наполеоновские планы
Наполеон-то как раз покорения Москвы и сдулся...
вопрос 2 его начальству: в проекте появляется узкое место в виде "ресурса" Пети. Он может уйти в отпуск, заболеть, решать другие задачи, уволиться, умереть (не дай бог). что будет с проектом?
Как работодатель, я бы либо вообще не связывался бы с Петей, либо дал ему не жизненно важную, но сложную автономную задачу, тем самым зарезав ему возможность какого-либо роста. А с таким подходом к коллегам ему это не грозит в любом случае.
у начальства 2 выхода, либо уволить петю и не мешать ему в росте, либо подсадить пете кучу нубов, которые за год-два станут кучей петь, и будут приносить больше профита и учить нубов.
чего-то мне кажется что второй случай более приемлимый для начальства ибо всеобщая деградация просто невыгодна, особенно в условиях постоянного роста зарплат.
Петя - илитарий с ЧСВ > 9000. Даже при его (Пети) больших знаниях и умениях полезность его (Пети) работы для компании не выше, а то и ниже чем у пары-тройки быдлокодеров.
а я уж было подумал про ЧСВ речь
Вот и весь ответ
Тарас предложил выебать его в сраку.
Но вот если совершенно серьёзно рассудить, то стоит ли пользоватся всеми этими веерами шаблонов хотя бы для редкого узкого круга задач?
Я лично читаю код Александреску в легкую. Использовать могу все, кроме GenScatterHierarchy и GenLinearHierarchy. Применять их умею, но просто не знаю где и когда их правильно применять пока...
Стоит ли использовать знания, полученнные из книги Андрейки, или лучше их забыть раз и на всегда, а то рискуешь, что тебя просто погонят с работы?
Потому программирование и искусство, что у программиста должно быть чувство меры. В каждом конкретном случае нужно отдельно решать, стоит оно того или нет.
на баш! срочно!
ахахахахаххаха
Миду уже скучно так писать, и потому он с помощью шаблонов и паттернов создает абстрактные фабрики стратегий которые способны решить любую задачу в три строки. Мид рад, что он не пишет бойлерплейт.
Потом оказывается что гибкость нужна совсем в другом месте и бенефита от нее нет, зато для того, чтобы поменять алгоритм подсчета очков нужно освоить 4 API, каждый из которых состоит из семи интерфейсов и шести классов, документированных на три страницы каждый.
Сеньйор обычно понимает что гибкость это хорошо, но она не дается бесплатно (написать без багов умный код во много раз сложнее, чем написать глупый код, а писать-то хочется без багов) и если у тебя нет уверенности что твоим чудо-фреймвокром будет пользоваться 150 человек, то может быть проще написать 10 строчек по-ковбойски.
Собссно, отсюда и растут все наши питонии.
Так что Петя не виноват, он просто недостаточно еще говна поел
Это как? Который раз слышу в значении, как что-то плохое. Хотя на википедии написано, что это когда технические вопросы решает разработчик, а не менеджер (блять а как по-другому-то?).
Все любят выябываться на форумах модными словами из GoF, а потом идут на работу и пишут говно
Норкоман сходит с ума.
Норкомана мучит ломка,
Норкомана ждёт нора.
Норкоману говоря:
"Потерпи, сейчас отпустит,
Не нужна тебе нора".
ЗЫ. Ты ритм нарушил, норкоман.
Писать на стенах туалета,
Увы, мой друг, не мудрено.
Среди говна мы все поэты
Среди поэтов мы -- говно.
Поэт:
Известно каждому: не сразу
Поэт рождается меж нас
Потренируйся с унитазом
Чтоб заслужить признание масс
Сижу здесь, как фюрер,
А подо мной - коричневые массы.
https://youtu.be/RPyhyI1bdP4
Поэтами умирают.
Я вообще люто-бешено ненавижу шаблоны, о чем уже не раз говорил.
http://govnokod.ru/15505#comment221515
Просто к написанию современных приложений паттерны имеют примерно такое же отношение, как знание "жи/ши" к написанию Войны и Мира.
Знать их не плохо, но явно недостаточно.