Comments 242
я всегда пишу тип переменной в её названии.
LONG m_longForSomeHren;
BYTE m_byteSomeByte;
…
m — member
l — local
lp — local pointer
mp — member pointer и т.д.
…
А то потом встретишь в коде authorHappiness — и сиди думай что это за переменная.
LONG m_longForSomeHren;
BYTE m_byteSomeByte;
…
m — member
l — local
lp — local pointer
mp — member pointer и т.д.
…
А то потом встретишь в коде authorHappiness — и сиди думай что это за переменная.
-19
Спасибо за замечание. Я долго думал, включать этот пункт или нет.
Когда я писал только на Java, всё было просто: тип и видимость переменной подсказывала IDE. Однако, при составлении программ на C-подобных языках, иногда без IDE вообще, понял, что без
Когда я писал только на Java, всё было просто: тип и видимость переменной подсказывала IDE. Однако, при составлении программ на C-подобных языках, иногда без IDE вообще, понял, что без
m_
очень сложно.-3
UFO just landed and posted this here
попрыгав через go to definition у меня может и мысль пропасть — меня наоборот это отвлекает.
+5
UFO just landed and posted this here
на вкус и цвет, переменную объявлять там где она используется, а не за три-девять земель! )
0
«на вкус и цвет фломастеры разные»
p.s. извините, не удержался.
p.s. извините, не удержался.
0
Зато когда вы решите сменить тип переменной с int на unsigned long int вам не придется судорожно скакать по коду и менять ее имя везде где она встречается.
А если вы, не дай бог, забудете этого когда-нибудь сделать, следующий кто будет работать с вашим кодом получит неверную информацию о переменной, ИМХО Вы перекладываете на свои плечи (плечи программиста) работу IDE, уже давно все приличные IDE показывают тип переменной в ToolTop'е
А если вы, не дай бог, забудете этого когда-нибудь сделать, следующий кто будет работать с вашим кодом получит неверную информацию о переменной, ИМХО Вы перекладываете на свои плечи (плечи программиста) работу IDE, уже давно все приличные IDE показывают тип переменной в ToolTop'е
+25
любой IDE сам всё мне переименует, я же не в блокноте пишу (хотя и там есть Ctrl+H).
+2
любая нормальная IDE покажет тип переменной.
+12
для того чтобы его увидеть надо совершить какие-то действия, ну как минимум курсор навести. А когда голова занята написанием алгоритма сложнее открытия файла(к примеру) — любые лишние телодвижения отвлекают. ну ненравится вам так — пишите по своему, я же не заставляю.
+2
а зачем вам нужно знать тип переменной?
+1
если вы пишете на ПХП — то не надо. А если на С++, то можете вместо переменной записать половину переменной. Недавно в рассылке дебиана видел =)
size_t n;
fscanf(f, "%u", &n);
if ((n > K_MAX_ITEMS) || (n == 0))
человек объявил size_t переменную, которая на АМД64 занимает 64бита, а потом читает в нее fscenf, но как в unsigned int, которая 32, в итоге очень удивлялся почему условие не срабатывает. Так что если вы не на пхп, тип переменной учитывать крайне важно.
size_t n;
fscanf(f, "%u", &n);
if ((n > K_MAX_ITEMS) || (n == 0))
человек объявил size_t переменную, которая на АМД64 занимает 64бита, а потом читает в нее fscenf, но как в unsigned int, которая 32, в итоге очень удивлялся почему условие не срабатывает. Так что если вы не на пхп, тип переменной учитывать крайне важно.
+1
это банальная невнимательность, в пхп тоже можно каутн от строки взять и удивляться почему резуьтат всегда 1… дело не в приставках, а если вы пишете «алгоритм сложнее открытия файла», то его можно писать и без типов переменных, в википедии все алгоритмы написаны на «гипотетическом языке» и нормально функционируют, и 99% из них сложней чем «открытие файла»
0
опечатка=) каутн = count подсчет элементов в массиве, на строках всегда возвращает 1
+1
я ответил на вопрос «зачем нужно знать тип переменной», но с именованием в этой ветке я при этом согласен быть не обязан. Вы же мне эти заслуги приписали.
Но с другой стороны, есть ru.wikipedia.org/wiki/Венгерская_нотация которая данный синтаксис как раз таки и пропагандирует по большей части и вот с ней надо считаться.
Но с другой стороны, есть ru.wikipedia.org/wiki/Венгерская_нотация которая данный синтаксис как раз таки и пропагандирует по большей части и вот с ней надо считаться.
0
да и если в коде надо типы менять, это я считаю ошибкой проектирования.
-13
Вы никогда не совершаете ошибок?
+16
конечно совершаю. наверняка больше вас, так как я не то чтобы совсем програмист. но написав кучу кода используя переменную, потом осознать что она не того типа — это уж крайне редкая ситуация.
0
эм, банально изменились требования и необходимо поддежривать 64-битные числа вместо 32-битных?
0
Это легко может произойти, скажем, если поменялся тип данных, передаваемых объекту извне. А тот тип, с свою очередь, может измениться по независящим от разработчиков причинам. Например, перестало хватать простого инта и пришлось использовать что-то более длинное. Или срочно понадобился знак там, где его не предполагалось использовать.
0
без личностей, я совершаю достаточно ошибок (и уж, если откровенно как раз больше вас, именно потому, что я совсем программист, в смысле профессия это моя), просто я считаю, что совершение ошибок это нормальный рабочий процесс, как говориться не ошибается только тот, кто ничего не делает.
0
строго говоря, он прав, для того и придумали agile техники, чтобы ошибки проектирования стоили меньше крови.
0
такую детализацию лучше не использовать. Достаточно указать char, string, number. Все остальное сложные типы. если размерность с short на long еще возможна для одной и той же переменной, то с string на int — врядли. Скорее всего прийдется изменить и наименование.
0
Напрасно. Если это будет не `authorHappiness`, а `lpcwstrAuthorHappiness`, станет легче?
1. Особенно «удобно» произносить такие переменные, объясняя по телефону/скайпу, например `m_lpctstrzShortName`. Пипец, хоть СМС пиши.
2. Если использование переменной и ее объявление не умещаются на одном экране, у вас имхо слишком длинный метод.
3. Goto declaration есть в любой IDE. Если вы пользуетесь блокнотом или другой «смотрелкой», см. пункт 2.
1. Особенно «удобно» произносить такие переменные, объясняя по телефону/скайпу, например `m_lpctstrzShortName`. Пипец, хоть СМС пиши.
2. Если использование переменной и ее объявление не умещаются на одном экране, у вас имхо слишком длинный метод.
3. Goto declaration есть в любой IDE. Если вы пользуетесь блокнотом или другой «смотрелкой», см. пункт 2.
+21
да, lpcwstrAuthorHappiness для меня легче. правда я напишу lp_strAuthorHappiness.
1. я никому не говорю имена переменных
2. кому как
3. меня это отвлекает
1. я никому не говорю имена переменных
2. кому как
3. меня это отвлекает
-12
1. вы еще не работали в команде.
2. тут скорее когда как
3. а зря… в современных иде много полезных фич, которые позволяют избавиться от ужасного winapi подобного стиля именования аля lpcwstr…
2. тут скорее когда как
3. а зря… в современных иде много полезных фич, которые позволяют избавиться от ужасного winapi подобного стиля именования аля lpcwstr…
+3
1. и не собираюсь
2.…
3. я ими пользуюсь когда мне удобно
2.…
3. я ими пользуюсь когда мне удобно
-17
1. А зря, сейчас такое время, когда один человек не в состоянии написать хоть сколько-нибудь крупное коммерческое приложение, работа в команде это один из ключевых скиллов программиста при устройстве на работу в компании, единоличников не любит никто.
0
В прочем, глянул ваш ранний пост, то что я написал не про Вас, у Вас свой бизнес, но вообще программистам командная работа нужна.
0
я и не отрицаю того что работа в команде касается 90% а то и более програмистов. но только тут будут играть общие правила которые примет команда. можно их сколько убеждать что и кому удобнее, как команда решит так и придётся писать.
0
Этот «ужасный winapi подобный стиль» называется «Венгерская нотация», а использовать её или не использовать это уже личное дело каждого разработчика. И не нужно приплетать сюда работу в команде, как ни крути, одна команда написала целую операционку с использованием такого стиля и говорят, довольно успешную.
А IDE не все используют и не везде.
А IDE не все используют и не везде.
+6
Да про IDE согласен, слышал те самые кодеры которые написали ту самую операционку юзают блокноты. Тут в общем кто как хочет.
А про «Венгерскую нотацию» хочу сказать, что я, как человек начавший кодить уже в дружелюбном .NET, и только потом копнувший глубже в winapi мол «а как оно там все интересно работает?», признаю, что это может и удобно, но поскольку тема про читаемый код, то согласитесь… читается то оно как раз плохо.
А про «Венгерскую нотацию» хочу сказать, что я, как человек начавший кодить уже в дружелюбном .NET, и только потом копнувший глубже в winapi мол «а как оно там все интересно работает?», признаю, что это может и удобно, но поскольку тема про читаемый код, то согласитесь… читается то оно как раз плохо.
0
я как человек начавший кодить много раньше, скажу что мне понятнее так как я описал.
Мне ненадо никуда смотреть кроме кода. Ненадо никуда двигать мышью чтобы узнать тип и переменные у меня имеют осмысленные и длинные названия, префикс это не всё. Когда я смотрю на свой код — я вижу как оно работает, и не заставляю свой мозг искать ненужные и отвлекающие вещи.
Мне ненадо никуда смотреть кроме кода. Ненадо никуда двигать мышью чтобы узнать тип и переменные у меня имеют осмысленные и длинные названия, префикс это не всё. Когда я смотрю на свой код — я вижу как оно работает, и не заставляю свой мозг искать ненужные и отвлекающие вещи.
0
я всегда писал в юниксовой традиции, где, конечно, встречаются cryptic names, но они весьма осмысленны и обычно используют некое негласное общее соглашение, венгерская нотация же считается неприличием.
больше всего, опять же, писал на динамических языках, хотя начинал с С/C++.
так вот, если мы принимаем за данность небольшой размер средней функции (в пределах экрана-полутора), то что мешает поднять глаза на строку с аргументами функции или метода? она же близко, на том же экране.
не получается ли некоторая избыточность? тем более, если речь идет о де факто стандартном в промышленном программировании test driven development, когда каждая функция обвешивается тестами и опробывается в таком окружении, что ложные аргументы передать просто почти невозможно.
да и в случае с++ редко приходится работать чисто с нативными типами, чаще это объекты, полную запись класса которых писать явно не стоит.
больше всего, опять же, писал на динамических языках, хотя начинал с С/C++.
так вот, если мы принимаем за данность небольшой размер средней функции (в пределах экрана-полутора), то что мешает поднять глаза на строку с аргументами функции или метода? она же близко, на том же экране.
не получается ли некоторая избыточность? тем более, если речь идет о де факто стандартном в промышленном программировании test driven development, когда каждая функция обвешивается тестами и опробывается в таком окружении, что ложные аргументы передать просто почти невозможно.
да и в случае с++ редко приходится работать чисто с нативными типами, чаще это объекты, полную запись класса которых писать явно не стоит.
0
я уже незнаю сколько раз это писал — конкретно мне так не удубно. даже по одному экрану бегать глазами. могу такую аналогию привести:
читаем статью, но с непонятными терминами которые в начале. и постоянно туда сюда глазами. разве это удобно?
я даже прямо спрошу — вам такая нотация мешает чем-то кроме того что её считают неприличной?
читаем статью, но с непонятными терминами которые в начале. и постоянно туда сюда глазами. разве это удобно?
я даже прямо спрошу — вам такая нотация мешает чем-то кроме того что её считают неприличной?
0
мне она кажется некрасивой :) в инженерном смысле — несколько избыточной. Мне всегда хочется сделать код предельно лаконичным, даже в смысле названий. Хотя, конечно, может сказываться профессиональный опыт.
Вы, должно быть, под винду писали?
Вы, должно быть, под винду писали?
0
а вот мне наоборот. я например с большей вероятностью назову класс CEConnectionSocketToFile чем СConnStoF ну и т.д.
последние 12 лет виндовс(обычная + мобильная немного). до этого asm z80. сейчас вот Javascript смотрю, вот в нём конечно это избыточность.
честно не знал что эта тема такая холиварная, но всётаки каждый сам выбирает как ему писать и переубедить человека всёравно не получится ;)
И все эти памятки они для тех кто ещё не знает как лучше и пробует.
последние 12 лет виндовс(обычная + мобильная немного). до этого asm z80. сейчас вот Javascript смотрю, вот в нём конечно это избыточность.
честно не знал что эта тема такая холиварная, но всётаки каждый сам выбирает как ему писать и переубедить человека всёравно не получится ;)
И все эти памятки они для тех кто ещё не знает как лучше и пробует.
0
ну… Это ж тема из ряда классических холиворов, плюс еще накладывается местами вечный linux vs windows :)) в принципе пофиг, дело вкуса.
я вот бы вообще не так писал. Раз уж мы знаем контекст места, и тестируем функцию, то при должном количестве комментов в районе объявления достаточно обойтись названием вроде простого «socket» или, если совсем уж короткая функция и сетевой API внятный — «s». В конце концов, там сверху будет открываться этот самый сокет к файлу и, раз уж мы пишем так, как книгу писатель бы писал, получится что-то вроде:
Это, кстати Питон, но на Си я бы так же писал. Зачем повторяться и многократно повторять одну и ту же информацию?
я вот бы вообще не так писал. Раз уж мы знаем контекст места, и тестируем функцию, то при должном количестве комментов в районе объявления достаточно обойтись названием вроде простого «socket» или, если совсем уж короткая функция и сетевой API внятный — «s». В конце концов, там сверху будет открываться этот самый сокет к файлу и, раз уж мы пишем так, как книгу писатель бы писал, получится что-то вроде:
s = connection(file, ...args) s.write(data) .... s.close()
Это, кстати Питон, но на Си я бы так же писал. Зачем повторяться и многократно повторять одну и ту же информацию?
+1
>такая нотация мешает чем-то кроме того что её считают неприличной?
Скажу за себя. Некрасиво и избыточно. Продираться через все эти lpcwstr на каждой букве глаз спотыкается, а мозг силится понять чего же это такое и выстроить последовательность в тип. Отвлекает жутко.
Постоянно смотреть на то какой у переменной тип нужды нет. Если работаешь с каким-то куском кода и забыл тип переменной, то либо выбрана не та профессия :), либо дизайн программы настолько ужасен, что во всё этом можно запутаться.
Скажу за себя. Некрасиво и избыточно. Продираться через все эти lpcwstr на каждой букве глаз спотыкается, а мозг силится понять чего же это такое и выстроить последовательность в тип. Отвлекает жутко.
Постоянно смотреть на то какой у переменной тип нужды нет. Если работаешь с каким-то куском кода и забыл тип переменной, то либо выбрана не та профессия :), либо дизайн программы настолько ужасен, что во всё этом можно запутаться.
0
Венгерская нотация бывает системной и для приложений. Изначально она была использована с ms word для того чтобы отличать переменные, ортогональные по смыслу, никак не по типу. Моду на lpcwstrYetAnother в winapi взяли на вооружение позднее.
Подробнее: Как заставить неправильный код выглядеть неправильно.
Подробнее: Как заставить неправильный код выглядеть неправильно.
+1
Так напишите для вашей IDE плагин, который будет выдавать декларейшен при наведении мыши.
0
Да, лень великое дело…
Взять, да и свалить все на ИДЕ.
«Компьютер должен работать, человек думать» ©
Взять, да и свалить все на ИДЕ.
«Компьютер должен работать, человек думать» ©
+1
Это верный признак того, что функция получилась слишком длинная. Ну или используется много глобальных переменных, что ещё хуже.
0
Венгерская нотация для простых типов конечно хороша, но что делать для пользовательских? Например, как будет выглядеть экземпляр переменной класса CUnboundException, SimpleCreatureFactory и подобных?
+5
у всех моих классов префикс CEClassName, объекты соответственно m_ceObject, l_ceObject…
-4
Ну и какой толк от этого? Все переменные всех классов имеют один и тот же префикс, где логика? Как по переменной m_ceObject можно понять какого она класса?
+4
как минимум понятно что это объект. есть другие варианты?
0
Я добавляю префикс in перед входными переменными, т.е. так:
foo(int inNumber)
foo(int inNumber)
0
>>встретишь в коде authorHappiness — и сиди думай что это за переменная
Я в шоке 0_0 Как можно юзать переменную, если не знаешь ее тип и предназначение…
Я в шоке 0_0 Как можно юзать переменную, если не знаешь ее тип и предназначение…
0
А если в проекте >100 классов? И пишется он не один год, всё помните? я не помню, может у меня под это мозги не заточены. поэтому пишу тип переменной и во время написания кода на вознью мышкой не отвлекаюсь, иначе ещё медленней буду писать.
0
>А если в проекте >100 классов?
Значит вы не знакомы с одной из основ ОО-дизайна — инкапсуляцией :).
У вас в коде разве есть место, где используются все эти 100 классов? Тем более, вы же сами показали, что в случае переменных классов этот замореченый стиль не работает.
>И пишется он не один год, всё помните?
Зачем всё? Классы небольшие, связность классов маленькая, методы обозримые. Если у вас не так, значит вы что-то неправильно спроектировали. Когда вы что-то правите, код класса всё-равно перечитываете, чтобы логику понять.
Значит вы не знакомы с одной из основ ОО-дизайна — инкапсуляцией :).
У вас в коде разве есть место, где используются все эти 100 классов? Тем более, вы же сами показали, что в случае переменных классов этот замореченый стиль не работает.
>И пишется он не один год, всё помните?
Зачем всё? Классы небольшие, связность классов маленькая, методы обозримые. Если у вас не так, значит вы что-то неправильно спроектировали. Когда вы что-то правите, код класса всё-равно перечитываете, чтобы логику понять.
0
что значит «встретишь». Она в воздухе будет висеть? или будет что-то вроде
authorHappiness +=1;
?
Если и по контесту непонятно, и из задачи неясно, как уже неоднократно заметили практически все современные IDE показывают тип в подсказке. Еще дельфи с незапамятных времен умела.
authorHappiness +=1;
?
Если и по контесту непонятно, и из задачи неясно, как уже неоднократно заметили практически все современные IDE показывают тип в подсказке. Еще дельфи с незапамятных времен умела.
0
Это называется «венгерская нотация».
0
Полезная статья: Спольски разоблачает неверное понимание Венгерской нотации:
local.joelonsoftware.com/mediawiki/index.php/Как_заставить_неправильный_код_выглядеть_неправильно
local.joelonsoftware.com/mediawiki/index.php/Как_заставить_неправильный_код_выглядеть_неправильно
+4
Я не так много пишу на cpp, но мне кажется, что хорош вариант использования нижних подчеркиваний для приватных членов класса.
Например:
private:
int __count;
protected:
int _max;
Правда, это в некоторой степени питонизм, но я в основном пишу на питоне, и мне кажется это вполне логичным.
Например:
private:
int __count;
protected:
int _max;
Правда, это в некоторой степени питонизм, но я в основном пишу на питоне, и мне кажется это вполне логичным.
+2
Я не так много пишу на cpp, но мне кажется, что хорош вариант использования нижних подчеркиваний для приватных членов класса и двойных нижних подчёркиваний для параметров функций.
Например:
private _count:int;
protected _max:int;
function countIsMax(__count:int, __max:int):Boolean
{
return (__count == __max);
}
function set count(__count:int):void
{
_count = __count;
trace(«count updated: » + count);
}
if (countIsMax(_count, _max)) count = 0;
Но я в основном пишу на Action script, и мне кажется это вполне логичным.
Бардак )
Например:
private _count:int;
protected _max:int;
function countIsMax(__count:int, __max:int):Boolean
{
return (__count == __max);
}
function set count(__count:int):void
{
_count = __count;
trace(«count updated: » + count);
}
if (countIsMax(_count, _max)) count = 0;
Но я в основном пишу на Action script, и мне кажется это вполне логичным.
Бардак )
0
Я вам дам совет НИКОГДА не называйте переменные с двойным подчёркиванием когда пишете на С/С++. Эти имена зарезервированы для разработчиков компилятора. Вы можете использовать их на свой страх и риск, но в любой нормальной компании во первых дадут железной линейкой по рукам, а во вторых вероятность получить неприятный эффект отлична от нуля.
Во вторых, каждый язык програмирования имеет свой свод неписанных правил и идиом, и не стоит переносить их с одного языка в другой, Python язык динамический, у него нет явного указания private области видимости, потому используется такой вот узаконенный хак.
Во вторых, каждый язык програмирования имеет свой свод неписанных правил и идиом, и не стоит переносить их с одного языка в другой, Python язык динамический, у него нет явного указания private области видимости, потому используется такой вот узаконенный хак.
0
это средневековые методы!
0
В языках со строгой статической типизацией это совершенно излишне. А вот если типизация динамическая (PHP) или нестрогая (плюсы) — то бывает полезно.
0
полезно? тип переменной в названии? в Питоне или Руби? руки рубить, да розгами сечь за такое «полезно».
на динамических языках нормальные системы без тестового покрытия >=90% не пишутся. Функции да методы ма-а-а-аленькие. названия переменных осмысленные и короткие. Код читаться должен как книга, иначе нафиг такой язык высоченного уровня.
а не… lptrlwSocket
на динамических языках нормальные системы без тестового покрытия >=90% не пишутся. Функции да методы ма-а-а-аленькие. названия переменных осмысленные и короткие. Код читаться должен как книга, иначе нафиг такой язык высоченного уровня.
а не… lptrlwSocket
0
Бывает полезно рисовать схемки классов и их взаимодействий. Имхо часто можно обойтись без UML.
Скажем комментарии в коде описывают колесо и все его функции. Часто нужно понять где и зачем это колесо используется. А так же зачем, скажем, нужны 2-3 разновидности колес.
Скажем комментарии в коде описывают колесо и все его функции. Часто нужно понять где и зачем это колесо используется. А так же зачем, скажем, нужны 2-3 разновидности колес.
0
Кроме того, в п.2 упоминается C/C++ хидер, а код — Java ;)
0
Предпочитаю писать комментарии на русском. Если разработку ведёт интернациональный коллектив, то английский, конечно, неизбежен. Но если реальной необходимости в этом нет, по-русски всё-таки проще. Даже если в правильности и ясности своего английского я уверен, не всем коллегам доверил бы чтение англоязычных комментариев :) C++ и Perl поймут лучше :) Да и для описания некоторых тонкостей программы гибкость русского языка очень важна.
+1
Как раз сейчас разбираюсь с сайтом, в котором половина полей и ключей в базе данных, а также часть коментов, используют всю гибкость норвежского языка. Так-как сам я его не знаю, то весьма весело
+2
Повторюсь: если разработку ведёт интернациональный коллектив, то английский, конечно, неизбежен!
+2
Если Вы делаете OpenSource приложение или библиотеку, Вы не можете знать программисту из какой страны потребуется Ваш код.
0
и чем же это противоречит тому, что говорит aralex?
+4
А если я делаю программу с закрытыми исходниками? По-моему, лицензию автор не оговаривал ;)
Да для OpenSource-а комментарии на английском — это хороший тон. Бесспорно! Хотя, согласно GPL — никаких гарантий. В том числе, гарантий читабельности исходников :)
Да для OpenSource-а комментарии на английском — это хороший тон. Бесспорно! Хотя, согласно GPL — никаких гарантий. В том числе, гарантий читабельности исходников :)
0
Иногда не известно, кому Ваш код отдадут после Вас… А ну как найдётся индус, готовый работать за еду?
На самом деле, ИМХО, конечно, если комментарий сложно сформулировать, значит проблема в структуре кода. Например, у нас принято комментировать только «грязные хаки» (без которых, к сожалению, иногда никак), а весь остальной код должен быть написан так, чтобы его можно было как книжку читать :). Я, естественно, имею в виду комментарии внутри кода, а не описание, например, входных параметров функций для *doc
На самом деле, ИМХО, конечно, если комментарий сложно сформулировать, значит проблема в структуре кода. Например, у нас принято комментировать только «грязные хаки» (без которых, к сожалению, иногда никак), а весь остальной код должен быть написан так, чтобы его можно было как книжку читать :). Я, естественно, имею в виду комментарии внутри кода, а не описание, например, входных параметров функций для *doc
+2
а у меня в одной из либ комменты на китайском
+1
На самом деле это очень спорный момент.
Однажды я работал с очень важным блоком когда, который был написан итальянским разработчиком. Комментов было очень много, но они были на итальянском. Ну и названия переменных и методов были на итальянском.
Моей задачей было переписать этот кусок «чтоб работало также». Scegli una lingua nuova :)
Однажды я работал с очень важным блоком когда, который был написан итальянским разработчиком. Комментов было очень много, но они были на итальянском. Ну и названия переменных и методов были на итальянском.
Моей задачей было переписать этот кусок «чтоб работало также». Scegli una lingua nuova :)
+3
Ещё раз повторюсь: если разработку ведёт интернациональный коллектив, то английский, конечно, неизбежен. Но если реальной необходимости в этом нет… :)
+3
Вот наверное испанец и норвег тоже считали, что реальной необходимости нет.
В случаях, когда пишется хоть чуток востребованная кем-то кроме тебя программа, никогда не знаешь, кто будет смотреть/поддерживать код. Поэтому, не только мой опыт подсказывает, что лучше с самого начала приучить себя писать коменты и именовать переменные на английском.
Вообще, разок поковырявшись в комментах на эстонском сам быстро к этому приходишь ;)
В случаях, когда пишется хоть чуток востребованная кем-то кроме тебя программа, никогда не знаешь, кто будет смотреть/поддерживать код. Поэтому, не только мой опыт подсказывает, что лучше с самого начала приучить себя писать коменты и именовать переменные на английском.
Вообще, разок поковырявшись в комментах на эстонском сам быстро к этому приходишь ;)
+2
> Вот наверное испанец и норвег тоже считали, что реальной необходимости нет.
Вполне вероятно. И по-своему они правы: всегда приходится выбирать между общественно-полезным и удобным для себя лично. Если написание комментариев на иностранном языке создаёт серьёзные препятствия работе, то есть повод задуматься, ради чего Ты работаешь: ради удобства забугорных программистов (которые, может быть, когда-нибудь будут изучать твою программу) или ради быстро и качественно сделанной работы. Если участие иностранных разработчиков маловероятно, по-моему, стоит предпочесть родной язык.
А может быть, они не настолько хорошо знали английский, чтобы грамотно прокомментировать программу. Как я слышал, в Европе английский в почёте далеко не везде.
Я не буду утверждать, что российским программистам нужно писать комментарии только на русском. Это должно определяться корпоративными стандартами компании. Если руководители решили, что английский актуален — на английском. А мы пишем на русском. Потому что так проще, понятнее, и привлекать к работе иностранцев мы не планируем.
Вполне вероятно. И по-своему они правы: всегда приходится выбирать между общественно-полезным и удобным для себя лично. Если написание комментариев на иностранном языке создаёт серьёзные препятствия работе, то есть повод задуматься, ради чего Ты работаешь: ради удобства забугорных программистов (которые, может быть, когда-нибудь будут изучать твою программу) или ради быстро и качественно сделанной работы. Если участие иностранных разработчиков маловероятно, по-моему, стоит предпочесть родной язык.
А может быть, они не настолько хорошо знали английский, чтобы грамотно прокомментировать программу. Как я слышал, в Европе английский в почёте далеко не везде.
Я не буду утверждать, что российским программистам нужно писать комментарии только на русском. Это должно определяться корпоративными стандартами компании. Если руководители решили, что английский актуален — на английском. А мы пишем на русском. Потому что так проще, понятнее, и привлекать к работе иностранцев мы не планируем.
+4
Давно как-то читал исследование буржуев про комментарии в программном коде. Они нам очень завидовали — русские графемы отличаются от латинских и комментарии сразу хорошо видно — они не сливаются с текстом программы.
Впрочем, это было в те времена, когда небыло не то что IDE с подсветкой синтаксиса, но даже цветных мониторов :). Сейчас подсветка эту проблему решает.
Впрочем, это было в те времена, когда небыло не то что IDE с подсветкой синтаксиса, но даже цветных мониторов :). Сейчас подсветка эту проблему решает.
0
Кроме комментариев к коду есть еще комментарии к коммитам, с ними та же история. Если зарубежных разработчиков нет и не планируется, то лучше грамотный русский, чем обрывки безграмотного английского. Почему-то нечасто встречаю, чтобы разработчики комментарии к коммитам по-русски писали, имеет смысл делать это значительно чаще, не нужно этого бояться.
+2
> лучше грамотный русский, чем обрывки безграмотного английского
А ещё лучше — грамотный английский ;).
Ну, наверняка же, есть в команде человек, который в состоянии перевести одно предложений нормально. А если нет, так, может быть, стоит задуматься о том, чтобы знание языка подтянуть?
А ещё лучше — грамотный английский ;).
Ну, наверняка же, есть в команде человек, который в состоянии перевести одно предложений нормально. А если нет, так, может быть, стоит задуматься о том, чтобы знание языка подтянуть?
0
эм? И к этому одному человеку всей командой бегать/писать/звонить при каждом коммите?
Комментарии на английском сложнее писать (даже независимо от уровня владения языком, если он не родной), они менее понятны при чтении (что часто усугубляется недостаточными навыками письма).
Из-за того, что их сложнее писать, они пишутся менее подробно и точно.
И при всем этом смысла-то писать их на английском особого нет очень часто. Я к тому, что лучше решение принимать осознанно, а не говорить по дефолту «комментарии к коммитом пишем на английском». У комментариев к коммитам на русском есть много плюсов.
Комментарии на английском сложнее писать (даже независимо от уровня владения языком, если он не родной), они менее понятны при чтении (что часто усугубляется недостаточными навыками письма).
Из-за того, что их сложнее писать, они пишутся менее подробно и точно.
И при всем этом смысла-то писать их на английском особого нет очень часто. Я к тому, что лучше решение принимать осознанно, а не говорить по дефолту «комментарии к коммитом пишем на английском». У комментариев к коммитам на русском есть много плюсов.
-1
Спорить не буду — зависит от специфики. Но, уверен, что, в любом случае, уровень владения языком у хорошего программиста должен быть достаточным для написания комментария к коммиту.
0
Да, согласен, уровень должен быть. Вопрос тут в том, что даже если уровень достаточен, усилия все равно требуются разные, и это приводит к снижению качества комментариев.
0
зато есть дополнительный резон изучить английский! ;)
+2
А что у вас семпл непоследователен — то внутри скобок вызова функции есть пробелы, то нету? Мне кажется, самое главное последовательность и неизменность, а как именно вы оформляете — это уже второстепенно
+1
Последовтелен :)
Я стараюсь не ставить пробелы в конструкторах и ставить при вызове функций.
Однако, теперь, когда Вы заметили, действительно как-то странно выглядит. Спасибо за замечание.
Я стараюсь не ставить пробелы в конструкторах и ставить при вызове функций.
Однако, теперь, когда Вы заметили, действительно как-то странно выглядит. Спасибо за замечание.
0
Продолжаем. За такое оформление (лишние отступы) надо бить ногами:
postCount += 1;
authorHappines +=… bla-bla…
Поясняю: добавится у вас еще одна строчка в низу, более длинная — будете переформатировать весь кусок. Что за фигня, может вам лучше в типографы пойти?
postCount += 1;
authorHappines +=… bla-bla…
Поясняю: добавится у вас еще одна строчка в низу, более длинная — будете переформатировать весь кусок. Что за фигня, может вам лучше в типографы пойти?
+1
А научить IDE делать такие отступы реально?
0
А толку-то? Дело не в том, что надо руками что-то менять — дело в том, что потом в хистори системы управления версии остаются пометки, что в связи с такой-то таской (багом, еще чем-то) строки менялись, хотя реально их только для красоты правили: вы добавили одну, а поменяли еще две тока потому, что вашей левой ноге захотелось форматирования в столбик. Реальное заподло самому себе.
+2
Я всегда так форматирую. И переформатирую, когда добавляется строчка.
Думаю, это вопрос вкуса.
Думаю, это вопрос вкуса.
0
Как отметили выше, при использовании системы контроля версий этот вкус переходит во вредную привычку.
+3
Очень хорошее, кстати, замечание. Задумался…
0
Дурная привычка — ковыряться в носу или смачно сплевывать на улице; коммитить не проходящий тесты код или не делать регулярный бэкап продакшн базы.
А это… вполне представляю ситуации, когда редактирование упрощается засчет таких фокусов, скажем, в очень симметричных кусках кода.
А это… вполне представляю ситуации, когда редактирование упрощается засчет таких фокусов, скажем, в очень симметричных кусках кода.
0
Про отсутствие закомментированного кода… Наверное, стоит различать код, готовый к продаже, и код в процессе разработки. Первый, конечно, рудиментов содержать не должен: дурной тон. Во втором, мне кажется, вкрапления (!) закомментированного кода вполне допустимы, пока они актуальны. Пока действительно не устарели и если действительно не мешают читать актуальный код.
+2
Ну, естественно. Код в разработке, как рабочее место художника, загадочен и непонятен постороннему.
0
В моей практике бывает, что в комментах пишутся куски кода, который заработает после закрытия пары-другой мелких тикетов (под которые не плодят отдельных бранчей), чтобы блюсти правило про «мастер в любой момент компилится, и если нужно релизится», а код мирно дожидается своего часа уже на нужном месте
0
А у Вас ни разу не было случая, когда такой код с «кусочками для себя» уходил в поставку? По-моему, если вы храните «сувенир на память» об этом замечательном алгоритме, который сейчас не нужен, а вот в будущем..., то хранить его стоит у себя на HD или в прошлых версиях в репозитарии. Есть такой антипаттерн даже. Bot anchor называется.
0
Использование стандартов кодирования и оформления. Можно использовать вариант как для конкретного языка или среды разработки, так и внутрифирменный, со своей спецификой. Главное, чтобы все разработчики в команде придерживались единых правил, иначе…
0
eclipse + ctrl + shift + f и любой код читаем
в любой компании есть старый софт, который писался когда компания дико быстро росла и никто не уделял внимание качеству кода ) так что только так.
в любой компании есть старый софт, который писался когда компания дико быстро росла и никто не уделял внимание качеству кода ) так что только так.
0
Откуда вы узнали про CommonUtils?
+6
Сижу, разглядываю листинг на Питоне. Отец, глянув издалека на монитор, спрашивает:
— Маяковского читаешь?
quote/406082
+12
Для меня еще актуальный вопрос по форматированию скобок.
1. Если в условии одна из веток имеет скобки, то и вторая должна иметь скобки:
плохо:
if(var1>2){
var+=3;
var3-=2;
}else
var1*=5;
хорошо:
if(var1>2){
var+=3;
var3-=2;
}else{
var1*=5;
}
2. Скобки я предпочитаю размещать не с новой строки, а на той же что и операторы. Больше информации помещается на экране:
плохо:
if(var1>2)
{
var+=3;
var3-=2;
}
else
{
var1*=5;
}
хорошо:
if(var1>2){
var+=3;
var3-=2;
}else{
var1*=5;
}
1. Если в условии одна из веток имеет скобки, то и вторая должна иметь скобки:
плохо:
if(var1>2){
var+=3;
var3-=2;
}else
var1*=5;
хорошо:
if(var1>2){
var+=3;
var3-=2;
}else{
var1*=5;
}
2. Скобки я предпочитаю размещать не с новой строки, а на той же что и операторы. Больше информации помещается на экране:
плохо:
if(var1>2)
{
var+=3;
var3-=2;
}
else
{
var1*=5;
}
хорошо:
if(var1>2){
var+=3;
var3-=2;
}else{
var1*=5;
}
0
По моему опыту, вопрос размещения скобок — один из самых больных при согласовании стандартов кодирования.
Аргумент «с новой строчки»:
Аргумент «с новой строчки»:
0
По моему опыту, вопрос размещения скобок — один из самых больных при согласовании стандартов кодирования.
Аргумент «с новой строчки»: более очевидно, где тело ветки.
Аргумент «на той же строчке»: больше кода помещается.
Аргумент «с новой строчки»: более очевидно, где тело ветки.
Аргумент «на той же строчке»: больше кода помещается.
0
Аргумент «с новой строчки»: экраны у нас давно не 800x600 и кода помещается заметно больше ;)
Вот ещё вспомнил неудобную вещь — ломание строк, как будто экран пикселей 300 по ширине, типа этого. Сама по себе конструкция полный ужас, а когда в три строки написана вообще дурдом.
// RegEnumValue to enumerate the values in the key
while (ERROR_SUCCESS == RegEnumValue(hkey,
dwIndex++, szValName, (cbValName = chDIMOF(szValName), &cbValName),
NULL, &dwType, bData, (cbData = chDIMOF(bData), &cbData))) {
Вот ещё вспомнил неудобную вещь — ломание строк, как будто экран пикселей 300 по ширине, типа этого. Сама по себе конструкция полный ужас, а когда в три строки написана вообще дурдом.
// RegEnumValue to enumerate the values in the key
while (ERROR_SUCCESS == RegEnumValue(hkey,
dwIndex++, szValName, (cbValName = chDIMOF(szValName), &cbValName),
NULL, &dwType, bData, (cbData = chDIMOF(bData), &cbData))) {
0
Хороший код и читать весьма приятно, и даже кажется порой работает он лучше. :)
+3
А мне не нравится когда слишком много комментариев. Зачем комментировать очевидные вещи? Только место занимать и внимание отвлекать.
Как в вашем примере комментарий к методу sendPost вида 'send the post to the server', название функции в данном случае говорит само за себя.
Или комментарии 'state vatiables' — это к чему? Для людей, не знакомых с языком? И зачем в комментарии писать то, что уже написано в названии переменной?
В общем, я бы в вашем примере количество комментариев сократил минимум вдвое :)
Как в вашем примере комментарий к методу sendPost вида 'send the post to the server', название функции в данном случае говорит само за себя.
Или комментарии 'state vatiables' — это к чему? Для людей, не знакомых с языком? И зачем в комментарии писать то, что уже написано в названии переменной?
В общем, я бы в вашем примере количество комментариев сократил минимум вдвое :)
+4
Очень интересные замечания.
Однако, есть несколько контраргументов.
Комментарии методов:
1. В комментариях методов стоит намекать на реализацию. В примере с sendPost указано, что будет совершен HTTP запрос. Это значит, например, что эту функцию не стоит вызывать из нити, которая отрисовывает интерфейс.
2. Иногда читаешь только комментарии. Допустим, надо понять что умеет делать класс. Если все методы имеют комментарий, то глазу проще искать синенькие блоки и читать только их. Безусловно, самый плохой случай, когда у части методов комментарий есть, а у части — нет.
3. Иногда надо создать Javadoc. Тогда хоть какой-нибудь комментарий лучше, чем никакой.
Комментарии полей: Обычно у класса есть ссылки на «родительские» объекты, объекты, которые класс контролирует и поля состояния. Мне нравится разделять эти группы и явно указывать, что, например, следующие поля будут постоянно меняться. Потом проще вспомнить, что к чему.
Однако, есть несколько контраргументов.
Комментарии методов:
1. В комментариях методов стоит намекать на реализацию. В примере с sendPost указано, что будет совершен HTTP запрос. Это значит, например, что эту функцию не стоит вызывать из нити, которая отрисовывает интерфейс.
2. Иногда читаешь только комментарии. Допустим, надо понять что умеет делать класс. Если все методы имеют комментарий, то глазу проще искать синенькие блоки и читать только их. Безусловно, самый плохой случай, когда у части методов комментарий есть, а у части — нет.
3. Иногда надо создать Javadoc. Тогда хоть какой-нибудь комментарий лучше, чем никакой.
Комментарии полей: Обычно у класса есть ссылки на «родительские» объекты, объекты, которые класс контролирует и поля состояния. Мне нравится разделять эти группы и явно указывать, что, например, следующие поля будут постоянно меняться. Потом проще вспомнить, что к чему.
0
Вы меня, кажется, не поняли. Я не говорил, что комментарии это плохо и давайте ка лучше без них. Я имел в виду, что чрезмерное количество очевидных комментариев — зло.
1. Комментарии с описанием функции post и перечислением ее параметров — вещь нужная и правильная, но совершенно очевидный комментарий к методу sendPost — не нужен.
2. Тут, видимо, на вкус и цвет товарищей нет. Но по мне удобней читать сам код и, если что-то ну совсем уж непонятно — посмотреть в комментарий, если есть. По моему, совершенно очевидно, что postCount += и authorsHappiness += это инкременты этих самых переменных. И мне комментарий, о том, что это таки инкремент — не нужен.
3. Для javadoc достаточно описания самих функций и их переменных. Не обязательно в каждую строчку пихать по комменту :))
Я обычно разделяю группы пустой строкой, если я правильно понял о чем вы.
Но это все, конечно, на вкус и цвет.
1. Комментарии с описанием функции post и перечислением ее параметров — вещь нужная и правильная, но совершенно очевидный комментарий к методу sendPost — не нужен.
2. Тут, видимо, на вкус и цвет товарищей нет. Но по мне удобней читать сам код и, если что-то ну совсем уж непонятно — посмотреть в комментарий, если есть. По моему, совершенно очевидно, что postCount += и authorsHappiness += это инкременты этих самых переменных. И мне комментарий, о том, что это таки инкремент — не нужен.
3. Для javadoc достаточно описания самих функций и их переменных. Не обязательно в каждую строчку пихать по комменту :))
Я обычно разделяю группы пустой строкой, если я правильно понял о чем вы.
Но это все, конечно, на вкус и цвет.
+5
Теперь, похоже понял.
Наверное, всё зависит от того, как привык писать код. Я привык сначала писать комментарии, а потом код. То есть, завожу новый класс, пишу стабы методов, для каждого пришу примерно, что я хочу, чтобы он делал, потом вставляю во внутрь несколько коментов, как он будет это делать, ну а потом и код появляется…
Конечо, для мелких классов или внутренних функций этого нет.
Наверное, всё зависит от того, как привык писать код. Я привык сначала писать комментарии, а потом код. То есть, завожу новый класс, пишу стабы методов, для каждого пришу примерно, что я хочу, чтобы он делал, потом вставляю во внутрь несколько коментов, как он будет это делать, ну а потом и код появляется…
Конечо, для мелких классов или внутренних функций этого нет.
+1
Главное потом удалять очевидные комментарии, чтобы другие (следующие) разработчики не мучились.
+1
Комментарий о том, что делает код ИМХО излишен, так как это должно быть очевидно из самого кода и требует дополнительной работы при его модификации.
Другое дело — комментарий о цели кода. Очень помогает при чтении, а особенно при переделках, когда желательно быстро решить дилемму «прибить или оставить».
Другое дело — комментарий о цели кода. Очень помогает при чтении, а особенно при переделках, когда желательно быстро решить дилемму «прибить или оставить».
0
Согласен. Видел пример, когда ситуация была доведена до абсурда — комментариев было много, но каждый выполнял функцию к/о: описывал назначение функции ровно настолько, насколько было и так понятно из названия.
// Получаем клиента по ID
GetCustomerByID( int customerID )
Самое забавное, что в том же коде не были никак описаны действительно не очень прозрачные места.
// Получаем клиента по ID
GetCustomerByID( int customerID )
Самое забавное, что в том же коде не были никак описаны действительно не очень прозрачные места.
+2
А мне кажется что комментов слишком много, мешают читать.
Если методы/переменные нормально названы, не вижу в этом необходимости (если только комменты не для IDE).
Например, postCount => postCountPerSession, и можно убрать коммент. Бонус: внутри методов будет понятнее.
Комменты вроде // increment… над += 1 тоже можно убрать.
Если методы/переменные нормально названы, не вижу в этом необходимости (если только комменты не для IDE).
Например, postCount => postCountPerSession, и можно убрать коммент. Бонус: внутри методов будет понятнее.
Комменты вроде // increment… над += 1 тоже можно убрать.
+3
+1, пример кода на скриншоте настолько захламлён комментариями, что на него даже смотреть тошно, не то что читать.
Когда уже до всех дойдёт очевидная мысль: комментарии должны пояснять как код работает и почему именно так, а тупые комментарии с пересказом о том, что код делает никому нафиг не нужны. Во всяком случае тем, кто с используемым языком программирования знаком, понятнее будет запись на самом языке программирования, а не на английском, русском, испанском, etc. А если из самого кода программисту не понятно что он делает, то необходимо этот код выбросить вместе с комментариями.
Когда уже до всех дойдёт очевидная мысль: комментарии должны пояснять как код работает и почему именно так, а тупые комментарии с пересказом о том, что код делает никому нафиг не нужны. Во всяком случае тем, кто с используемым языком программирования знаком, понятнее будет запись на самом языке программирования, а не на английском, русском, испанском, etc. А если из самого кода программисту не понятно что он делает, то необходимо этот код выбросить вместе с комментариями.
0
добавлю — имена фукцний, классов и переменных должны быть на английсоком. А если вы не знаете нужного слова — потратьте минуту своего времени поглядите в словаре как же переводится на английский нужное слово.
И конечно же в идеале эти названия должны быть написаны грамматически правильно. Потому что тот кто их бегло читает — прочетет правильно а работать оно не будет.
(особенно тут вспоминается волшебное слово анализ ( analyse, analyze, analise, analysis, analisys… ну вы поняли )
И конечно же в идеале эти названия должны быть написаны грамматически правильно. Потому что тот кто их бегло читает — прочетет правильно а работать оно не будет.
(особенно тут вспоминается волшебное слово анализ ( analyse, analyze, analise, analysis, analisys… ну вы поняли )
+8
UFO just landed and posted this here
Python — код, который приятно читать :)
0
Вот маленький кусочек кода из одного проекта:
Многим может показаться излишеством конструкция else, но мне так удобнее и понятнее.
Многим может показаться излишеством конструкция else, но мне так удобнее и понятнее.
0
Да, тоже приходилось часто слышать ехидные комментарии «гуру программирования» по поводу того, что тут будет все работать и без else и нечего писать лишний на код. Хотя при чтении кода сразу видна его логика и не приходится искать return выше.
Добавлю только, что лично мне приятнее else ставить на новой строчке и присваивания отделять пробелами от переменных.
Добавлю только, что лично мне приятнее else ставить на новой строчке и присваивания отделять пробелами от переменных.
0
многим может показаться излишним SetByte при наличии перегрузки оператора «квадратные скобки»
;-)
P.S.: а почему название метода с большой буквы, тоже привычка?
;-)
P.S.: а почему название метода с большой буквы, тоже привычка?
0
>>а почему название метода с большой буквы, тоже привычка?
Мне так удобнее хотя, наверное, следует избавляться от этой привычки.
Кстати, дефайны я пишу заглавными буквами.
А перед константами ставлю префикс k.
Мне так удобнее хотя, наверное, следует избавляться от этой привычки.
Кстати, дефайны я пишу заглавными буквами.
А перед константами ставлю префикс k.
0
А почему 'k', а не 'с'? От чего образовался такой префикс?
0
C я юзаю для наименования класса, а k от немецкого Konstante.
-1
вот кстати вспомнил про скобки. всегда их пишу даже если в условии одна строка и именно как у вас, чтобы каждая скобка на отдельной строке. тогда мозгам проще зацепиться за блок который внутри них находится, чтобы начать анализовать код. А не искать где там оно кончается.
+2
Хороший пример для разбора.
1. Название функции isRange переводится как «является ли диапазоном?», что при аргументе типа unsigned int выглядит очень загадочно.
2. Обычное соглашение — возвращение признака ошибки. Если я правильно понял код, то тут при нестандартной ситуации возвращается 0, а не 1.
3. Микро-рефакторинг, соглашение, описанное у Фаулера, которое позволяет делать код проще и понятнее: сначала проверяем нестандартные ситуации, потом выполняем действия. Так мы избегаем дополнительных уровней вложенности и, что самое важное, основной код (суть функции) видно сразу: он находится в теле функции, а не в одной из веток if'ов. Это же не равноправный код — тот, которые проверяет какие-то аргументы на допустимость и тот, который выполняет собственно то, для чего функция задумана.
4. Про префиксы классов — все эти С и тд ссылка тут уже пробегала на Спольски, почитайте.
С учетом всего этого:
1. Название функции isRange переводится как «является ли диапазоном?», что при аргументе типа unsigned int выглядит очень загадочно.
2. Обычное соглашение — возвращение признака ошибки. Если я правильно понял код, то тут при нестандартной ситуации возвращается 0, а не 1.
3. Микро-рефакторинг, соглашение, описанное у Фаулера, которое позволяет делать код проще и понятнее: сначала проверяем нестандартные ситуации, потом выполняем действия. Так мы избегаем дополнительных уровней вложенности и, что самое важное, основной код (суть функции) видно сразу: он находится в теле функции, а не в одной из веток if'ов. Это же не равноправный код — тот, которые проверяет какие-то аргументы на допустимость и тот, который выполняет собственно то, для чего функция задумана.
4. Про префиксы классов — все эти С и тд ссылка тут уже пробегала на Спольски, почитайте.
С учетом всего этого:
bool Memory::SetByte(unsigned int offset, unsigned char value) { if (!inRange(offest)) return 1 Memory[inOffest] = value return 0 }
+1
А почему не на ексепшене? И почему можно дать неправильный адрес и ничего страшного не случится? Ошибка же останется незамеченной.
0
Если несколько параметров и ошибка в любом вызовет один и тот же ексепшн, то не очень понятно, как это описать.
0
А вам не кажется, что проще передавать сразу правильные параметры, чем проверять результаты вызова каждой функции? Руки же отвалятся if'ы писать?
0
В том-то и дело, приходится идти на жертвы. Мы с Вами, безусловно, грамотные разработчики, которые всегда передают правильные параметры.
Но, увы, вокруг существует очень много других людей, которые могут быть не так аккуратны. А позволить своему коду оставить систему в неопределенном состоянии я не могу.
Но, увы, вокруг существует очень много других людей, которые могут быть не так аккуратны. А позволить своему коду оставить систему в неопределенном состоянии я не могу.
0
Насчет 200-300 строк в файле — далеко не всегда это возможно. Особенно, если пишется что-то чуть более сложное, чем Hello World. Я вот сейчас работаю с парой классов, у которых только декларация вдвое длиннее, а уж сам код за 3000 у каждого перевалил. Если это порезать на куски по 300 строк, из каждого файла получится десяток, и понять, как оно работает будет трудновато.
0
хмм… У меня вот твёрдая уверенность, что любой God Object (исключая, возможно, фасады) можно с помощью декомпозиции свести к нескольким «нормальным». Возможно, просто проблема в нежелании / нехватки времени на рефакторинг?
+2
Не всегда это можно сделать. Вернее, сделать-то можно, только код от этого понятнее не станет. В моем примере для достижения идеала в 200-300 строк класс пришлось бы разобрать буквально на отдельные методы, а некоторые из них еще и разрезать на куски. Просто сложная обработка сложных данных.
0
Методы по 300 строк — это абсолютное зло. Какой бы сложности данные не были, выделить из 300 строк несколько отдельных методов можно всегда. Вопрос — насколько это хочется делать.
+1
Вопрос, имеет ли это смысл. Представьте например, что эти 300 строк — заполнение одного объекта данными. Утрируя, это просто 300 вызовов obj.SetFoo(); obj.SetBar()… Зачем разбивать логически единый кусок на части?
Кроме того, иногда разбиение на мелкие функции сильно влияет на производительность. Например, мне надо пройтись по гигу данных (char-ов) и сконвертить их определенным образом, причем сама обработка, вобщем-то, копеечная. Можно выделить тело цикла в отдельную функцию (или даже несколько), но это будет означать тот самый гиг call-ов, так что скорость работы просядет ниже плинтуса. Оно правда нужно?
Кроме того, иногда разбиение на мелкие функции сильно влияет на производительность. Например, мне надо пройтись по гигу данных (char-ов) и сконвертить их определенным образом, причем сама обработка, вобщем-то, копеечная. Можно выделить тело цикла в отдельную функцию (или даже несколько), но это будет означать тот самый гиг call-ов, так что скорость работы просядет ниже плинтуса. Оно правда нужно?
+1
Ну так перепишите в каком-то более декларативном стиле, это ж полный трэш — 300 строк однообразных вызовов obj.SetFoo. Это не «логически единый кусок», который нельзя разбивать на части, это именно что плохой код.
А насчет производительности — думать о ней стоит тогда, когда она становится проблемой, а не заранее, оправдывая ей плохой и неструктурированный код.
А насчет производительности — думать о ней стоит тогда, когда она становится проблемой, а не заранее, оправдывая ей плохой и неструктурированный код.
+1
Я же сказал, что это утрированно. Хорошо, другой пример: при обработке данных мне постоянно нужен десяток-другой переменных. Разбить обработку на куски — значит сделать несколько функций, которым придется передавать этот десяток переменных, причем большую часть не по значению, а по неконстантной ссылке. Вы, действительно, думаете, что это будет более читаемо? Я вам по секрету скажу, у меня есть такие функции. Там, где это действительно необходимо. Но плодить их только ради разбиения кода на мелкие куски — это безумие.
Насчет производительности: вот именно в этом месте она очень критична, поскольку объемы данных бывают очень большие (я не зря привел в примере гиг чаров, хотя в реальности все гораздо сложнее). А код вполне нормально структурирован. Просто сделано это исходя из логики работы класса, а не абстрактных ограничений на размер функции.
Насчет производительности: вот именно в этом месте она очень критична, поскольку объемы данных бывают очень большие (я не зря привел в примере гиг чаров, хотя в реальности все гораздо сложнее). А код вполне нормально структурирован. Просто сделано это исходя из логики работы класса, а не абстрактных ограничений на размер функции.
0
Думаю, мы на разных языках говорим. Альтарнатива методам на 300 строк — это никак не функции с десятками параметров. Почитайте «Рефакторинг» Фаулера, очень хорошая книга.
+1
А какие еще альтернативы вы видите? Ну, хорошо, вспомогательный класс или структура, в которые эти переменные завернуты. На каждый существующий метод пришлось бы добавить 2-3 таких структуры. Количество кода выросло бы в 2-3 раза. Логика работы потерялась бы полностью за этими мелочами. Количество файлов выросло бы на порядок. Чтобы понять, что функция делает, пришлось бы облазить кучу кода в разных местах и понять, как он взаимодействует. И все это только для того, чтобы сократить размер функции?
Книжки книжками, но загонять себя в жесткие рамки из религиозных соображений тоже не стоит. Ситуации бывают очень разные.
Книжки книжками, но загонять себя в жесткие рамки из религиозных соображений тоже не стоит. Ситуации бывают очень разные.
0
Вот именно что загонять себя в рамки не стоит, и для этого полезно хорошенько разобраться, как все такие вопросы обычно-то решаются и чем это обосновывается. Те ужасы, которые Вы описываете — это последствия неправильно проведенной декомпозиции, и чтоб такого не было, как раз и полезно почитать Фаулера. ООП в чистом виде, без знания механизмов рефакторинга и шаблонов проектирования (а также без умения их не применять там, где не нужно), легко запутывает код, это точно.
Код, состоящий из небольших независимых (или слабосвязанных) кусков, обычно наоборот, проще для понимания. Кроме того, его гораздо проще тестировать и отлаживать, а еще его проще оптимизировать, т.к. поиск узких мест упрощается.
Вычислительные задачи — особая область, но это не значит, что к ним не применимы современные подходы.
Код, состоящий из небольших независимых (или слабосвязанных) кусков, обычно наоборот, проще для понимания. Кроме того, его гораздо проще тестировать и отлаживать, а еще его проще оптимизировать, т.к. поиск узких мест упрощается.
Вычислительные задачи — особая область, но это не значит, что к ним не применимы современные подходы.
+1
Конечно, каждая ситуация отличается, но скорее всего что-то пошло не так.
Я не знаю Вашего кода, как он будет использоваться и так далее, но поддерживать 3000 строчек очень сложно. Обычно есть способы разбивки на функциональные компоненты.
Пожалуй, лишь списки констант иногда выходят очень длинными.
Я не знаю Вашего кода, как он будет использоваться и так далее, но поддерживать 3000 строчек очень сложно. Обычно есть способы разбивки на функциональные компоненты.
Пожалуй, лишь списки констант иногда выходят очень длинными.
0
Да, задачи у нас несколько специфические (биоинформатика). Код часто получается сложным просто потому, что и логика обработки данных далеко не сахар.
Поддерживать 3000 строк кода одного класса в одном файле в моем случае гораздо проще, чем разбить это хозяйство на 10 классов/файлов. Я знаю о чем говорю, потому что в какой-то момент мне пришлось один класс разбить на два (по соображениям минимизации зависимостей от других библиотек). Вот теперь это настоящий кошмар — код раскидан по разным местам и уследить за ним очень трудно.
Поддерживать 3000 строк кода одного класса в одном файле в моем случае гораздо проще, чем разбить это хозяйство на 10 классов/файлов. Я знаю о чем говорю, потому что в какой-то момент мне пришлось один класс разбить на два (по соображениям минимизации зависимостей от других библиотек). Вот теперь это настоящий кошмар — код раскидан по разным местам и уследить за ним очень трудно.
0
С. Макконнелл «Совершенный код» тоже затрагивает поднимаемые здесь вопросы, ну и еще некоторые ;)
Пост хорош, но некоторые мысли, мне кажется, не доведены до логического завершения.
В пункте 6, к переменным с которыми предполагается сложная работа, возможно было бы полезнее сделать сеттеры и геттеры, а не описывать как правильно с ними работать.
Пост хорош, но некоторые мысли, мне кажется, не доведены до логического завершения.
В пункте 6, к переменным с которыми предполагается сложная работа, возможно было бы полезнее сделать сеттеры и геттеры, а не описывать как правильно с ними работать.
+1
«Совершенный код» — отличная книга. Я хотел затронуть лишь те правила, которые использую сам.
Про пункт 6 — замечание очень верное. Комментарии полей, пожалуй, больше для тех, кто будет менять класс «после нас».
Про пункт 6 — замечание очень верное. Комментарии полей, пожалуй, больше для тех, кто будет менять класс «после нас».
0
С. Макконнелл «Совершенный код» тоже затрагивает поднимаемые здесь вопросы, ну и еще некоторые ;)
Пост хорош, но некоторые мысли, мне кажется, не доведены до логического завершения.
В пункте 6, к переменным с которыми предполагается сложная работа, возможно было бы полезнее сделать сеттеры и геттеры, а не описывать как правильно с ними работать.
Пост хорош, но некоторые мысли, мне кажется, не доведены до логического завершения.
В пункте 6, к переменным с которыми предполагается сложная работа, возможно было бы полезнее сделать сеттеры и геттеры, а не описывать как правильно с ними работать.
0
Внесу свои 5 копеек. Чтобы читать было приятно не только свой код, но и весь код проекта, надо перед его началом собраться командой и написать свой CodingStyle, взяв за основу какой-либо популярный для вашего языка/платформы. При этом учесть пожелания всех, новичкам объяснить почему так писать хорошо, а так — не очень, в общем провести подготовительную работу.
Потом может пару-тройку недель инициатору придется немного контролировать процесс, указывать на ошибки, может быть вносить коррективы в документ. Но вся эта морока с лихвой окупится в дальнейшем, когда не придется разбираться в тонкостях чужой нотации и весь код буден в одном, понятном каждому стиле.
Потом может пару-тройку недель инициатору придется немного контролировать процесс, указывать на ошибки, может быть вносить коррективы в документ. Но вся эта морока с лихвой окупится в дальнейшем, когда не придется разбираться в тонкостях чужой нотации и весь код буден в одном, понятном каждому стиле.
+2
>>… и написать свой CodingStyle
После того, как возьмутся за это, до самой работы дело дойдет нескоро :) Т.к. очень уж холиварная тема для команды
После того, как возьмутся за это, до самой работы дело дойдет нескоро :) Т.к. очень уж холиварная тема для команды
-1
UFO just landed and posted this here
А лучше по началу собираться регулярно, скажем, раз в неделю. У нашей команды одно время была практика code review, когда раз в неделю кто-то один читал код всех остальных и указывал на такие вот недостатки (плюс, естественно, архитектурные проблемы). В результате стиль кодирования был всё же выработан. и это при том, что ребята пишут на PHP.
0
С. Макконнелл «Совершенный код» тоже затрагивает поднимаемые здесь вопросы, ну и еще некоторые ;)
Пост хорош, но некоторые мысли, мне кажется, не доведены до логического завершения.
В пункте 6, к переменным с которыми предполагается сложная работа, возможно было бы полезнее сделать сеттеры и геттеры, а не описывать как правильно с ними работать.
Пост хорош, но некоторые мысли, мне кажется, не доведены до логического завершения.
В пункте 6, к переменным с которыми предполагается сложная работа, возможно было бы полезнее сделать сеттеры и геттеры, а не описывать как правильно с ними работать.
0
Дело вкуса, конечно, но я предпочитаю укладываться в как можно меньше кода и при этом иметь как минимум 30% комментариев. Отсюда следует несколько простых правил:
1) Если возможно — не пользоваться временными переменными
2) Не ставить {} на новую строку
3) Если в методе больше 20 строк кода — то она плохо написана
4) Если в классе больше 300 строк кода — то он плохо написан
5) Если для того, чтобы получить какое-то значение из другого класса нужно соблюдать больше чем 1 уровень иерархической вложенности — то всё пропало
6) По-максимуму использовать энкапсуляцию и полиморфизм
1) Если возможно — не пользоваться временными переменными
2) Не ставить {} на новую строку
3) Если в методе больше 20 строк кода — то она плохо написана
4) Если в классе больше 300 строк кода — то он плохо написан
5) Если для того, чтобы получить какое-то значение из другого класса нужно соблюдать больше чем 1 уровень иерархической вложенности — то всё пропало
6) По-максимуму использовать энкапсуляцию и полиморфизм
0
Согласен почти со всем.
А не могли бы Вы аргументировать пункт 2 (не ставить {} на новую строку)?
А не могли бы Вы аргументировать пункт 2 (не ставить {} на новую строку)?
0
исключительно потому что код тогда занимает значительно меньше места
Copy Source | Copy HTML
- //wtf
- if(foo == bar)
- {
- if(tempVar = foobar(true))
- {
- print(doodle(tempVar));
- }
- else
- {
- print('No Joy');
- }
- }
- else
- {
- if(tempVar = foobar(false))
- {
- print(doodle(tempVar));
- }
- else
- {
- print('Really No Joy');
- }
-
- }
-
-
- //not so wtf
- if(foo == bar) {
- if(tempVar == foobar(true)) {
- print(doodle(tempVar));
- } else {
- print('No Joy');
- }
- }else{
- if(tempVar == foobar(false)) {
- print(doodle(tempVar));
- } else {
- print('Really No Joy');
- }
- }
-
-
- //totally not wtf
- if(foo == bar && (tempVar == fooBar(true) || tempVar == fooBar(false))) {
- print(doodle(tempVar));
- } else {
- print('No Joy');
- }
+2
Если в методе больше 20 строк кода — то она плохо написана
Ну это вы перегибаете, честное слово=)
+1
От языка зависит.
0
я всегда годов убедиться в обратном, но пока не встречал ни одного примера!
0
Сомневаюсь, что вы уложитесь в 20 строк кода, когда будете писать какой-нибудь накрученный графический фильтр на C++.
Нет, вы, конечно, можете разбить весь процесс на множество маленьких функций, данные вывести в отдельные сущности, но это только ухудшит читаемость, снизит производительность и породит множество сильно связанных объектов, что противоречит шаблону «Low Coupling».
Нет, вы, конечно, можете разбить весь процесс на множество маленьких функций, данные вывести в отдельные сущности, но это только ухудшит читаемость, снизит производительность и породит множество сильно связанных объектов, что противоречит шаблону «Low Coupling».
0
Можно взять крайний случай — ассемблер (да, бывает, пишут и на нем). Так вот там только для того, чтобы собрать в стек параметры для вызова какой-то функции, может понадобиться больше 20 строк.
Даже если не вдаваться в крайности, 20 строк — зачастую это бесполезное дробление, часто как раз ухудшающее удобочитаемость. Еще и во многих случаях влияющее на производительность.
В общем, во всякой декомпозиции должна быть мера.
Даже если не вдаваться в крайности, 20 строк — зачастую это бесполезное дробление, часто как раз ухудшающее удобочитаемость. Еще и во многих случаях влияющее на производительность.
В общем, во всякой декомпозиции должна быть мера.
0
Основное уже перечислили, но хочу добавить:
1) не использую тернарный условный оператор (?:) — т.к. плохо читаем
2) во всех конструкциях if (даже, если в теле только один оператор) использую фигурные коды скобки
3) стараюсь выносить числовые значения в отдельные константы, а не бросать их в коде; т.е.
4) Ещё, как можно увидеть из кода, люблю после символа "//" ставить пробел=)
5) А вообще советую почитать классику (Кернигана- Пайка и Макконнелла)
1) не использую тернарный условный оператор (?:) — т.к. плохо читаем
2) во всех конструкциях if (даже, если в теле только один оператор) использую фигурные коды скобки
3) стараюсь выносить числовые значения в отдельные константы, а не бросать их в коде; т.е.
Copy Source | Copy HTML
- // ПЛОХО
- if (someVariable > 10)
- {
- // что-то там
- }
Copy Source | Copy HTML
- // ХОРОШО
- int tresholdValue = 10; // пороговое значение
- if (someVariable > tresholdValue)
- {
- // что-то там
- }
-
4) Ещё, как можно увидеть из кода, люблю после символа "//" ставить пробел=)
5) А вообще советую почитать классику (Кернигана- Пайка и Макконнелла)
+2
пункт 3 обычно приводит ещё и к более быстрому коду, так как значение переменной зачастую содержиться в регистре, а не в памяти как в неправильном варианте. по меньшей мере наблюдал это на VC++ 6.0
0
Это далеко не всегда. Регистров-то кот наплакал, а переменных может быть вагон и еще маленькая тележка. Даже директива register в Си, дает указание компилятору по-возможности использовать регистры для хранения переменной.
0
я же и написал — обычно.
особенно заметно на таких кусках (так быстрее):
int l_intSize = 374747;
for ( int l_intIndex = 0; l_intIndex < l_intSize; l_intIndex++ )
…
или так:
int l_intSize = l_ceSomeContainer.GetSize();
for ( int l_intIndex = 0; l_intIndex < l_intSize; l_intIndex++ )
…
а так вполне нормально регистров. не так давно оптимизировал распаковку одного RAW формата, так хаффман + дельта и ещё кое что, в достаточно компактном размере получились.
особенно заметно на таких кусках (так быстрее):
int l_intSize = 374747;
for ( int l_intIndex = 0; l_intIndex < l_intSize; l_intIndex++ )
…
или так:
int l_intSize = l_ceSomeContainer.GetSize();
for ( int l_intIndex = 0; l_intIndex < l_intSize; l_intIndex++ )
…
а так вполне нормально регистров. не так давно оптимизировал распаковку одного RAW формата, так хаффман + дельта и ещё кое что, в достаточно компактном размере получились.
0
Если компилятор умеет оптимизировать код, то, как правило, он вынесет значение в отдельную переменную. Будет она в памяти или в регистре — этот вопрос надо изучить подробнее.
Просто при таком подходе и код более осмысленным получается, и значительно легче изменить параметры цикла и оператора ветвления, что снижает количество ошибок.
Просто при таком подходе и код более осмысленным получается, и значительно легче изменить параметры цикла и оператора ветвления, что снижает количество ошибок.
0
1) не использую тернарный условный оператор (?:) — т.к. плохо читаем
Вы считаете, что это плохо читается?
int max = value1 > value2 ? value1 : value2;
Совет — попробуйте писать в 3 строки — очень читабельно с моей точки зрения.
0
Лично по мне, в конструкции «if — else » сразу видно куда идёт ветвление, и какой переменной присваивается значение; в то время, как у "?:" надо напрягать мозги при определении, что означает символ "?" и ":".
Я думаю, вы согласитесь, что текстовые обозначения намного более понятны человеку, чем различные закорючки;)
Я думаю, вы согласитесь, что текстовые обозначения намного более понятны человеку, чем различные закорючки;)
0
Спасибо — очень интересная и правильная статья.
Я очень сожалею, что мой опыт показался Вам не интересным.
Я очень сожалею, что мой опыт показался Вам не интересным.
0
Ни в коем случае я Вас не имел в виду. Извините, если не так меня поняли. Я просто писал про то, что часть комментаторов здесь беззастенчиво антипаттерны используют, а часть — даже не догадываются об их существовании.
0
Ой, извините, я действительно не так Вас понял.
Я с Вами абсолютно согласен про некоторых комметаторов. Мне кажется вполне естественным, что большинство беззастенчиво антипаттерны использует. Иногда это верно не только в программировании, но и в более общем случае :)
Однако, Хабр ещё торт, поскольку в комментариях до сих пор появляется здоровая критика, толковые идеи и полезные ссылки.
Я с Вами абсолютно согласен про некоторых комметаторов. Мне кажется вполне естественным, что большинство беззастенчиво антипаттерны использует. Иногда это верно не только в программировании, но и в более общем случае :)
Однако, Хабр ещё торт, поскольку в комментариях до сих пор появляется здоровая критика, толковые идеи и полезные ссылки.
0
В посте комментарии в стиле:
Мне они кажутся совершенно бесполезными.
Я стараюсь давать имена переменным и методам такие, чтобы код можно было читать вслух. Комментирую константы и некоторые неявные решения, если таковые имеются. Все остальные комментарии — пометки TODO.
private int i = 1; // объявляем перменную i и инициализируем ее единичкой
i++; // инкрементируем переменную i
Мне они кажутся совершенно бесполезными.
Я стараюсь давать имена переменным и методам такие, чтобы код можно было читать вслух. Комментирую константы и некоторые неявные решения, если таковые имеются. Все остальные комментарии — пометки TODO.
+2
Префиксы для полей класса _ и статических переменных __ — чтобы легчебыло читать даже без расцветки.
КОНСТАНТЫ — заглавными буквами
А вообще — читаемость кода — единственный универсальный критерий, оптимальность нужна не всюду.
Даже не только читабельность, а более общее качество — сопровождаемость. Это и читаемость и легкость модификации и легкость дебагирования
КОНСТАНТЫ — заглавными буквами
А вообще — читаемость кода — единственный универсальный критерий, оптимальность нужна не всюду.
Даже не только читабельность, а более общее качество — сопровождаемость. Это и читаемость и легкость модификации и легкость дебагирования
+2
Бейте меня палкой, а я почти никогда не комментирую свой код :). Я стараюсь давать комментарии только в том случае, если код сильно расходится с соглашениями о кодировании на соответствующем языке.
Я не комментирую и не объясняю простые и стандартные вещи, но зато стараюсь максимально подробно комментировать сложные места и места, где, по-моему мнению, можно было сделать по-другому, но я не знаю, как :).
Я не комментирую и не объясняю простые и стандартные вещи, но зато стараюсь максимально подробно комментировать сложные места и места, где, по-моему мнению, можно было сделать по-другому, но я не знаю, как :).
+1
Если есть перечисления чего-то, или сложные условия, тогда предпочитаю писать каждое с новой строки и с учетом того что запятую или логический оператор ставлю в начало строки. Удобно отключать комментарием // (c++, java) или — (SQL) какой-то блок, при этом в целом конструкция остается синтаксически верной (за исключением комментирования первой строки):
enum{
test1
, test2
//, test3
, test4
}
if (
a==b
// && c>d
&& d!=5
){
return c-d;
}
enum{
test1
, test2
//, test3
, test4
}
if (
a==b
// && c>d
&& d!=5
){
return c-d;
}
+1
Размер 200-300 строк имеет то недостаток что на среднем проекте у вас винчестер будет гореть красной лампочкой постоянно, загрузка проекта з 1000-2000 таких файлов даже на мощной машине удовольствие не из приятных.
Я пишу на C# и если классы связаны по смыслу пытаюсь разместить их в одном файле. Оптимум для меня 500-1000 строк, если получается больше, например при взаимодействии с native-кодом, клас делаю partial Хорошая IDE нормально можеть свернуть регионы, при нужде можно разделители поставить, монитор 24 дюйма с 16:10 в вертикальной ориентации классная штука.
А вообще жёсткая привязка в количеству строк ни к чему хорошему не приводит. Есть только один критерий связность сущностей в класе и возможность сопровождать его сложность, при превышении пороговой сложности мы пытаемся её уменьшить путём введения дополнительной сущности(нового класа). Разбиение каждый делает сам в силу своего опыта. Но этот способ не решает сложность связанную с слишком большим количеством сущностей(бритва Оккама). Множество библиотек Java, а в последнее время и .NET тяготеют к этому, получается то что я называю overcomplicated когда библиотеки стают настолько всеобъемлющие что один человек просто не может их постигнуть за приемлемые строки. Если это обосновано требованиями то пусть будет даже 1500 строчек, чем 15 с жёсткими зависимостями особенно цикличными друг к другу.
Я пишу на C# и если классы связаны по смыслу пытаюсь разместить их в одном файле. Оптимум для меня 500-1000 строк, если получается больше, например при взаимодействии с native-кодом, клас делаю partial Хорошая IDE нормально можеть свернуть регионы, при нужде можно разделители поставить, монитор 24 дюйма с 16:10 в вертикальной ориентации классная штука.
А вообще жёсткая привязка в количеству строк ни к чему хорошему не приводит. Есть только один критерий связность сущностей в класе и возможность сопровождать его сложность, при превышении пороговой сложности мы пытаемся её уменьшить путём введения дополнительной сущности(нового класа). Разбиение каждый делает сам в силу своего опыта. Но этот способ не решает сложность связанную с слишком большим количеством сущностей(бритва Оккама). Множество библиотек Java, а в последнее время и .NET тяготеют к этому, получается то что я называю overcomplicated когда библиотеки стают настолько всеобъемлющие что один человек просто не может их постигнуть за приемлемые строки. Если это обосновано требованиями то пусть будет даже 1500 строчек, чем 15 с жёсткими зависимостями особенно цикличными друг к другу.
0
Самым подозрительным в приведенном фрагменте кода является то, что метод содержит объявление только
Еще одним признаком приятного кода я бы назвал расположение сначала открытых членов и только после них — закрытых. В общем случае пользователя не должна интересовать закрытая часть класса и чаще всего ищутся именно открытые члены. Более того, мне кажется естественным располагать конструктор на первом месте, перед всеми остальными методами (но после объявления открытых констант).
В вашем фрагменте конструктор не наблюдается (видимо, он определен ниже), и первое, с чем сталкивается читатель кода, это определение двух закрытых членов. Раз уж он их видел, то ему наверняка интересно будет узнать, необходимо ли их инициализировать в конструкторе. С этого момента можно считать, что данный код не является самым приятным кодом на свете, так как конструктор еще предстоит найти…
throws HabrException
, а в первой же строке он бросает IllegalArgumentException
. Но можно предположить, что это оговорено в соглашениях для данного проекта, поэтому не критично.Еще одним признаком приятного кода я бы назвал расположение сначала открытых членов и только после них — закрытых. В общем случае пользователя не должна интересовать закрытая часть класса и чаще всего ищутся именно открытые члены. Более того, мне кажется естественным располагать конструктор на первом месте, перед всеми остальными методами (но после объявления открытых констант).
В вашем фрагменте конструктор не наблюдается (видимо, он определен ниже), и первое, с чем сталкивается читатель кода, это определение двух закрытых членов. Раз уж он их видел, то ему наверняка интересно будет узнать, необходимо ли их инициализировать в конструкторе. С этого момента можно считать, что данный код не является самым приятным кодом на свете, так как конструктор еще предстоит найти…
0
Очень интесные замечания.
Про конструктор и открые члены: абсолютно согласен. В данном примере конструктор пришлось опустить. Полностю было бы: public конструктор, public post, private sendPost.
IllegalArgumentException
я не документирую отдельно, однако в комментарии к параметру функции указываю pre-condition («Must not be null», в случае title
из примера).Про конструктор и открые члены: абсолютно согласен. В данном примере конструктор пришлось опустить. Полностю было бы: public конструктор, public post, private sendPost.
0
На мой взгляд комментарии типа 'Number of posts per session' или 'Check input' даже не бесполезны, а именно вредны. Так же как и:
// Increment i
i++;
Не нужно комментировать очевидные вещи!
// Increment i
i++;
Не нужно комментировать очевидные вещи!
0
Как известно, финансовые и временные затраты на сопровождение программного продукта могут в несколько раз превысить затраты на его разработку. Программа, создаваемая 1 год, может использоваться 10 лет.
Одним из важнейших факторов, влияющих на способность программы к развитию, является правильная организация и оформление исходного текста. Если он написан без соблюдения определенного стиля и системы, без комментариев, представляет собой «мешанину» операторов и знаков препинания, то вносить изменения в него очень сложно даже автору. Представьте, что вы пытаетесь прочесть книгу, текст которой не отформатирован: нет абзацных отступов, разделения абзацев пустой строкой, пробелов после знаков препинания и т. д. Сложности модификации также значительно возрастают по прошествии времени и при необходимости работать с чужой программой.
Это цитата из «Инструкции программиста», которая в свое время была «скомпилирована» мной из несольких больших статей по «правильному» программированию (уже не вспомню каких). Инструкция писалась для себя, но с прицелом на студентов-программистов, которых мне отдавали на стажировку.
Инструкция больше ориентирована на С/С++ (хотя и применима для других языков), с применением doxygen'a.
Пара выдержек:
Правила оформления исходного текста
1. Иерархия конструкций
Подчинение операторов и управляющих конструкций заключается в том, что такие операторы, как операторы цикла (for, while, do), условные операторы (if/else), операторы выбора (switch) имеют основную часть (управляющую конструкцию) и подчиненную часть.
При описании класса в качестве управляющей конструкции выступает заголовочная часть класса.
При определении функции в качестве управляющей конструкции выступает заголовок функции.
2. Количество операторов в строке
Для улучшения читаемости исходного текста программы следует располагать не более одного оператора в строке, что вызвано особенностями человеческого восприятия текста. Кроме того, это облегчает пошаговую отладку в символьных отладчиках.
Использование двух и более операторов в строке допустимо только в том случае, если это позволяет подчеркнуть некоторую систему в локальной последовательности операторов.
3. Отступы (сдвиги)
Правильное использование сдвигов или, иначе, отступов (indentation) является ключевым методом обеспечения читаемости. Идея состоит в том, что отступы зрительно показывают подчиненность (иерархию) операторов. При этом директивы препроцессора (#include, #define и т.д.), описания классов, структур, типов, глобальных данных и определения функций всегда имеют наивысший приоритет, то есть начинаются с крайней левой позиции.
Если хаброобществу интересно, готов опубликовать в виде статьи (ну и дополнить с помощью конструктивных комментариев ;-) )
+3
У меня есть хорошее правило: если хочется написать комментарий к куску кода, то возможно, стоит подумать и попробовать сначала переписать этот кусок по-проще, ну а уж если попроще не получается, то писать комментарий, но комментировать не что код делает, а зачем он это делает.
+2
У меня есть хорошее правило: если хочется написать комментарий к куску кода, то возможно, стоит подумать и попробовать сначала переписать этот кусок по-проще, ну а уж если попроще не получается, то писать комментарий, но комментировать не что код делает, а зачем он это делает.
0
Я думаю к улучшению восприятия стоит добавить соблюдения уровня абстракции внутри каждого класса, бывает читаешь код класса который отвечает за работу с персоналом, все красиво, методы называется в соответствии с этим уровнем абстракции: не addData(), а addEmployee(), и тут раз, прямой вызов запроса на MySQL и обработка результатов. Я понимаю что это называется «чтобы быстро, очень просили», но хотя бы «TODO: » комментарий можно вставит с текстом вроде «перенести в другое место, обернуть в метод»
0
У констант можно комменты оформить тоже как javadoc:
Не
а
Тогда они появятся в сгенерированной javadoc -документации.
Но смысл так делать, наверное, есть только в случае описания статических констант.
Не
// Number of posts per session
а
/** Number of posts per session */
Тогда они появятся в сгенерированной javadoc -документации.
Но смысл так делать, наверное, есть только в случае описания статических констант.
0
> только в случае описания статических констант
А как константа может быть нестатической? Приведите практический пример, если Вас не затруднит. Не могу сам себе это представить.
А как константа может быть нестатической? Приведите практический пример, если Вас не затруднит. Не могу сам себе это представить.
0
Очевидно, что ваш примерный код передокументирован. Там комментов больше чем самого кода. Мусорные комменты, которые просто перефразируют названия методов нужно сразу удалять. А если они всё-таки в двух словах обьясняют что-то, то лучше этими двумя словами метод и назвать. Джавадок бесспорно нужен, но остальное только засоряет.
0
иде отступы проставляет, только почему то у меня это происходит время от времени
0
> 2. Файлы не длиннее 200-300 строк У громадных файлов та же проблема, что и у некоторых швейцарских ножей: невозможно запомнить, что эта хрень делает.
Принято считать что человек может одновременно осознавать 5-9 семантических едениц. Вот у меня, кажется, это не 9 и не 7, а 3 и то с трудом (при этом IQ у меня таки выше ста, просто ёмкость внимания низкая). Сплошной кусок кода длиннее нескольких строчек из нескольких простыъ выражений меня вгоняет в ступор, а попытка в нём срочно разобраться и вовсе в панику. Настоящим спасением для меня стали «регионы» появившиеся в Visual Studio 2005. Каждый логически самостоятельный блок я закрываю в регион и сворачиваю. Потом логически связянные последовательно расположенные регионы ещё в регион вместе. В результате получается нехилое дерево регионов в каждом файле, зато всегда точно ясно что делает каждый кусочек кода в отдельности и что они делают вместе с соседями в результате.
Аналогичную систему я в своё время (когда хранимые процедуры с бизес-логикой для SQL Server для большого ERP проекта писал) приделал к SQL взяв, кажется, UltraEdit и сделав там макрос с --#region/--#endregion (на манер C#, в котором это — стандартная директива, но прикрыв директивой комментария чтобы SQL сервер не пугать). Непонятно почему Microsoft (вроде как изобретатели этого приёма) до сих пор не реализовали его своих редакторах T-SQL-кода в Visual Studio и Management Studio.
Принято считать что человек может одновременно осознавать 5-9 семантических едениц. Вот у меня, кажется, это не 9 и не 7, а 3 и то с трудом (при этом IQ у меня таки выше ста, просто ёмкость внимания низкая). Сплошной кусок кода длиннее нескольких строчек из нескольких простыъ выражений меня вгоняет в ступор, а попытка в нём срочно разобраться и вовсе в панику. Настоящим спасением для меня стали «регионы» появившиеся в Visual Studio 2005. Каждый логически самостоятельный блок я закрываю в регион и сворачиваю. Потом логически связянные последовательно расположенные регионы ещё в регион вместе. В результате получается нехилое дерево регионов в каждом файле, зато всегда точно ясно что делает каждый кусочек кода в отдельности и что они делают вместе с соседями в результате.
Аналогичную систему я в своё время (когда хранимые процедуры с бизес-логикой для SQL Server для большого ERP проекта писал) приделал к SQL взяв, кажется, UltraEdit и сделав там макрос с --#region/--#endregion (на манер C#, в котором это — стандартная директива, но прикрыв директивой комментария чтобы SQL сервер не пугать). Непонятно почему Microsoft (вроде как изобретатели этого приёма) до сих пор не реализовали его своих редакторах T-SQL-кода в Visual Studio и Management Studio.
0
Ещё стоит, наверно, упомянуть, что в случае с большими классами иногда очень удобно делать partial классы и разносить их по нескольким файлам. Это заодно повышает удобство распределения разработки по версиям и по коллективу. Но, возвращаясь к заглавию статьи, увлекаться этим тоже не стóит, не участвовавшего в начальной разработке человека, вероятно, не меньше шокирует огромное колличество файлов и папок в исходниках.
0
Я мечтал написать такую статью, вот с такими же тезисами.
Все хорошее уже сделано :)
Все хорошее уже сделано :)
0
Sign up to leave a comment.
Код, который приятно читать