Была бы у меня возможность показать вам код проекта которому уже лет 6 как, на ноде, с колбэками, без абстракций… когда в контроллере функции на (я не шучу) 2k строк… и все это еще завязано на ивент емитере…
Дв даже если его разбросать по ту мач абстракциям, вреда будет в разы меньше… как минимум можно будет протестировать абстракции.
Мы как в том анекдоте, едим кактус и плачем. Ооочень медленно вводим абстракции вида
1. Validation layer (валидаци? какая валидация? =))
2. Thin Controller (сейчас это просто куча кода с колбек хелами)
3. Service Layer (отсутствует как класс. вся логика в контроллере)
4. DAO/Repository (сейчас монгуси прямо в контроллерах)
5. Mappers (работаем с внешними апишками)
6. Resources (http clients)
Да, файлов много. Но уже не так потеешь когда открываешь контроллер. И этих файлов будет еще больше. Но альтернатива в виде огромных функций это ад…
Ну и нужно понимать, абстракции потекут если их не поддерживать… и превратятся в гомно, кучу кода с ифами… я думаю все мы это проходили =))
з.ы.
Естественно мы не пытаемся впихнуть невпихуемое типа абстрактной фабрики и т.д. Да и 80% разработчиков и не слышали о них, может это и к лучшему =))
з.ы.
И да, стараемся переписать на микро-сервисы… сложность убегать на уровень выше…
Мне до работы 10 мин на мотоцикле. С воскресенья тоже можем работать дома. Вроде и удобно, так как экономится время на одеться+доехать. Если зубы не чистить, еще 2 минуты можно сэкономить =))
Но я когда работал на себя, и я помню как тяжело заставить себя работать дома. Холодильник, телевизор, балкончик с пепельницей… все это отвлекает. А сейчас работая в стартапе, понимаешь что возможность зайти в соседнюю дверь к девопсам попросить че нить, или сделать смол толк на кухне по поводы какой-то кривой фичи, и много других «мелочей» типа нескольких мониторов, стабильная сеть и т.д. реально влияют на мое КПД.
Хотя бывают дни когда тебя интерраптят по поводу и без повода, что реально хочется закрыться где нить с наушниками и тупо часами писать код.
Так как в кампании большинство программистов с других городов, я думаю приезжать в офис и работать одному, но в офисе. Психологически легче настраиваться на работу :/ Но если запретят вообще, придется с дома работать, и я чувствую что я буду тратить больше время на работу чем работая в офисе :/
Как-то так…
з.ы.
И это я холостяк. У кого дети дома, уже плачут горькими слезами =)))
Не решается ли первое добавлением своего zero value object? Другое дело что это будет конвенцией за которой тяжело уследить в большой команде или кросс тим разработке. По идее компилятор раста забирает на себя эту работу… что есть хороше как я понимаю.
То есть если в го (жава и т.д) мне что б понять если может прилететь nil, мне нужно просмотреть код… и найти того кто вместо *something может мне кинуть nil, то в Rust я это вижу явно, что не дает мне возможности пропустить хендлинг этого случая?
Как так, если даже в документации есть пример: golang.org/pkg/time/#example_Sleep
Вот что я люблю в ГО, так это то, что тесты рядом с файликами есть даже в стандартной библиотеке. А так как язык простой, то и тесты и сорсы читаются на отлично…
Пока 2 просмотрел. Столько нюансов и подводных камней… реально нужно понимать как компилятор работает что бы писать нормально. На порядок сложнее GO.
А вообще последние 2 года только на Node.js пишу (работаю с стартапе). И если на GO я еще могу пописать для себя, или тулзу запилить на работе just for fun, то с Rust чувствуется что трудно читать код с женериками и другими новыми для меня конструкциями языка типа восклицательного или вопросительного знака… наверное дело в привычке.
И не понял пока преимущества Result<res, err> над гошным res, err… ну кроме сахара в виде foo()?
Именно эта статья сподвигла меня попробовать Rust. Помню как первый раз GO учил. В принципе за спиной уже был php, java, js, python (c++ и C# помню только со времен учебы что-то).
Так вот, после прохождения tour.golang.org/welcome/1 я уже мог что то писать. Оно компилировалось и работало. А если не работало — то компилятор говорил что не так. Язык примитивный и все ограничивалось банальной правкой типов и т.д.
И вот я день прот… хался с Rust. Это ад какой-то. Да, Hello World с божей помощь скомпилировался. Дай думаю забабахаю простенький ендпоинт который будет принимать айдишник и брать доку с монги. Ошибки компилятора — напомнили с++ где читаешь ошибки и хрен знаешь как ее чинить… Столько всего нужно писать — макросы, импорты, неймспейсы… потом конфликты библиотек прилетели…
В интернете нет ни одного нормально рабочего примера. Могу ошибаться, но как я понял язык настолько быстро ломает свои контракты что большинство информации просто устаревает слишком быстро. А разработчики библиотек не успевают выпускать новые версии.
В общем, как я понял с ходу этот язык не осилить. Попробую прочитать книжку, хотя я уверен она уже устарела… Если осилю, попробую дать еще один шанс этому языку…
Да дело даже не в хорошем или плохом коде. Со временем когда mvp или poc взлетел, код будет изменяться с огромной скорость. Через годик-два, если это не статический язык, добавление строчки кода будет опаснее коронавируса =)) И что бы каждый раз не какать в штаны при деплое, будут писаться тесты на самые элементарные вещи, но это не всегда будет помогать. Люди будут передавать инлайн обьекты, попутно добавляя и убирая фиелды… ты будешь смотреть на код и не понимать с какими структурами данных ты работаешь, потому что их нет. Люди будут делать волшебные вещи которые язык делать позволяет.
Рефактор? Это ад. Дай мне программу на го, удали часть когда, я его восстановлю и починю только глядя на ошибки компайлера.
Главный посыл — в шорт-терм, динамические языки рулят. Лонг-терм, поддержка и добавление изменений это сущий ад, и дальнейшее развитие продукта будет замедленно.
з.ы.
Вне веба, имхо немного другие критерии. Например обработку текста и матриц делать на го или жаве, то еще удовольствие… а вот на пайтоне — рай для души.
Я уже давно перестал влезать в эти разборки. Для меня важнее что бы человек понимал, что на питоне, жаваскрипте и т.п. он напишет и поднимет сервис быстрее чем не той же жаве или даже го, и кода меньше будет в разы… но когда ему придется это код поддерживать и рефакторить, особенно когда по нему прошлись десятки разработчиков — да поможет ему бог.
Не нравится мне идея разбрасывания SQL-ки по файлам… почему вообще контроллер должен знать (хоть и косвенно теперь через QueryFilter о том что тут присутствует SQL?
Всегда хватало простого Separation of concerns
Controller — тупой, и тупо получает запрос
RequestModel/FormModel/SearchModel (называйте как хотите) — инкапсулирует данные запроса
ServiceLayer — получает нужные зависимости и данные запроса. Вся движуха в плане бизнес логики делается тут и далее использует DAL.
DAL (Repository, DAO) — там уже строим нужную SQL-ку… хоть чистый хоть орм-ный… в одном месте.
Ошибка № 4. Не использовать Promise.all()
Если у Вас есть несколько не зависящих друг от друга промисов, Вы можете выполнить их одновременно.
IMHO тут важно новичку обьяснить что значит «не зависящих друг от друга промисов». С потолка беру пример, но сталкивался похожей ситуацией.
Ну вот пришел новичек, видит 2 функции (с):
1. downloadFile(fileURL) — скачивает файлы, долго…
2. findUserById(userId) — находит юзера в базе, сравнительно быстро
3. someFoo(file, userId)
По бизнесу, мне не нужен юзер что бы скачать файл, и юзеру тоже пофиг на файл. Это важно только для someFoo()
Новичек запихивает это все в PromiseAll. И вроде все правильно, две функции не зависят друг от друга. Работает быстрее.
Но, я встречал людей которые не понимают что если зафейлится findUserById(), функция downloadFile() не отменяется… и продолжает работать.
В итоге, когда все хороше — да, быстрее. Но когда случаются ошибки… мемори лик, пустая трата ресурсов.
Попадался код который ну просто везде юзает Promise.all. Понимает ли новичек что все это не бесплатно, и что в конце концов это все равно пойдет в очередь, и не важно на каком уровне? Нода, нетворк… в итоге вся система страдает, вместо того что бы иметь несколько пускай не очень быстрых мест.
Возможно это только мой опыт, но когда перешел в мир жаваскрипта из PHP/Python/Java/Go, очень тяжело объяснять разработчикам зачем нужен DI (я не имею ввиду фреймворк, я имею ввиду чистый ручно инжекшен зависимостей). Ну привыкли они делать require() и все работает. Тесты? Привет rewire, proxyquire и другим костылям… которые тоже не со всем справляются когда весь проект выглядит как клубок из require(), имеются cycle dependencies и код выполняется прямо после вызова require(), а не когда Я как разработчик захочу…
А когда количество тестов растет и они начинают падать непонятно почему (понятно, где то что то замокалось один раз и все, потому что референс на функцию зарезолвился при require(), потому что никто не понимает что тесты бегут в одном процессе...), когда что бы протестировать хоть что то нужно делать танцы с бубном… я начинаю плакать Ж(
Как же все таки приятно работать когда я могу заинжектить то что мне надо, даже не используя сторонних библиотек…
У меня есть теория, что если человеку не приходилось заниматься сексом с огромным количеством тестов, ему трудно понять преимущества этого подхода…
Жаль что нет какой то синхронизации релизов между bcc и bpftrace. На данный момент если вы попытаетесь собрать из мастера bcc/bpftrace, последний не соберется: github.com/iovisor/bpftrace/issues/453
Пришлось билдить bcc с предидущего коммита. Но даже после этого не убунте не все тулзы работают :/ Пока не разобрался почему…
Буквально месяц торчу там уже. Пока доволен. Но вот чат выпилили как я понял. Во всяком случаем в приложенни для ios я его не вижу. Жаль конечно, но радует то что их система реально заставляет запоминать слова и предложения как на слух так и через зрительную память. Я обычно не верю во все эти фокусы но щас сам удивился.
Пробовал еще lingualeo, даже за премиум заплатил. Только вот у них баг какой-то. Деньги снялись а премиум не включился. Послал мейл, пока тишина.
Когда то тоже писял кипятком от скорости NODE.js в случаях когда сервер должен выдержать десятки тысяч реквестов на API который в принципе ничего сложного не делает кроме как выплюнуть малюсенький json. После написания нескольких проектов, которые немного сложнее чем тысячи трехстрочных примеров в интернете, типа идем в базу, берем что-то и выплевываем JSON, я очень надеюсь что когда-нибудь это какашка (nodejs) умрет.
Как только в приложении появляется бизнес логика (привет коллбэкам), как только с данными нужно проводить операции которые занимают процессорное время (привет однопоточности) а не только асинхронный io, начинаются пляски с промисами, асинк и т.д. (асинк эвэйт из той же серии) и разработка превращается в ад и Израиль.
Не ведитесь на цифры, они далеко не фактор. Я уже не говорю о нормальных разработчиках которые реально понимают разницу между Parallel vs Concurrent.
Я все еще пишу на ноде, но очень маленькие прототипы с минимум логики, микросервисы можно сказать. Когда нужно писать что нибудь серьезное, понимаешь что тебе не хватает управления твоей же программой. Хочется самому решать в каком потоке и что запускать, синхронизировать, и т.д. Хочется писать нормальный синхронный код и не тратить время на понимание каши которую сам же и написал 5 минут назад, и строить в голове граф из колббэков, прромисов и т.д.
В тоже время PHP я вообще не использую для написания миркосервисов (ну не его это ниша). Если программеры нормальные, PHP это отличное решение для быстрой веб-разработки, особенно для стартапов. Масштабируется PHP тоже очень хороше. А то что работает медленно, можно вынести в микросервис.
И вот тут у меня большие надежды на GO. Писать микросервисы одно удовольствие. GO дает достаточно высокоуровневого API, и в тоже время. у программиста есть возможность использовать низкоуровневые плюшки (мьютексы и т.д.).
P. S.
На неделе исправил баг в системе, когда CRM умирал (LAMP стэк). После рисерча, нашелся код, от одного разраба который работал в компании в 2015 году. Там было (это я еще почистил от мусора):
//Задача — найти все депозиты конкретного клиента
function findUserDeposits($user_id)
{
$deposits = $this->getAllDepositsFromDatabase(); // SELECT * FROM transactions
$transactions = $this->deepCopy($deposits); // deep copy of $deposits array data to new array with array key as row id from database
$results = [];
foreach ($transactions as $transaction) {
if (('' . ($transaction['user_id'])) !== ('' . $user_id)) {
continue;
}
$id = $transaction['id'];
$result[$id] = $transaction;
}
return $results;
}
Не трудно догадаться почему все умерло… Когда я это увидел у меня скатилась слеза…
Что-то мне подсказывает, дай этому разрабу вместо php, какой-нибудь С или JAVA, ничего бы не изменилось. А вой дай ему NODEJS с коллбэками, то я даже представить не могу что бы он там наколбасил. А вы тут микросекунды считаете. Я сам как инженер люблю цифры, но вот пришел к понимаю того, что это далеко не главное, во всяком случае не там где эти цифры нам показывают в тестах.
Вот померять скорость обработки изображения например — тут реально есть что мерять и сравнить разные тулзы и языки. А взять с базы, выплюнуть JSON или html страничку, и замерять это — вот уже действительно трата времени.
Дв даже если его разбросать по ту мач абстракциям, вреда будет в разы меньше… как минимум можно будет протестировать абстракции.
Мы как в том анекдоте, едим кактус и плачем. Ооочень медленно вводим абстракции вида
1. Validation layer (валидаци? какая валидация? =))
2. Thin Controller (сейчас это просто куча кода с колбек хелами)
3. Service Layer (отсутствует как класс. вся логика в контроллере)
4. DAO/Repository (сейчас монгуси прямо в контроллерах)
5. Mappers (работаем с внешними апишками)
6. Resources (http clients)
Да, файлов много. Но уже не так потеешь когда открываешь контроллер. И этих файлов будет еще больше. Но альтернатива в виде огромных функций это ад…
Ну и нужно понимать, абстракции потекут если их не поддерживать… и превратятся в гомно, кучу кода с ифами… я думаю все мы это проходили =))
з.ы.
Естественно мы не пытаемся впихнуть невпихуемое типа абстрактной фабрики и т.д. Да и 80% разработчиков и не слышали о них, может это и к лучшему =))
з.ы.
И да, стараемся переписать на микро-сервисы… сложность убегать на уровень выше…
Но я когда работал на себя, и я помню как тяжело заставить себя работать дома. Холодильник, телевизор, балкончик с пепельницей… все это отвлекает. А сейчас работая в стартапе, понимаешь что возможность зайти в соседнюю дверь к девопсам попросить че нить, или сделать смол толк на кухне по поводы какой-то кривой фичи, и много других «мелочей» типа нескольких мониторов, стабильная сеть и т.д. реально влияют на мое КПД.
Хотя бывают дни когда тебя интерраптят по поводу и без повода, что реально хочется закрыться где нить с наушниками и тупо часами писать код.
Так как в кампании большинство программистов с других городов, я думаю приезжать в офис и работать одному, но в офисе. Психологически легче настраиваться на работу :/ Но если запретят вообще, придется с дома работать, и я чувствую что я буду тратить больше время на работу чем работая в офисе :/
Как-то так…
з.ы.
И это я холостяк. У кого дети дома, уже плачут горькими слезами =)))
Не зря кто-то потратил свое время на написание вот этого — blog.burntsushi.net/rust-error-handling
Пройдет ли с практикой чувство того что ты не читаешь код а расшифровываешь?
То есть если в го (жава и т.д) мне что б понять если может прилететь nil, мне нужно просмотреть код… и найти того кто вместо *something может мне кинуть nil, то в Rust я это вижу явно, что не дает мне возможности пропустить хендлинг этого случая?
Значит если функция вернула ошибку, у меня нет доступа к результату. А если отработала нормально, есть ли гарантия что там не NULL? (None)
Вот что я люблю в ГО, так это то, что тесты рядом с файликами есть даже в стандартной библиотеке. А так как язык простой, то и тесты и сорсы читаются на отлично…
Нашел неплохие лекции по Rust: www.youtube.com/watch?v=Oy_VYovfWyo&list=PLlb7e2G7aSpTfhiECYNI2EZ1uAluUqE_e
Пока 2 просмотрел. Столько нюансов и подводных камней… реально нужно понимать как компилятор работает что бы писать нормально. На порядок сложнее GO.
А вообще последние 2 года только на Node.js пишу (работаю с стартапе). И если на GO я еще могу пописать для себя, или тулзу запилить на работе just for fun, то с Rust чувствуется что трудно читать код с женериками и другими новыми для меня конструкциями языка типа восклицательного или вопросительного знака… наверное дело в привычке.
И не понял пока преимущества Result<res, err> над гошным res, err… ну кроме сахара в виде foo()?
Продолжаю исследование =)
Так вот, после прохождения tour.golang.org/welcome/1 я уже мог что то писать. Оно компилировалось и работало. А если не работало — то компилятор говорил что не так. Язык примитивный и все ограничивалось банальной правкой типов и т.д.
И вот я день прот… хался с Rust. Это ад какой-то. Да, Hello World с божей помощь скомпилировался. Дай думаю забабахаю простенький ендпоинт который будет принимать айдишник и брать доку с монги. Ошибки компилятора — напомнили с++ где читаешь ошибки и хрен знаешь как ее чинить… Столько всего нужно писать — макросы, импорты, неймспейсы… потом конфликты библиотек прилетели…
В интернете нет ни одного нормально рабочего примера. Могу ошибаться, но как я понял язык настолько быстро ломает свои контракты что большинство информации просто устаревает слишком быстро. А разработчики библиотек не успевают выпускать новые версии.
В общем, как я понял с ходу этот язык не осилить. Попробую прочитать книжку, хотя я уверен она уже устарела… Если осилю, попробую дать еще один шанс этому языку…
А жаль, так хотелось поиграться :(
Рефактор? Это ад. Дай мне программу на го, удали часть когда, я его восстановлю и починю только глядя на ошибки компайлера.
Главный посыл — в шорт-терм, динамические языки рулят. Лонг-терм, поддержка и добавление изменений это сущий ад, и дальнейшее развитие продукта будет замедленно.
з.ы.
Вне веба, имхо немного другие критерии. Например обработку текста и матриц делать на го или жаве, то еще удовольствие… а вот на пайтоне — рай для души.
Всегда хватало простого Separation of concerns
Controller — тупой, и тупо получает запрос
RequestModel/FormModel/SearchModel (называйте как хотите) — инкапсулирует данные запроса
ServiceLayer — получает нужные зависимости и данные запроса. Вся движуха в плане бизнес логики делается тут и далее использует DAL.
DAL (Repository, DAO) — там уже строим нужную SQL-ку… хоть чистый хоть орм-ный… в одном месте.
IMHO тут важно новичку обьяснить что значит «не зависящих друг от друга промисов». С потолка беру пример, но сталкивался похожей ситуацией.
Ну вот пришел новичек, видит 2 функции (с):
1. downloadFile(fileURL) — скачивает файлы, долго…
2. findUserById(userId) — находит юзера в базе, сравнительно быстро
3. someFoo(file, userId)
По бизнесу, мне не нужен юзер что бы скачать файл, и юзеру тоже пофиг на файл. Это важно только для someFoo()
Новичек запихивает это все в PromiseAll. И вроде все правильно, две функции не зависят друг от друга. Работает быстрее.
Но, я встречал людей которые не понимают что если зафейлится findUserById(), функция downloadFile() не отменяется… и продолжает работать.
В итоге, когда все хороше — да, быстрее. Но когда случаются ошибки… мемори лик, пустая трата ресурсов.
Попадался код который ну просто везде юзает Promise.all. Понимает ли новичек что все это не бесплатно, и что в конце концов это все равно пойдет в очередь, и не важно на каком уровне? Нода, нетворк… в итоге вся система страдает, вместо того что бы иметь несколько пускай не очень быстрых мест.
Поправьте если я не прав…
А когда количество тестов растет и они начинают падать непонятно почему (понятно, где то что то замокалось один раз и все, потому что референс на функцию зарезолвился при require(), потому что никто не понимает что тесты бегут в одном процессе...), когда что бы протестировать хоть что то нужно делать танцы с бубном… я начинаю плакать Ж(
Как же все таки приятно работать когда я могу заинжектить то что мне надо, даже не используя сторонних библиотек…
У меня есть теория, что если человеку не приходилось заниматься сексом с огромным количеством тестов, ему трудно понять преимущества этого подхода…
Ошибки еще есть но исправляюсь =)
Уже на 599 уроке.
Пришлось билдить bcc с предидущего коммита. Но даже после этого не убунте не все тулзы работают :/ Пока не разобрался почему…
Пробовал еще lingualeo, даже за премиум заплатил. Только вот у них баг какой-то. Деньги снялись а премиум не включился. Послал мейл, пока тишина.
Нравится аппликация и то что присутствует социальный элемент. Жаль нет живого общения.
Как только в приложении появляется бизнес логика (привет коллбэкам), как только с данными нужно проводить операции которые занимают процессорное время (привет однопоточности) а не только асинхронный io, начинаются пляски с промисами, асинк и т.д. (асинк эвэйт из той же серии) и разработка превращается в ад и Израиль.
Не ведитесь на цифры, они далеко не фактор. Я уже не говорю о нормальных разработчиках которые реально понимают разницу между Parallel vs Concurrent.
Я все еще пишу на ноде, но очень маленькие прототипы с минимум логики, микросервисы можно сказать. Когда нужно писать что нибудь серьезное, понимаешь что тебе не хватает управления твоей же программой. Хочется самому решать в каком потоке и что запускать, синхронизировать, и т.д. Хочется писать нормальный синхронный код и не тратить время на понимание каши которую сам же и написал 5 минут назад, и строить в голове граф из колббэков, прромисов и т.д.
В тоже время PHP я вообще не использую для написания миркосервисов (ну не его это ниша). Если программеры нормальные, PHP это отличное решение для быстрой веб-разработки, особенно для стартапов. Масштабируется PHP тоже очень хороше. А то что работает медленно, можно вынести в микросервис.
И вот тут у меня большие надежды на GO. Писать микросервисы одно удовольствие. GO дает достаточно высокоуровневого API, и в тоже время. у программиста есть возможность использовать низкоуровневые плюшки (мьютексы и т.д.).
P. S.
На неделе исправил баг в системе, когда CRM умирал (LAMP стэк). После рисерча, нашелся код, от одного разраба который работал в компании в 2015 году. Там было (это я еще почистил от мусора):
//Задача — найти все депозиты конкретного клиента
Не трудно догадаться почему все умерло… Когда я это увидел у меня скатилась слеза…
Что-то мне подсказывает, дай этому разрабу вместо php, какой-нибудь С или JAVA, ничего бы не изменилось. А вой дай ему NODEJS с коллбэками, то я даже представить не могу что бы он там наколбасил. А вы тут микросекунды считаете. Я сам как инженер люблю цифры, но вот пришел к понимаю того, что это далеко не главное, во всяком случае не там где эти цифры нам показывают в тестах.
Вот померять скорость обработки изображения например — тут реально есть что мерять и сравнить разные тулзы и языки. А взять с базы, выплюнуть JSON или html страничку, и замерять это — вот уже действительно трата времени.