Angular2+: Почему нельзя обойтись без dependency injection?
Стандартный пример внедрения зависимостей выглядит так:
import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app', providers: [ HttpClient ], templateUrl: './app.component.html' }) export class AppComponent implements OnInit { constructor( private http: HttpClient ) {} getData(){ return this.http.get('/url'); } Зачем такое усложнение, если достаточно одних ES6-модулей? Особенно это касается внедрения сервисов, которые представляют сообой, по-сути, объекты с методами или функции? import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { getData(){ return HttpClient.get('/url'); //в крайнем случае new HttpClient().get('/url'); } |
|
Да знаю я всё это, читал. И ангуляровскую доку читал и статьи. Не нужно сыпать абстракциями, интересно практическое применение. Сейчас я не вижу разницы, если вместо DI использовать только es6-модули (каждый из которых синглтон), ну или делать экземпляр, если нужно. Зачем нужен DI, если стандартными средствами можно делать то же самое, только короче и проще?
Реальные примеры, пожалуйста, где одними модулями не обойтись |
Shitbox2,
Предположим у вас будет какой-то сервис, в котором будет порядка 100 запросов и логика обработки ответов. Теперь нам нужно протестировать его. Вручную - скучно. Будем писать автоматически запускаемые юнит тесты. Так, есть. В случае, который предлагаете вы, при каждом запуске тестов будет происходить 100 запросов на сервер, а это нагрузка, это время. Хорошо получается? В случае DI вместо HttpClient я могу передать backend заглушку, которая будет отдавать заранее подготовленные данные и тестировать именно логику обработки ответов. |
destus, ну так, тут то же самое. У нас есть
import { HttpClient } from '@angular/common/http'; Или рассмотрим для простоты commonJs модуль const { HttpClient } = require('@angular/common/http'); Кто мешает тестовому фреймворку подменить зависимость здесь? Постоянно делаю так в node.js. Уверен и для es6 есть решения. |
Как бы вам сказать, чтобы вас не расстроить :)
На мой взгляд Angular 2+ -- это преимущественно оверхед. Разработчика обязывают писать много кода просто потому, что ребята которые проектировали ангуляр считают это лучшим выбором. Когда еще второй ангуляр был в альфе, я понял что с ним работать не буду :D Я же не мазохист) Разве что денег много предложат. Вообщем, "удачи вам там. Вы там держитесь" :) |
Цитата:
Цитата:
|
nerv_,
Солидарен абсолютно. Такое же отношение и так же считаю, что они пошли куда-то не в ту сторону. Для меня они до сих пор в альфе: у них интерсепторы нормальные в http-сервисе пару недель назад появились и куча другого не доделано, что давно было в первой версии. Тем не менее альтернативы-то нет :-( Остальные либо такие же переусложненные фреймворки, либо библиотеки типа Реакта, где кучу всего самому пилить надо (с этим вдоволь намучился). Ну vue.js... Но пока не особо радует. В Ангуляре сейчас неплохое ядро и расширяемость. Сообщество большое, не глупое. Пишутся неплохие плагины. Думаю, написать к основным сервисам адаптеры и придумать как обойти весь этот оверхед. Главное это упростить DI, чтобы им могли пользоваться js-джуниоры, а не только java-синьоры и ООП-задроты. destus , Это не странное переопределение импортов, это стандартная практика. Большинство тех, кто пишет на Реакте и проч. не пользуются DI-библиотеками. В npm куча пакетов типа mock-require, которыми подменяешь зависимости. По опыту скажу, что это даже проще чем делать моки для первого Ангуляра (со вторым не пробовал еще). DI во втором Ангуляре это не одна строчка кода (дело тут совсем не в строчках), а три места, где нужно не забыть написать код, если хочешь подключить сервис: импорт, массив провайдеров и конструктор. Причем, зачем все зависимости экспортить в this класса в уме не приложу. Так что все мои вопросы сейчас направлены на то, чтобы понять как упростить систему или увидеть преимущества существующего подхода (реальные, практические, а не соответствие каким-то абстрактным ООП канонам) |
Цитата:
Более лучший вариант -- это использовать spy. // наш сервис export class Service { getData() { return new HttpClient().get('/url'); } handleResponse(res: HttpResponse) { // как-то обрабатываем ответ } makeRequest() { this.getData().map(this.handleResponse.bind(this)).subscribe() } } // тесты it('blabla', () => { const service = new Service(); spyOn(service, 'getData').and.returnValue(Observable.of(['Test1', 'Test2'])) }) Но использовать MockBackend заглушку лучше, потому что я могу протестировать своё апи с правильными параметрами, по правильному адресу и т.д. А шпионов обычно используют когда тестируют контроллер, и вместо вызова метода сервиса, возвращают заранее подготовленные данные и смотрят как эти данные, например, отрисовываются в DOM. Цитата:
|
Цитата:
|
Часовой пояс GMT +3, время: 08:24. |