"dependency injection. javascript.", Сергей Камардин, moscowjs 15

28
Dependency Injection. Javascript. Сергей Камардин

Upload: moscowjs

Post on 09-Jun-2015

832 views

Category:

Software


0 download

DESCRIPTION

Слайды доклада "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

TRANSCRIPT

Page 1: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Dependency Injection. Javascript.

Сергей Камардин

Page 2: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Задача из жизни

1. Разместить на карте зарегистрированных пользователей;

!

2

Page 3: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

«JS Way»Locator.prototype.locateUsers = function(users) { // Инициалиация сервиса карт loadScript("..."); client.init(...); ! // Создание карты var map = new client.Map(...); ! // Отображение на карте маркеров users.forEach(...); }

3

Page 4: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Задача из жизни

1. Разместить на карте зарегистрированных пользователей;

2. Поменять поставщика карт;

4

Page 5: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Решение: АбстракцияAbstractMapService.prototype = { ! createMap: function() { throw new TypeError("Not implemented"); }, ! createMapMarker: function() { throw new TypeError("Not implemented"); } !}

5

Page 6: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

ИмплементацияAbstractMapService.extend({ ! createMap: function(id, options) { // }, ! createMapMarker: function(map, options) { // } !});

6

Page 7: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Locator.prototype.locateUsers = function(users) { // Create map service // Could be an Fabric Method, Service Locator, DI var mapService = new ConcreteMapService(...); ! // Create map var map = mapService.createMap(...); ! // Run each users, making markers users.forEach(...); }

7

Page 8: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Single responsibility?Locator.prototype.locateUsers = function(users) { // Create map service // Could be an Fabric Method, Service Locator, DI var mapService = new ConcreteMapService(...); ! // Create map var map = mapService.createMap(...); ! // Run each users, making markers users.forEach(...); }

8

Page 9: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Проблемы

• Невозможно написать юнит тесты;

• Использование сервиса карт во многих местах в коде;

• Избыточная функциональность локатора;

• Reusability.

9

Page 10: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Задача из жизни

1. Разместить на карте зарегистрированных пользователей;

2. Поменять поставщика карт;

3. Перенести локатор в другой проект, как плагин.

10

Page 11: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

ResultLocator.prototype = { // injection setMapService: function(mapService) { this.mapService = mapService; }, ! locateUsers: function(users) { // Create map var map = this.mapService.createMap(...); ! // Run each users, making markers users.forEach(...); } }

11

Page 12: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

12

Page 13: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

ResultLocator.prototype = { // injection setMapService: function(mapService) { this.mapService = mapService; }, ! locateUsers: function(users) { // Create map var map = this.mapService.createMap(...); ! // Run each users, making markers users.forEach(...); } }

13

Вот оно

Page 14: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Routine// Create MapService var mapService = new MapService(...); !// Create Locator var locator = new Locator(); !// Inject mapService locator.setMapService(mapService); !// Use locator locator.locateUsers(users);

14

Page 15: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Inversion of Control

• Dependency Injection

• Service Locator

• Factory Method

IoC container:

15

Page 16: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Dependency Injection

• Constructor injection

• Setter injection

• Interface injection

16

Page 17: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Hard Coupling

17

Page 18: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Coupling

18

Page 19: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Loose Coupling

19

Page 20: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Плюсы• Каждый объект отвечает за свою функцию;

• Соблюден принцип инверсии зависимостей;

• Простая конфигурация объектов;

• Безболезненная смена имплементаций;

• Легко писать юнит тесты.

20

Page 21: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

dm.js

• Javascript Реализация IoC;

• Работает в node.js и браузере;

• Легко расширяется (любые загрузчики скриптов и Promise/A+ библиотеки);

• Простая конфигурация (в духе Symfony).

21

Page 22: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Конфигурация "locator": { path: "path/to/locator/implementation", calls: [ ["setMapService", ["@maps"]] ] } "maps": { path: "path/to/map/service/implementation", arguments: [{ id: "my-app-id" }] }

22

Page 23: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Использование

dm .get("locator") .then(function(locator) { locator.locateUsers(users); });

23

Page 24: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Тестированиеit("should create map", function() { var mapStub, locator; ! mapMock = sinon .mock(new AbstractMapService) .expects("createMap") .once(); ! locator = new Locator(); locator.setMapService(mapMock); ! locator.locateUsers(...); ! mapMock.verify(); });

24

Page 25: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Syntax! "example": { "path": "...", "arguments": [{ "service": "@service", "method": "@service:method" "result": "@service:method[1,2,3]", "resource": "#path/to/my.tpl#", "path": "http://%{api_path}" "build": "build_no_#{file.txt}" }] } !

25

Page 26: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Альтернативы

• Wire.js

• Angular’s DI

• Тупо контейнеры

26

Page 27: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Где и для чего это можно использовать?

27

Page 28: "Dependency Injection. JavaScript.", Сергей Камардин, MoscowJS 15

Спасибо!

github.com/gobwas/[email protected]

Сергей Камардин