Если кто хочет предыдущий пост в академическом виде https://youtu.be/9JUY3prnCQ4
YouTube
Мономорфный и полиморфный код, инлайн-кэш, скрытые классы в JavaScript
Примеры: https://github.com/HowProgrammingWorks/Monomorphism
Структура курса: https://github.com/HowProgrammingWorks/Index/blob/master/IP9X.md
Структура курса: https://github.com/HowProgrammingWorks/Index/blob/master/IP9X.md
❤9👍4🔥4
Forwarded from HowProgrammingWorks - JavaScript and Node.js Programming
💡 Начиная Chrome 119 и Node.js 22 у нас есть
Для чего оно нужно? Представьте, что у нас есть какое-то callback-returning API или EventEmitter/EventTarget или другие абстракции, поведения которых нужно подождать. И вот нужно сделать адаптер, обертку с внешним Promise-returning интерфейсом.
Пример:
Раньше это могло выглядеть так:
Или так:
Но теперь withResolvers позволяют это написать проще
‣ Значит ли это, что иначе писать уже плохо?
Это достаточно редкая и специфическая штука, ее нужно использовать в библиотеках и коде платформ с надеждой на то, что движки будут это как-то дополнительно оптимизировать, а в продуктовом коде нет на вас вины, если пишете по старинке.
‣ Значит ли это, что оно всем нужно?
Нет, но если знаете, это плюс.
Promise.withResolvers();
Для чего оно нужно? Представьте, что у нас есть какое-то callback-returning API или EventEmitter/EventTarget или другие абстракции, поведения которых нужно подождать. И вот нужно сделать адаптер, обертку с внешним Promise-returning интерфейсом.
Пример:
const sumAsync = (a, b, callback) => {
if (typeof a !== 'number') return;
if (typeof b !== 'number') return;
setImmediate(() => {
callback(a + b);
});
};
Раньше это могло выглядеть так:
let resolve, reject;
const promise = new Promise((resolved, rejected) => {
resolve = resolved;
reject = rejected;
});
setTimeout(reject, 1000, new Error('Timed out'));
sumAsync(2, 3, resolve);
const result = await promise;
console.log({ result });
Или так:
const promise = new Promise((resolve, reject) => {
sumAsync(4, 5, resolve);
setTimeout(reject, 1000, new Error('Timed out'));
});
const result = await promise;
console.log({ result });
Но теперь withResolvers позволяют это написать проще
const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(reject, 1000, new Error('Timed out'));
sumAsync(6, 7, resolve);
const result = await promise;
console.log({ result });
‣ Значит ли это, что иначе писать уже плохо?
Это достаточно редкая и специфическая штука, ее нужно использовать в библиотеках и коде платформ с надеждой на то, что движки будут это как-то дополнительно оптимизировать, а в продуктовом коде нет на вас вины, если пишете по старинке.
‣ Значит ли это, что оно всем нужно?
Нет, но если знаете, это плюс.
👍14🔥7
🧩 Пока я готовлю курс по паттернам GoF, SOLID, GRASP с адаптацией для Node.js и JavaScript, собрал тут ссылки на все старые материалы, видео, примеры кода, задачи, если по ссылке github репозиторий, то часто там и примеры и видео: https://github.com/tshemsedinov/Patterns-JavaScript
🔥18👍9❤3
Почему нужно избегать union-тайпов?
1. Каждый раз, когда юнион куда-то приходит аргументом, нужно делать if, чтобы понимать, как с ним работать, кроме случая, когда все классы/типы, входящие в юнион имплементируют один и тот же интерфейс и нас интересует обращение именно через этот интерфейс, зачем тогда юнион, используйте этот интерфейс вместо него, ну если в юнион не входит undefined, null, unknown и т.д.
2. Юнионы приводят к мегаморфной форме обращения к объектам в V8, и это замедляет код, не сметртельно, но это неприятно и проще всего всего забыть их. Но для чего же они тогда вообще нужны? Для совместимости с JS, если в нем можно передать что-угодно аргуметом, то это нужно меть возможность как-то выразить. Это не значит, что это хорошо и так нужно писать кода, это добавили как возможность, а не как обязанность )
3. Это часто ведет к нарушению SOLID:SRP (принципа единственной отвественности), потому, что как может метод, например, получать сокеты или таймеры на выбор и делать разные вещи в зависимости от этого, это же маразм, нарушает SOLID:LSP (принцип подстановки), иногда нарушает GRASP:InformationExpert, явно повышает Coupling.
Вместо этого нужно всегда использовать маленькие интерфейсы, заточенные под узкую задачу, помним про SOLID:ISP (принцип разделения интерфейсов) и могут быть optional аргументы, для этого не нужно делать union с null.
1. Каждый раз, когда юнион куда-то приходит аргументом, нужно делать if, чтобы понимать, как с ним работать, кроме случая, когда все классы/типы, входящие в юнион имплементируют один и тот же интерфейс и нас интересует обращение именно через этот интерфейс, зачем тогда юнион, используйте этот интерфейс вместо него, ну если в юнион не входит undefined, null, unknown и т.д.
2. Юнионы приводят к мегаморфной форме обращения к объектам в V8, и это замедляет код, не сметртельно, но это неприятно и проще всего всего забыть их. Но для чего же они тогда вообще нужны? Для совместимости с JS, если в нем можно передать что-угодно аргуметом, то это нужно меть возможность как-то выразить. Это не значит, что это хорошо и так нужно писать кода, это добавили как возможность, а не как обязанность )
3. Это часто ведет к нарушению SOLID:SRP (принципа единственной отвественности), потому, что как может метод, например, получать сокеты или таймеры на выбор и делать разные вещи в зависимости от этого, это же маразм, нарушает SOLID:LSP (принцип подстановки), иногда нарушает GRASP:InformationExpert, явно повышает Coupling.
Вместо этого нужно всегда использовать маленькие интерфейсы, заточенные под узкую задачу, помним про SOLID:ISP (принцип разделения интерфейсов) и могут быть optional аргументы, для этого не нужно делать union с null.
👍8❤4🔥2🤯2
✅ План стримов по паттернам:
08 августа - четверг - ITBeard
09 августа - пятница - Деми Мурыч
10 августа - суббота - Илья Климов
08 августа - четверг - ITBeard
09 августа - пятница - Деми Мурыч
10 августа - суббота - Илья Климов
❤25🎉7🔥6👍2
В субботу будет мастер-класс «Middle to Senior in 2024» в 15.00 (GMT+3) 👉 https://t.me/JavaScriptPatternsBot?start=TIMUR
👍24❤8🔥3
⭐️ Менеджмент — это лженаука об управлении. А наука об управлении называется кибернетика.
⭐️ Парадигмы программирования, кроме процедурной — это пока еще так... игрушечки и эксперименты. Весь существенный софт написан процедурно.
⭐️ Если вы приличный человек, у вас успешный продукт, большая команда и кодовая база — то вам очень стыдно за код проекта.
⭐️ Секта антисектантов «осознанность»
⭐️ Появилось предположение, что Jira и прочий треш-софт придумали для того, чтобы оправдать найм непрограммистов и заполнить их рабочее время хоть чем-то работоподобным, кроме бесконечных созвонов.
⭐️ Чем заменить конфлюенс? Он прекрасно заменяется отсутствием конфлюенса.
⭐️ No-code advantages: no bugs, no problems, no tests needed, no git diff, no code review and fixes needed, perfect just after first release, no-code is compatible with serverless.
⭐️ Cloud naïve: PaaS — promise as a service
⭐️ Приходит Цекербрин к своим разработчикам и спрашивает: ну шо, когда уже наш фейсбук будет дописан окончательно?
⭐️ Любая достаточно развитая технология неотличима от Метархии.
⭐️ Парадигмы программирования, кроме процедурной — это пока еще так... игрушечки и эксперименты. Весь существенный софт написан процедурно.
⭐️ Если вы приличный человек, у вас успешный продукт, большая команда и кодовая база — то вам очень стыдно за код проекта.
⭐️ Секта антисектантов «осознанность»
⭐️ Появилось предположение, что Jira и прочий треш-софт придумали для того, чтобы оправдать найм непрограммистов и заполнить их рабочее время хоть чем-то работоподобным, кроме бесконечных созвонов.
⭐️ Чем заменить конфлюенс? Он прекрасно заменяется отсутствием конфлюенса.
⭐️ No-code advantages: no bugs, no problems, no tests needed, no git diff, no code review and fixes needed, perfect just after first release, no-code is compatible with serverless.
⭐️ Cloud naïve: PaaS — promise as a service
⭐️ Приходит Цекербрин к своим разработчикам и спрашивает: ну шо, когда уже наш фейсбук будет дописан окончательно?
⭐️ Любая достаточно развитая технология неотличима от Метархии.
🤣34👍14❤9💩1
Кто еще не смотрел стрим про связь профессионального роста и паттернов, то готовьтесь, там больше 7 часов, и главное — все по делу, про то, как и чему учиться и про важность культуры, которая проникает через паттерны https://www.youtube.com/watch?v=QzxklJW4_LM
YouTube
🧩 Самые полезные знания для роста — Переосмысление паттернов для JavaScript, TypeScript, Node.js
👉 Следующий стрим: https://youtube.com/live/tpY01TLctAs
👉 Регистрация на курс: https://nodeua.com/Patterns-2024-buy.html
👉 Github автора: https://github.com/tshemsedinov
👉 Примеры кода по адаптерам из стрима: https://github.com/HowProgrammingWorks/Ad…
👉 Регистрация на курс: https://nodeua.com/Patterns-2024-buy.html
👉 Github автора: https://github.com/tshemsedinov
👉 Примеры кода по адаптерам из стрима: https://github.com/HowProgrammingWorks/Ad…
👍11🔥6❤5🤯2
Открыта предварительная регистрация на курс Patterns 2024 — я уже изучил всю доступную литературу и конкурентов и теперь уверен — аналогов нет, ни кто так и не смог сделать приличной адаптации паттернов к JavaScript, TypeScript, Async, Node.js миру — https://nodeua.com/Patterns-2024-buy.html
👍12🔥3❤2
1 сентября: понятный и красивый код может появляться только из стремления использовать его для образовательных целей. Если Вы видите понятный и красивый код, то будьте уверены, что или сам программист или его учитель выработали этот стиль для того, чтобы пояснить свою мысль. Ни стремление к производительности, ни бизнес-задачи, ни большой опыт не создают таких условий. Они могут порождать очень крутой код, сложный и даже надежный, но он в нем не будет человеко-ориентированности и эстетики.
❤20👍7🤯3🎉1
Вы наверняка видели код, в котором на событиях или на роутах висит обработчик, который содержит и часть бизнес-логики и обращение к базе и работу с сетью. Такой портянка-код характерен для чат-ботов и серверов. Как это можно написать иначе и как в этом помогают паттерны?
Нам нужно отделить три составляющих кода (грубо говоря, совсем упрощая): транспорт, бизнес-логику, базу. Но обеспечить между ними зацепление, минимальное необходимое. Лучше всего разнести их в три разные модуля (на это не обязательно), можно разнести в три разные программные компонента или в три разные абстракции. Одна обеспечивает работу с базой и ничего не знает о транспорте, а вторая - работу с транспортом и ничего не знает о базе. Дальше их должна сшивать общая абстракция (по принципу композиции, можно и агрегации). Какие паттерны тут помогут?
🧩 Mediator - снижает зацепление и подойдет нам для изоляции базы от транспорта.
🧩 Strategy - реализация стратегии для JavaScript это Map<PropertyKey, Implementation> что позволяет абстрагироваться от Implementation, находя его по ключу и работая по обобщенному интерфейсу.
🧩 Bridge - позволяет разделять абстракции и снижать зацепление, но не характерен для JavaScriot.
🧩 Abstract factory - для JavaScript абстрактная фабрика сводится к стратегии инстанциирования: Map<PropertyKey, Creator> и применяется как и стратегия, но в том месте, где нам нужно создавать инстансы (тут Creator это любой порождающий паттерн).
Признаки проблемы:
• Если вы не можете модифицировать работу с базой не трогая транспорт или бизнес-логику, не задевая базу, то нужно начинать внедрять разделение ответственности (separation of concerns).
• Если сложно написать юниттесты, а что-то протестировать можно только все целиком - ну вот оно, вы нашли проблему.
• Если код невозможно переиспользовать и вы чувствуете, что одно и то же пишете уже много раз.
Примеры на курсе по паттернам 👉 https://nodeua.com/Patterns-2024-buy.html
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤4🔥3🤯2