LINUX.ORG.RU

Чистый код нужен прежде всего для упрощения реверс инжиниринга?

 , ,


0

2

Вот такое подозрение возникло у меня при чтении книжки «Чистый код» 2016 года выпуска.

Сначала всё было более-менее ничего. Разумные пожелания. Когда-то я подходил к этой книжке в магазине и открыл страницу, где советовали делать функции короче. С тех пор мои функции стали намного короче.

Но когда я купил книжку, стал её читать не спеша и дошёл до главы о функциях, там стали советовать делать функции желательно вовсе без параметров, с одним допустимо, с двумя - плохо, с тремя - вообще ужас.

Параметры предлагалось группировать в объекты или запихивать в переменные класса!

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

Количество параметров у них порядка десятков.

Идея запихнуть всё в класс и сделать жирное «состояние» мне вообще не понравилась. Эта идея однозначно делает код более неявным, менее ясным и даже менее надёжным. Напротив, сейчас считается более модным применять чистое ФП везде, где это только возможно. А тут предлагается совершенно противоположная идея: увеличивать степень императивности.

Тут-то я и заподозрил неладное. Если сделать короткие функции по 4-5 строк с длинными говорящими именами, избавиться от локальных переменных (которые наверняка не сохраняются в метаданных), то вся структура кода будет находиться в метаданных, причём смысл каждого малюсенького куска кода будет выражен на понятном человеку языке (ведь нужно тщательно выбирать понятные имена). Каждая сущность данных также будет поименована. А уж связь между ними легко достаётся из байт-кода. Учитывая, что байт-код Java сам по себе легко декомпилируется, подобная практика сделает реверс инжиниринг совершенно тривиальным.

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

Старательно выражая содержимое комментариев в именовании кода, автор кода любезно предоставляет реверс-инженеру нужную ему информацию в уже готовом виде - в противном случае он бы её не смог добыть.

★★★★★

Старательно выражая содержимое комментариев в именовании кода, автор кода любезно предоставляет реверс-инженеру нужную ему информацию в уже готовом виде - в противном случае он бы её не смог добыть.

Как что-то плохое.

Lincor ()

Но когда я купил книжку, стал её читать не спеша и дошёл до главы о функциях, там стали советовать делать функции желательно вовсе без параметров, с одним допустимо, с двумя - плохо, с тремя - вообще ужас.

А можно цитату или ссылку? Слишком дико звучит.

tailgunner ★★★★★ ()

А какую книжку почитать, что бы мой код стал менее быдло.

anonymous_sapiens ★★★★ ()

Анонимус одобряет чистый код

Опенсорсу только профит, а проприетарщики должны страдать.

anonymous ()

Js-анонимус разёнс инфекцию по всему ЛОРу, срочно перейдите в карантин.

anonymous ()

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

MinasFilm ()

Всё что нужно действительно прятать всё равно пропускают через обфускаторы и компанию.

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

Короче нет.

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

А можно цитату или ссылку?

Ссылку не дам, цитату набью небольшую: [Роберт Мартин Чистый Код Питер 2016, стр. 64-65]

В идеалном случае количество аргументо функции равно нулю... Далее следуют функции с одним аргументом ... и с двумя ... . ... тернарных следует по возможности избегать. ... Аргументы усложняют функции и лишают их ... концептуальной мощи. ... Возьмём хотя бы переменную StringBuffer. Её можно было бы передать в аргументе (вместо того, чтобы делать её переменной экземпляра), но тогда читателям кода пришлось бы интерпретировать её каждый раз, когда она встречается в коде. ... Аргументы создают ещё больше проблем ... тестирования. ... Если аргументов нет - задача тривиальна. Если же аргументов больше двух, задача ... выглядит ... устрашающе ...

Далее предлагается для решения этой проблемы делать группы аргументов объектами. Например, не (x,y), а (point). Но практически в примерах аргументы сплошь и рядом преобразуются в поля объекта.

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

Ты уверен, что _все_ обязательно пропускают? Ведь секта как строится? Не нужно завлечь всех, нужно завлечь достаточное количество доноров. А если есть возможность просто брать даром код у 50% авторов, так ли нужны остальные 50%?

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

Ты уверен, что _все_ обязательно пропускают?

Все у кого цель скрыть кишки - да. Иначе это школьник. А кому по настоящему может быть необходим код школьника? Разве что другому школьнику.

iu0v1 ()
Последнее исправление: iu0v1 (всего исправлений: 1)

Вот такое подозрение возникло у меня

требуются санитары в тред

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

У него много хороших мыслей касательно проектирования. Но нужен хороший фильтр. Он просто давно не писал кода.

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

Ну ладно, пусть будет так. Я своей паранойей, во всяком случае, поделился, а вы уж не будьте школьниками (я сам на Java не пишу). Аминь.

den73 ★★★★★ ()

Не знаю насчет «чистого» кода, но простым его следует делать прежде всего для себя и своих коллег (иными словами для тех, кто будет сопровождать код). Иначе ты сам через пару месяцев не разберешь тонкие моменты в своем же коде.

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

Если читать текст как «ни в коем случае не делайте функций с четырьмя параметрами», то да, слабоумный. Только не автор, а читатель, который так понял.

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

anonymous ()

для начала неплохо было понять что понимается под чистым кодом или серым кодом, не чистым кодом.

a = 1; b = a;

это чистый код?

короче - баззворд

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

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

А знаешь почему автор якобы сначала советует делать жирное состояние и объединять группы параметров в объекты, а сам так не делает потом? Потому что он думает головой, а ты нет и надеешься на серебряную пулю, которая избавит от необходимости думать. Оказывается автор не даёт такой серебряной пули, что тебя конечно разочаровывает - «советы автора не работают, он слабоумный». Однако для самого автора они работают... Хм... Что же тут не так?

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

дурилка, это не классный код, это антипаттерн God Object

anonymous ()

Говнокод реверсить сложнее.

Мимореверсер.

Deleted ()

Чушь. Читайте «Совершенный код» макконелла лучше. Он говорит о том, 2-3 аргумента - ок, более 5 - точно много, тупо потому что человек может удержать в уме одновременно 5-7 сущностей, более - уже человек будет путаться и перепроверять. Это же самое касается локальных переменных.

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

Он говорит о том, 2-3 аргумента - ок, более 5 - точно много, тупо потому что человек может удержать в уме одновременно 5-7 сущностей

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

anonymous ()

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

Забудь о защите ява кода. Только обернув его полиморфным кодом на асме можно чего-то достичь. Глянь на код skype. Там и защиты срабатывают и участки кода меняются. Яве это только снилось. Конечно, ты можешь поверх явы навернуть свою защиту. Только причем тут твоя книга?

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

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

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

я сейчас поискал классы в нашем текущем проекте - 7800 основных, и 15300 если все (включая автоматически сгенеренные). Вреда от добавления еще классов особо нет, а профит очевидный - как раз то, о чем говорит автор

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

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

например, в SDK джавки есть шаблон для функции с одним параметром (Function) и с двумя параметрами BiFunction. А вот TriFunction итп придется писать самому. Что как бы намякивает, что начиная с двух аргументов предполагается свертывать параметры в класс. Пруфы: https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary....

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

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

или эффективно иммутабельными - т.е. после создания средствами языка изменять можно, но по конвенции - нельзя. Например, в джавовском SDK есть мутабельный класс Date, который по факту никакой разумный человек менять не будет - вдруг чо. Если например, по какой-то причине обязательно требуется на вход мутабельный джавабин, то можно сэмулировать локинг, во все сеттеры поставив инкремент счетчика обращений, и если в следующей секции счетчик больше нуля - объект скомпроментирован и бросать IllegalStateException (ну или как вариант бросать в сеттере IllegalOperationException). Короче тут мутная тема, как сохранить в целостности и сохранности effectively immutable и effectively threadsafe куски кода.. Только дисциплина, боль и унижение

stevejobs ★★★☆☆ ()

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

anonymous ()

Для всяких нехороших людей есть обфускаторы. Защемлять свои яйца только ради того, чтобы защемить вместе с ними яйца злоумышленника — идиотизм.

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

или эффективно иммутабельными - т.е. после создания средствами языка изменять можно, но по конвенции - нельзя.

Это затруднительно сделать в рамках чистого кода. Пример с 5 полями в той книжке есть, хотя бы на стр.172. Каждая ф-я принимает не более 3 параметров. Пусть поля получаются присваиванием извне. Значит, если у нас 5 полей в классе, нужно хотя бы два вызова, чтобы записать извне 5 полей.

Т.е., первая функция будет заведомо работать в ситуации, когда ещё не все поля инициализированы. Значит, их уже нельзя считать иммутабельными.

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

У меня было подозрение, что это имелось в виду, но я не готов поверить. Идиот не справится с программированием.

Только причем тут твоя книга?

При том, что без имён локальных переменных и при больших функциях в коде нелегко разобраться, даже если ты его декомпилировал. Я пробовал. А вот если код чистый - то просто бери, называй переменные именами v1,v2,v3 и всё равно всё будет понятно.

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

Если ЯП со сборщиком мусора, то однозначно лучше point, чем x,y иначе скорее всего тоже лучше point, хотя где 1-2 аргумента не так страшно.

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

Если читать текст как [...]

А вот если читать как [...]

А вот и толкователи священных текстов подтянулись.

tailgunner ★★★★★ ()

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

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

Deleted ()

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

Ты же не передаёшь ls-у кучу параметров просто так:

ls 1 2 true false true 4 5 true false
. Ты их именуешь, т.е. создаёшь один объект «параметры». Аргумент так себе.

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

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

Старательно выражая содержимое комментариев в именовании кода, автор кода любезно предоставляет реверс-инженеру нужную ему информацию в уже готовом виде - в противном случае он бы её не смог добыть.

Без обфускации это большой роли не играет, разберут хоть так, хоть так. А с обфускацией это тоже большой роли не играет, всё превратится в a b c a1 a2.

Вот последнее, чем надо руководствоваться при написании кода в общем случае — задумываться о том, как усложнить жизнь реверсеру. Хочешь усложнить — пользуйся обфускаторами, пользуйся специальными защитами, но уже после того, как напишешь код.

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

Просто в недоязычках не завезли именованных аргументов.

приведи пример с именоваными агрументами

Хотя если функция ждет много параметров, значит она слишком много на себя взяла.

а если эта функция - большой метод, который всего-лишь является контейнером для маленьких функций?

reprimand ★★★★★ ()

Автор плавно подводит тебя к мысли: не пиши монструозных программ. совсем.

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

Роберт Мартин

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

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

Ну если ты такой тупой, что тебе растолковывать приходится... =)

anonymous ()

Все фигня (кроме пчёл).

Как часть советов, так и твоё заключение.

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

Ладно, давайте закругляться уже.

Я понял одно - вопрос реверс инжиниринга решается обфускаторами. Для тех, кто ими воспользуется. Остальные подарят свой код авторам этой книжки. Те, кто работает на Java, может легко меня проверить, почитав любой стек трейс проприетарного приложения. Если там абракадабра, то они воспользовались обфускатором. Если там нормальные человеческие слова, то нет.

Ещё одна заметка. В книжке полно примеров с игнорированием исключений. Я уж не знаю, что автор вкладывает в слово «чистый», но в моём понимании это не то же, что «хороший». Хороший код не должен игнорировать ошибки. Даже если это учебник.

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

растолковывать приходится... =)

Напиши Мартину и приложи свой вариант толкования. Интересно, куда он тебя пошлет.

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

А вот не надо читать всяких мартинов, фаулеров, кокбернов, атвудов, спольски и прочих

Как раз надо, чтобы понимать откуда ноги растут у быдлокода, с которым приходится работать. Ну и что-то разумное у них иногда проскакивает. Не надо бежать сломя голову реализовывать все эти приемы because i can, это да.

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

Сам напиши ему, что считаешь его слабоумным. Посмотрим куда пошлют тебя.

anonymous ()

Параметры предлагалось группировать в объекты или запихивать в переменные класса!

Немного полистал и второго не заметил. Но вот первое — вполне себе нормальное предложение. Про printf он пишет, что считает её бинарной, ибо по сути она принимает два аргумента: 1. формат строки; 2. список подставляемых аргументов. В этом есть здравое зерно.

nezamudich ★★ ()

Чистый код нужен прежде всего для упрощения реверс инжиниринга?

Да. Причём заниматься этим делом ты будешь сам, спустя полгода после написания.

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