Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 26.07.2017, 15:43
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 520

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');
  }
Ответить с цитированием
  #2 (permalink)  
Старый 26.07.2017, 15:48
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 867

Синглтон
Ответить с цитированием
  #3 (permalink)  
Старый 26.07.2017, 17:07
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 520

Да знаю я всё это, читал. И ангуляровскую доку читал и статьи. Не нужно сыпать абстракциями, интересно практическое применение. Сейчас я не вижу разницы, если вместо DI использовать только es6-модули (каждый из которых синглтон), ну или делать экземпляр, если нужно. Зачем нужен DI, если стандартными средствами можно делать то же самое, только короче и проще?

Реальные примеры, пожалуйста, где одними модулями не обойтись
Ответить с цитированием
  #4 (permalink)  
Старый 26.07.2017, 17:35
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 867

Shitbox2,
Предположим у вас будет какой-то сервис, в котором будет порядка 100 запросов и логика обработки ответов. Теперь нам нужно протестировать его. Вручную - скучно. Будем писать автоматически запускаемые юнит тесты. Так, есть. В случае, который предлагаете вы, при каждом запуске тестов будет происходить 100 запросов на сервер, а это нагрузка, это время. Хорошо получается? В случае DI вместо HttpClient я могу передать backend заглушку, которая будет отдавать заранее подготовленные данные и тестировать именно логику обработки ответов.
Ответить с цитированием
  #5 (permalink)  
Старый 26.07.2017, 18:04
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 520

destus, ну так, тут то же самое. У нас есть
import { HttpClient } from '@angular/common/http';

Или рассмотрим для простоты commonJs модуль
const { HttpClient } = require('@angular/common/http');

Кто мешает тестовому фреймворку подменить зависимость здесь? Постоянно делаю так в node.js. Уверен и для es6 есть решения.
Ответить с цитированием
  #6 (permalink)  
Старый 26.07.2017, 18:25
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,872

Как бы вам сказать, чтобы вас не расстроить

На мой взгляд Angular 2+ -- это преимущественно оверхед. Разработчика обязывают писать много кода просто потому, что ребята которые проектировали ангуляр считают это лучшим выбором.

Когда еще второй ангуляр был в альфе, я понял что с ним работать не буду Я же не мазохист) Разве что денег много предложат.

Вообщем, "удачи вам там. Вы там держитесь"
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #7 (permalink)  
Старый 26.07.2017, 18:34
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 867

Цитата:
Кто мешает тестовому фреймворку подменить зависимость здесь?
Пример будет? То есть у меня в коде будет написано, если запускаю на проде один импорт, если в тестах -- другой. В первом примере вы писали про "переусложнение", но реальность такова, что в случае DI нужно написать одну строчку кода (параметр конструктора). В вашем же случае, какое-то странное переопределение импортов, еще какие-то заморочки

Цитата:
Когда еще второй ангуляр был в альфе, я понял что с ним работать не буду
Ответить с цитированием
  #8 (permalink)  
Старый 26.07.2017, 22:26
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 520

nerv_,
Солидарен абсолютно. Такое же отношение и так же считаю, что они пошли куда-то не в ту сторону. Для меня они до сих пор в альфе: у них интерсепторы нормальные в http-сервисе пару недель назад появились и куча другого не доделано, что давно было в первой версии.

Тем не менее альтернативы-то нет :-( Остальные либо такие же переусложненные фреймворки, либо библиотеки типа Реакта, где кучу всего самому пилить надо (с этим вдоволь намучился). Ну vue.js... Но пока не особо радует. В Ангуляре сейчас неплохое ядро и расширяемость. Сообщество большое, не глупое. Пишутся неплохие плагины. Думаю, написать к основным сервисам адаптеры и придумать как обойти весь этот оверхед. Главное это упростить DI, чтобы им могли пользоваться js-джуниоры, а не только java-синьоры и ООП-задроты.


destus ,
Это не странное переопределение импортов, это стандартная практика. Большинство тех, кто пишет на Реакте и проч. не пользуются DI-библиотеками. В npm куча пакетов типа mock-require, которыми подменяешь зависимости. По опыту скажу, что это даже проще чем делать моки для первого Ангуляра (со вторым не пробовал еще). DI во втором Ангуляре это не одна строчка кода (дело тут совсем не в строчках), а три места, где нужно не забыть написать код, если хочешь подключить сервис: импорт, массив провайдеров и конструктор. Причем, зачем все зависимости экспортить в this класса в уме не приложу.

Так что все мои вопросы сейчас направлены на то, чтобы понять как упростить систему или увидеть преимущества существующего подхода (реальные, практические, а не соответствие каким-то абстрактным ООП канонам)
Ответить с цитированием
  #9 (permalink)  
Старый 26.07.2017, 22:59
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 3,455

Еще пара новых версий Ангуляра и им смогут пользоваться только сами его разработчики, я первую то не понял толком.
Ответить с цитированием
  #10 (permalink)  
Старый 27.07.2017, 08:45
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 867

Цитата:
В npm куча пакетов типа mock-require, которыми подменяешь зависимости. По опыту скажу, что это даже проще чем делать моки для первого Ангуляра (со вторым не пробовал еще).
Конкретно в данной ситуации, этот вариант -- худший из возможного, потому что он требует от разработчика собственной реализации класса HttpClient (чтобы в mockExports подменять экспорт модуля @angular/common/http). А так как будет подменяться весь экспорт модуля http на наш, то нам придется реализовывать не только класс HttpClient, но и остальные экспортируемые сущности, которых очень много.

Более лучший вариант -- это использовать 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.

Цитата:
DI во втором Ангуляре это не одна строчка кода (дело тут совсем не в строчках), а три места, где нужно не забыть написать код, если хочешь подключить сервис: импорт, массив провайдеров и конструктор.
Angular-cli решает проблему. Ну то есть просто в консоли пишем ng g service Blablabla и он сам расставит нужные импорты, запишет в провайдеры и т.д.

Последний раз редактировалось destus, 27.07.2017 в 08:48.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему можно использовать id элемента без использования getElementById? grifangel Общие вопросы Javascript 3 08.01.2014 20:20
можно ли обойтись без логического оператора НЕ macdack Общие вопросы Javascript 7 12.06.2013 20:16
Клик срабатывает без щелчка на кнопке - почему?.. deivan Events/DOM/Window 3 13.08.2012 13:42
почему нельзя объявить переменную и в ней использовать совмещенные операторы?!! alexben Общие вопросы Javascript 23 12.02.2012 23:32
Обойтись без <body onload=""> LRCenter Events/DOM/Window 3 06.02.2012 21:37