Полезная статья, но не согласен с некоторыми доводами.
А вот в JavaScript… ORM часто лишён смысла. Запрос к базе и так возвращает массив обычных объектов, а типизировать их в TypeScript можно простым as User[].
Это работает пока запросы относительно простые. Если запрос делает left join со связью 1:М, хочется иметь массив с объектами вида:
Тогда придется вручную мапить, избавляться от дубликатов юзеров и с типизацией разбираться. Согласен, что TypeORM перегружен, но тот же DrizzleORM в 2 раза легче и справляется на ура.
DI активно продвигается как «промышленный стандарт», главный аргумент — удобство тестирования: зависимости можно заменить моками.
Ну не только. DI отлично работает, когда у нас есть несколько сервисов, которым нужно задать одинаковый интерфейс. Например — платежки, которые можно реализовать в виде Стратегии и динамически инжектить.
Чтобы не создавать экземпляры вручную, подключают DI-контейнеры (Spring в Java, NestJS DI в JS). Это наглухо привязывает код к фреймворку, добавляет слои пустых абстракций, делая код неявным.
Вообще никто не заставляет тянуть целый фреймворк. У JS есть куча библиотек типа Awilix, которые не делают ничего, кроме добавления DI-контейнеров.
Многие современные фреймворки (Spring Web на Java, NEST и Fastify на JS) позволяют вообще ничего не оборачивать в try-catch — если исключение произойдёт, то фреймворк сам перехватит его, обернёт в объект ошибки и отправит в ответе.
Да, только не все ошибки мы хотим отдавать клиенту. В простых случаях, мы не будем отдавать исключение упавшего запроса к БД, а выкинем какой-нибудь 500 Internal Server Error, при этом записывая в логи проблемный запрос. В более сложных, сторонние сервисы могут отдавать десятки различных исключений, но пользователю мы хотим вернуть что-то общее, типа "Failed to send email" или "Data not found".
Типы никак не влияют на работоспособность кода. Они нужны для удобства разработчику. Если убрать все type и interface - на работу кода это никак не повлияет.
При запуске TypeScript Compiler типы удаляет, когда транспилит TS в JS
Это предложение в стандарт ECMAScript, т.е. речь тут про JS, а не TS. Касательно интерфейсов и типов, так это просто типизация. Composite - это самостоятельная структура
Спасибо за статью. Касательно реализации репозитория есть нюанс:
...
save(order: Order) {
this.storage[order['id']] = JSON.stringify(order);
}
findById(id: string): Order | null {
const data = this.storage[id];
return data ? JSON.parse(data) : null;
}
...
JSON не может иметь методов, потому JSON.stringify() не создаст точную копию объекта в строке. И потому обратная конвертация JSON.parse() по факту не является Order.
Вместо этого стоит на месте создавать Order из JSON'а:
findById(id: string): Order | null {
const data = this.storage[id];
return data ? new Order(JSON.parse(data)) : null;
}
Случай усложняется, если Order содержит структуры данных типа Map/Set, которых также нет в JSON. Тогда нужно будет заводить какой-то отдельный маппер
Задача 5 Тут еще стоит учитывать, что оставшийся сок в емкости на 17л нужно переливать обратно в 21л. Ну и последнему бегемоту можно налить сразу из бочки :)
Полезная статья, но не согласен с некоторыми доводами.
Это работает пока запросы относительно простые. Если запрос делает left join со связью 1:М, хочется иметь массив с объектами вида:
А квери билдеры вернут что-то такое:
Тогда придется вручную мапить, избавляться от дубликатов юзеров и с типизацией разбираться. Согласен, что TypeORM перегружен, но тот же DrizzleORM в 2 раза легче и справляется на ура.
Ну не только. DI отлично работает, когда у нас есть несколько сервисов, которым нужно задать одинаковый интерфейс. Например — платежки, которые можно реализовать в виде Стратегии и динамически инжектить.
Вообще никто не заставляет тянуть целый фреймворк. У JS есть куча библиотек типа Awilix, которые не делают ничего, кроме добавления DI-контейнеров.
Да, только не все ошибки мы хотим отдавать клиенту. В простых случаях, мы не будем отдавать исключение упавшего запроса к БД, а выкинем какой-нибудь 500 Internal Server Error, при этом записывая в логи проблемный запрос. В более сложных, сторонние сервисы могут отдавать десятки различных исключений, но пользователю мы хотим вернуть что-то общее, типа "Failed to send email" или "Data not found".
Типы никак не влияют на работоспособность кода. Они нужны для удобства разработчику. Если убрать все
typeиinterface- на работу кода это никак не повлияет.При запуске TypeScript Compiler типы удаляет, когда транспилит TS в JS
Это предложение в стандарт ECMAScript, т.е. речь тут про JS, а не TS.
Касательно интерфейсов и типов, так это просто типизация. Composite - это самостоятельная структура
Спасибо за статью. Касательно реализации репозитория есть нюанс:
JSON не может иметь методов, потому
JSON.stringify()не создаст точную копию объекта в строке. И потому обратная конвертацияJSON.parse()по факту не являетсяOrder.Вместо этого стоит на месте создавать
Orderиз JSON'а:Случай усложняется, если
Orderсодержит структуры данных типаMap/Set, которых также нет в JSON. Тогда нужно будет заводить какой-то отдельный маппер__proto__уже устарел, лучше использовать альтернативы - getPrototypeOf и setPrototypeOfЭтот пример корректен, но лишняя вложенность мозолит глаза
Спасибо за ваше мнение. А хабр тут причем?
Задача 5
Тут еще стоит учитывать, что оставшийся сок в емкости на 17л нужно переливать обратно в 21л. Ну и последнему бегемоту можно налить сразу из бочки :)
Пошаговое решение
За шаг взято одно переливание