- PVSM.RU - https://www.pvsm.ru -

Я пишу программы уже больше 15-ти лет, из них 11 — профессионально. Т.е. получаю за это деньги. Через меня прошло десятки коммерческих проектов разной величины. Вспоминая себя того, совсем юного девелопера, я понимаю насколько разнится у матерого разраба и юнца. Насколько развита интиуция и понимание после десяти лет разработки разноплановых проектов и только вышедшего из универа парня. Который, в то время, и курсовую левой рукой напишет, и дипломную, и даже авторегистратор для сайта знакомств.
В те годы, 10 лет назад, я думал скорее о хорошем тоне программирования, комментариях, наследовании и паттернах. О заученных постулатах Страуструпа и Кнута. К слову последний, до сих пор загорается яркой лампой в голове, со своей оптимизацией программ. Это «O(N^2) или O(NlogN)» невольно думается, когда выводишь 7 записей по дням недели.
А стоило прочитать серию для экспертов С++, того же Александреску или Скотта Мейрса, так
При этом программа выводила ничего. А заказчик то ждал…
Оглядываясь на то время, и наблюдая как дела обстоят сейчас, я решил собрать небольшой шорт лист из костылей, хаков, обходных путей (workarrounds) и прочих нетривиальных ходов, о которых начинающий разработчик может не задумываться. Да впрочем не только он.
Не, ну это же классика кун-фу:
Сначала ты не знаешь, что нельзя делать то-то
Потом знаешь, что нельзя делать то-то
Потом ты понимаешь, что иногда таки можно делать то-то
Ну а потом ты понимаешь, что помимо того-то существует еще шестьдесять шесть способов добиться желаемого, и все из них практически равноправны.
Когда тебя спрашивают «как мне добиться желаемого», ты быстро перебираешь в уме эти шестьдесять шесть способов, прикидываешь то общее, что в них есть, вздыхаешь и говоришь: «вообще-то, главное — гармония.»
На вопрос обиженных учеников: «а как ее добиться?», ты говоришь: «никогда не делайте то-то».
Оригинал [2]
Между тем как видит программу пользователь и как видит ее разработчик — пропасть. Мы видим коды, архитектуру, хитросплетение классов и функций. Человек же видит кнопки, поля
ввода и картинки. Не редко, пользователь получает результат, который совсем не ожидает. Не редко, пользователю выдается ошибка, от которой тот начинает нервничать и ерзать на стуле. А нам всего-то строчку поправить.
Так вот главное связующее звено между вешей программой и пользователем — это его восприятие. То есть то, что видит пользователь — такие у него и ощущения от вашей программы. Казалось бы очевидные вещи, но есть другая сторона медали. Это восприятие программиста. Об этом говорилось много раз, говорилось о правильном построение архитектуры, разделении обязанностей между классами, асинхронности и производительности.
Но редко кто заикался о восприятии самого пользователя. Того парня, который никогда не увидит SOLID-принципов за приложением с одной кнопкой. Того человека, который и платит деньги, и во многом благодаря которому эта программа [еще] существует.
Большая часть моего опыта — это фриланс. Или работа на заказ, с прямым общением с заказчиком. В этом плане работа в большой IT-компании в корне отличается восприятием процесса разработки, хотя бы по причине отсутствия контакта с конечным пользователем. Сеньоры в таких компаниях могут неделями и месяцами выстраивать многослойную архитектуру, обобщать интерфейсы и дженерики, и в 99% случаев заниматься оверинженирингом.
Во фрилансе же — ситуация ровно противоположная. Нет, тут не царит повсеместный говнокод… хотя кому я вру.
Часто именно он самый, да кодинг на скорость — вот что получается от хотелок заказчика. Т.к. бюджет лимитирован, а на код, код-ревью, юнит-тесты, QA всем плевать.
Есть исключения, но если мы говорим об условном Джонни из Флориды с 1000$ в кармане, и Вами на другом конце провода в качестве исполнителя — то ситуация именно
такая. Не GoF паттерны с юнит-тестами ждет Джонни за свои кровные, а удовлетворить свой business need.
Ок. Бог с ним с фрилансом. Вариант №2 — крупная компания и дедлайн. Очень распространенная ситуация. Сдавать новую версию нужно вчера, а приложение в один из 100 запусков выдает NPE. Что делать? Сгустились тучи над компанией, все сбежались один баг фиксить. И так и этак, а у кого-то дай и упадет. Не до хорошего уже. Костыль один, второй, третий… и о чудо! — Не падает!
Это было лирическое отступление. А теперь ближе к списку хаков.
Для начала, давайте отойдем от кода и обратим внимание на две главные вещи, которые
влияют на восприятие пользователя при работе с программой — это А) Картинка Б) Время.
Повторюсь, именно Картинка — то, что видит пользователь, и Время — сколько времени он работает, ждет, загружает, и так далее. Звуки, вибрации, может быть даже запахи — тоже возможно. Но в конечном счете взаимодействие сводится к этим двум.
Скажу более, картинка и время — это не только про пользователя. Это и про заказчика, и про менеджера, и про процесс разработки в целом. Именно поэтому — я всегда начинаю разработку с UI. Всегда. Чем раньше покажешь красивые интерфейс заказчику, тем сильнее будет впечатление, и тем быстрее выстроятся доверительные отношения между вами. Будь я тим-лидом, фрилансером или шараварщиком — первое, что я делал — это Картинка (User Interface). Нет, даже не так. Very Cool User Interface. И плевать на внутренности и все остальное на этом этапе.
На кону время. Время разработки и установление доверительных отношений.
А теперь наконец о хаках. Тех самых хитростях, которые могут помочь вам справиться с дедлайном, пофиксить неуловимый баг или «сделать видимость как должно быть». Вы должно быть их знаете, но только в другом контексте.
Поэтому я добавил примеры из моих реальных проектов, где эти хаки пригодились.
Швейцарские нож среди костылей (извините за каламбур). Насколько мне известно, каждый известный язык программирования (не запросов и не разметки) имеет таймер. Точнее стандартная библиотека языка. Таймер можно комбинировать с другими девхаками.
Таймер идет первым по списку, потому что именно он позволяет перехватить любое неведомое событие происходящее через определенный промежуток времени.
Это может быть вообще за пределами программы или происходить в закрытом модуле. Проходит 5 секунд — и обновить, закрыть, прибить, ваш вариант.
Вариация на тему: отдельный поток с функцией Sleep().
Пример из реального проекта:
Плагин для браузера, после загрузки страницы, должен был изменять ее содержимое. Стандартный обработчик loaded или ready() срабатывал слишком рано, и не все элементы и фреймы подгружались к этому моменту. Поэтому пользователю показывалось
белое окно поверх сайта, которое через 10 секунд пропадало. Чего было вполне достаточно, чтобы весь контент загрузился и плагин изменил содержимое всей страницы.
Логическое продолжение девхака «таймер», с уточнением, что «собака» мониторит другой процесс, делая регулярные проверки.
Процессом может быть как само приложение, внутри которого сидит «собака», так и внешний процесс. Так что, если вы вдруг услышите от другого разработчика — «А давай на него собаку пустим!» — знайте, речь идет о watchdog.
Примеры из реальных проектов:
1. Программа не должна была быть закрыта или прибита из таск менеджера. Она запускала watchdog, который каждую милисекунду проверял список запущенных процессов, и в случае чего, запускал основной процесс заново.
2. Программа делала backup'ы файлов. Второй Watchdog процесс мониторил создание бекапов в определенной папке и отправлял уведомления на сервер.
Очень часто, особенно в больших проектах, существует проблема передать данные из одного объекта в другой. Для этих целей можно использовать и Dependedncy Injection, однако не везде подходит. Речь же сейчас идет о девхаках. (Злобный читатель может назвать их грязыми хаками, но это не так. Некоторые из них довольно чистые).
В C# для этого отлично подходят обертки над делегатами Action, Func, В других языках — (указатели на) функции. До них будет просто добраться, если сделать статическими полями.
Пример из реального проекта:
В отдельном usercontrol пользователь нажимает checkbox. В основном окне, нужно проверить, чтобы отмеченных флажков было не больше 5.
На C#:
class MyControl
{
public static Func<bool> IsMoreThan5;
void OnChecked(CheckBox checkBox)
{
if (IsMoreThan5(checkBox))
{
Error("Можно отметить только 5 флажков!");
checkBox.IsChecked = false;
}
}
}
class MainWindoow
{
public MainWindoow()
{
MyControl.IsMoreThan5 = MoreThan5; // Задаем Callback
}
private bool MoreThan5()
{
int total = 0;
foreach (var checkBox in AllCheckboxes)
{
if (++total > 5)
return true;
}
return false;
}
}
Широко известный способ не дать заскучать пользователю, пока выполняется долгая операция. Также несет информативную состовляющую, сообщая сколько времени, процентов еще ждать.
В реальном проекте:
На одном вебсайте, пока загружались все данные, мы показывали цитаты великих людей. Пользователям нравилось.
Не столько интересен сам хак, сколько проблемы, которые он помог решить:
1. Однажды мне попался проект десктопного приложения, где фронт-енд был написан на HTML/JS и хостился в CEFSharp браузере.
Так как приложение было под Windows, а мне гораздо удобнее работать с WPF, чем HTML, то было сделано следующее:
Когда нужно было открыть экран с HTML-UI — показывался CEFSharp браузер с ним. А уже новые окна, которые были сделаны на WPF — показывались вместо браузера. Сам CEFSharp — прятался. Заказчик остался доволен.
2. Многие приложения устроены по принципу: разные меню, фон и основной placeholder — место где изменяется содержимое. Придумано множество фреймворков, где нужно создать 3 разных файла, 2 проекта, и в 5 местах зарегистрировать экраны, чтобы их можно было
переключать. В WPF приложениях я поступаю проще — храню все экраны (контролы) в свернутом виде в основном окне, и по запросу один показываю, а остальные прячу. Никаких оверхедов и фреймворков. Все просто.
Пример из реального проекта:
Нужно было запускать приложение, но чтобы пользователь его не видел. Malware? — спросите вы. Нет, не оно. В окне приложения грузился другой сайт и его содержимое нужно было проанализировать в фоне. Делаем что-то вроде
window.SetPosition(-10000, 0);
И окно улетает за пределы экрана, выполняя свою работу и не мешая пользователю.
Миллионы готовых утилит и программ лежит в свободном доступе. Возможно не нужно ничего писать? Зашить утилиту в ресурсы своего приложения, распаковать при старте и запустить. (Опционально)
Есть два момента: 1) антивирусу это может не понравиться 2) проверяйте лицензию программы.
Пример из реального проекта:
ffmpeg — универсальная утилита. Везде, где фото и видео обработка в проекте требовала больших усилий — запускался ffmpeg.
Когда-то на хабре пробегал перевод про геймдев, в котором разработчик отчаянно пытался пофиксить баг. Если не ошибаюсь, его персонаж постоянно проваливался за стену именно в одном месте. Тогда он решил сделать фикс таким образом:
когда объект находится именно в этой координате, то сдвигать его в сторону. Profit!
Если же у вас случается exception при каком-то определенном условии — логично его проверять и корректировать данные.
Это из области системного программирования. Хуки можно повесить глобально на почти любые события в ОС. Будь-то события клавиатуры, мыши, запуск процессов итд.
Пример из проекта:
Писал я как-то кейлоггер… Нет, была и реальная необходимость. Например в приложении для проверки зрения, мышь нужно было останавливать возле определенного символа. Девхак Хук может быть полезен, если например мы имеем закрытый модуль, защищенный
от изменений, а он себя не правильно ведет при нажатии клавиш или кнопок мыши. Хук на клаву делает workarround.
Далее речь пойдет меньше о технических, больше о жизненных хаках. О лайфхаках.
Это из области психологии. Чем больше визуального шума, разных сущностей и раздражителей в нашем поле зрения — тем сильнее это давит на
В реальных проектах, я всегда работаю только с одним проектом обособленно от остальных. Стараюсь максимально разделять один модуль и всю систему, при этом обязательно оставляя возможность запускать модуль самостоятельно, без всей системы.
Преимущества очевидны:
a) Время компиляции не всего солюшена, а только небольшого модуля в x5, x10 раз быстрее
б) Внимание сосредоточено там, где должно быть.
А задумывались ли вы когда-нибудь, зачем писать код, если его может написать кто-нибудь другой? Мы как разработчики, часто думаем, что именно мы должны делать реализацию всего проекта От и До.
Но ведь есть еще много свободных рук, которые свежим взглядом наговнокодят могут решить часть задачи, избавив вас от рутины или чего еще.
В реальном проекте:
Например у меня не было времени разбираться с модулем, в котором полно матана. В итоге за небольшую сумму отдал задачу написать модуль другому фрилансеру и по завершении спокойно прицепил его во всю систему.
Давая фрилансеру подробную спецификацию и понимания четко что нужно сделать — положительный результат гарантирован.
Более того, только начав формировать задачу, а затем получая заявки от разработчиков, уже на этом этапе можно найти решение, не тратя деньги.
Как вариант — вопрос коллеге. Мы программисты погружены в свой мир, который и является рамками нашего
Хотя бы проговорить задачу и проблему, а на том конце услышать «Угу» — уже разгрузит голову и подведет ближе к решению.
Неплохо работает в комбинации с лайфхаком «Чистый проект».
Где может пригодиться:
— Узнать как работает код закрытого модуля (в первую очередь)
— Проверить секьюрность программы, в том числе обфусцированной
— Взять кусок кода себе (в последнюю очередь)
На этом мой пост заканчивается, а у вас, я уверен, есть еще десятки хаков в запасе, которые экономят время, силы и решают проблемы.
Автор: Денис
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-2/270459
Ссылки в тексте:
[1] мышление: http://www.braintools.ru
[2] Оригинал: http://rsdn.org/forum/humour/1600906.flat
[3] Источник: https://habrahabr.ru/post/344436/?utm_source=habrahabr&utm_medium=rss&utm_campaign=344436
Нажмите здесь для печати.