Перечитывая книгу Роберта Мартина, «Чистый Код», я нашёл очень интересные советы связанные с количеством аргументов в методах.
Всё сводится к тому, что нужно писать методы только с 1 (унарные), 2(бинарные) и 3 (тернарные) аргументами (ну и без аргументов тоже).
Всё что больше, нужно отсекать, да и тернарные функции писать очень редко.
Первое что я сделал после прочтения, начал смотреть свой код (много PHP :) ), и естественно нашёл множественное несоблюдение этому правилу.
Как и любой хороший программист, хочу писать хороший код, и не найдя достаточно информации по этому вопросу, хотел бы узнать мнение других программистов.
Вопросы:
1. соблюдаете ли вы советы Мартина по количеству аргументов в методах?
2. случались ли у вас проблемы или просто ненужные затраты времени связанные с этой проблемой?
3. при рефакторинге тестов, является ли для вас увеличение количества аргументов проблемой?
И хотелось бы услышать просто мнение, узнать о чужом опыте.
Следуя принципу Single Responsibility (кстати придуманный как раз Робертом Мартином) при описании методов, количество аргументов действительно редко превышает значения 1.
Вообще, читая такие книги надо всегда обращать внимание на то, что написано мелким шрифтом (обычно под громким заголовком). Думаю, написав целую книгу советов о программировании, Мартин должен был объяснить исходя из каких соображений он дает такие советы.
В большинстве — да, но есть методы, которые принимают 4-5 аргументов, и я не вижу в этом ничего плохого.
Все подобные правила — на самом деле рекомендации, которым нельзя следовать отключая собственную логику и здравый смысл.
Интересно, авторы всех этих книженций действительно думают, что количество аргументов в методах и прочие аттрибуты «хорошего кода» имеют хоть какое-то отношение к качеству конечного продукта?
Философия этой книги — «Честность в мелочах — вовсе не мелочь».
И я скорее согласен, чем нет.
К сожалению я не могу прийти в магазин и сказать «дайте мне таблеток, после которых я буду выпускать более качественное ПО».
Есть конечно много направлений для развития, но сегодня я бы хотел поговорить об этом.
mifki, когда встретитесь с ситуацией «из-за обилия технического долга в проект слишком долго вносятся правки и фичи, проще переписать заново, с новой командой» — вспомните свои слова.
Я только что выкинул и написал заново один из проектов компании, хочу переписать еще два с половиной, но пока не уговорил начальство. В них разные проблемы — первоначально неправильный выбор технологий, криворукие джуниор программисты, пишущие совсем ерунду, неправильная архитектура, не позволяющая реализовать стабильную обработку всех возможных ситуаций в логике поведения программы, использование велосипедов вместо стандартных средств, овержинжиниринг, когда вместо одной большой, но прямолинейной и понятной функции используется 3 класса и десять методов, в которых ногу сломишь, пока разберешься. Еще бывает наплевательсткое отношение к скорости работы и дизайну.
Но я никогда не видел, чтобы количество аргументов в методах вызывало какие-либо проблемы или наоборот избавляло от каких-либо перечисленных выше.
mifki значит мало копались в чужом коде. Выкинуть то оно проще, с Вашей стороны. Но, думаю, не просто объяснить начальству, как изменятся значения прибылей после переписывания проекта с нуля, и как скоро окупятся затраты на такое масштабное мероприятие.
Я только что выкинул и написал заново один из проектов компании, хочу переписать еще два с половиной, но пока не уговорил начальство.
mifki — судя по всему вы работаете с поделками а не с серьезными промышленными продуктами.
Качество кода = стоимость поддержки и расширения — всей дальнейшей эволюции продукта.
Соль в том, что стоимость внесения изменений в программные продукты со временем растет экспоненциально. И лишь используя специальные методики контроля качества кода это можно изменить. Об этом много написано. И если вы в своей практике этого не видите — то это не значит что теория туфта. Просто к вашему конкретному случаю это не очень применимо. Речь о больших продуктах, а не о тех которые может на коленке написать один человек. Когда работают команды на протяжении N лет приспосабливая систему к новому бизнесу — все на много порядков сложнее.
Практически раньше такие проекты гарантированно вели к краху в перспективе.
Большое количество аргументов в коде — это запах серьезной проблемы: отсутствия непрерывного рефакторинга старого кода. То есть человек вместо того, чтобы переработать объектную модель — добавляет новые аргументы. Это может даже говорить об отсутствии вообще адекватной объектной модели. Поддерживая число аргументов в коде (а это очень простое правило для разработчика — потому что нарушение выявить легко) — мы будем вынуждены перерабатывать объектную модель и реагировать на такие проблемы.
pletinsky, да, я работаю с довольно небольшими продуктами, но это не даёт вам права называть их несерьёзными поделками, которые мы делаем на коленке. Подавляющее большинство используемых пользователями программ являются таковыми.
Я не хотел обидеть вас и ваши творения. В данном слове из моих уст не было негативного оттенка.
Думаю большинство используемых пользователями программ действительно маленькие, если сравнивать количество. Но большая часть разработчиков все таки трудится в больших проектах (ну я так думаю). И разумеется вопросы качественного кода и рефакторинга имеют смысл лишь в проектах с достаточным количеством людей.
В проектах которые пишет один человек это не так актуально — как правило в таких проектах код вообще не отличается качеством. И дело тут не в компетенции людей. Даже если разработчик очень крут — когда он один у него не будет стимула писать качественный код. Он будет уверен что его код хорош — но будет ошибаться — потому что проверить его все равно не кому.
Именно поэтому такие проекты и называют столь не полюбившимся вам словом «поделка». Без менторства вне команды невозможно научится писать качественный код. Просто потому, что он там никому не нужен. Но на крупных проектах он очень важен.
Там используют правила рефакторинга. И поставленный автором вопрос — это тема Code Smells, а вовсе не правил хорошего кода, хотя не уверен что он это понял.
pletinsky Ну, всё же, вопросы качественного кода имеют смысл везде. Я-то как раз за качественный год, просто понимаю это слово шире, и считаю, что качество кода, и уж, тем более, конечного продукта в целом не может напрямую коррелировать такими модными сейчас показателями, как количество строк в функциях, количество аргументов, процент покрытия тестами и прочее. Чтение советов незнакомых дядек в книжках и следование им не сделает из плохого программиста хорошего, так же, как команды, написавшие отличные продукты, не должны пойти убиться, обнаружив, что их код весь не по правилам.
Поэтом у меня вопросы, подобные заданному автором, и вызывают такую реакцию.
mifki, читая ваши комментарии, сразу виден юношеский максимализм. Лично у меня раньше не раз возникало желание переписать все внутренние проекты компании потому что «они не такие и написаны не мной».
Понимание советов незнакомых дядек приходит с опытом, когда лично сталкиваешься с подобной проблемой. И тогда советы дядек становятся очевидными.
Из плохого программиста сделать хорошего может только он сам, постоянно работая над собой и над новыми проектами с разными людьми и подходами к реализации.
Gariks, в моем случае причина довольно банальна, три проекта были отданы аутсорсерам, которые сделали откровенную лажу, с ней теперь все мучаются, потому что в силу специализации на других технологиях не знают, что можно сделать по-другому и избежать разом всех нынешних проблем.
mifki
Я посмотрел ссылку, которую вы дали. Возможно вы неправильно поняли автора комментария. Он говорил об оверинжениринге. О том, что при чрезмерном увлечении абстракциями и паттернами можно не улучшить а ухудшить качество кода. А вовсе не о том, что вопросы рефакторинга из умных книжек это ерунда. Более того, рефакторинг — близкий друг принципа KISS. Потому что писать код просто — это не значит писать его кое как.
И как раз во время рефакторинга обычно удаляют лишний код и ненужные конструкции.
А для того, чтобы выявить те или иные проблемы включая переусложненность кода и используют запахи кода, которые указывают на скрытые проблемы. Одним из таких индикаторов проблем в коде являются методы с большим количеством параметров. Сами по себе они не большая проблема — но указывают на проблемы с объектной моделью приложения.
Есть люди которые очень хорошо знают все советы умных дядек в книжках и говорят что это ерунда. Есть люди, которые не знают эту кухню и тоже говорят, что это ерунда. Но их слова несут совершенно разный смысл. Слова первых не стоит понимать буквально.
Читая эту книгу нужно иметь ввиду что она написана для объектно-ориентированного языка программирования. В ООП данные могут передаваться в конструкторе, сеттере и в самих методах. Т.е. аргументы метода относятся непосредственно к методу. Если аргументов много то их можно объединить в какой-нибудь класс типа <бизнесметод>.
1. Да. Исключение — конструкторы.
2. Конечно — чем больше аргументов, тем сложнее рефакторить использование этого метода. Растёт в геометрической прогрессии.
3. Да
Если у метода 1-2 аргумента, его назначение можно полностью описать его названием так, чтобы из названия было понятно, что ему нужно передать и как это будет использоваться. Например: sendEmail(email), setPasswordForUser(password, user). А читаемость кода это очень, очень важный фактор.
Если следуете этому правилу, создавая обёртки для однотипных переменных (например, Point), оставляйте функцию с исходным набором параметров. Очень часто приходится видеть вещи вида
setPlayerCoord(new Point(1, 2, 3));
Основное мое правило — метод должен как можно меньше распылятся: выполнять явную задачу. При таком подходе кол-во аргументов точно не превысит максимальное по Мартину.
И да, что по поводу массива который сойдет за один аргумент с кучей значений?
В лобешник закатать надо за массив с кучей аргументов. Хрен разберёшься потом, какие должны быть ключи, какие из них обязательны. Передавайте объекты. В C, вон, структуры передают — создавайте объекты без методов — юзайте как структуры.
К сожалению видел во многих фраемворках написанных на нетипизированных яп такую фичу, как массив-аргумент.
И очень часто это неудобно и не безопасно в конечном итоге.
Не надо так делать :) Может быть оправданно только в том случае, если у вас несколько десятков аргументов. И то, на мой взгляд, гораздо логичнее будет сделать класс — обёртку над этим несчастным массивом с кучей поименованных get/set. Чтобы не было красивостей, похожих на
Ребят, я это понимаю :) Просто немного не так сформулировал вопрос. Хотелось узнать описывает ли автор книги такую ситуацию и не использует ли спрашивающий такой подход.
Часто случается так, что в погоне за «преимуществом/правильностью» можно свернуть не туда.
Одним из видов кода с большим количеством аргументов — это получение данных из базы. В нём можно на практике увидеть, почему большое количество аргументов — это плохо.
//Получаем запись
abstract public function getRecords($what='*',$where=NULL, $limit=NULL, $order=NULL,$join=NULL,$debug=false);
самое интересное начинается, когда сортируем чаще, чем ограничиваем и решаем поменять параметры $limit и $order местами. или когда решаем добавить ещё один параметр, который ставится после $debug. или когда решаем переделать список параметров на параметр в виде массив. или когда…