Inversion Of Control

Алексей Плуталов, Злые марсиане

Inversion Of Control in the wild frontend

Алексей Плуталов, Злые марсиане

martian.png

План

  1. Что такое IoC?
  2. Factory Method
  3. Service Locator
  4. Dependency Injection
  5. IoC Container
  6. IoC в Ember.js

Часть 1 Что такое IoC?

martian.png

Что такое IoC? Аксиома

Чем сложнее класс или компонент, тем меньше должно быть внешних связей.

Тед Фейсон, Event-Based Programming

Что такое IoC? Определение

Важный принцип используемый для уменьшения связанности кода

Что такое IoC? Способы реализации

Часть 2 Factory Method

martian.png

Factory Method Схема

factory.png

Factory Method Описание

Часть 3 Service Locator

martian.png

Service Locator Схема

service-locator.png

Service Locator Описание

Паттерн скрывающий процессы связанные с получением модуля с сильным уровнем абстракции

Реализуется в виде центрального реестра ресурсов, возвращающего нужную информацию по запросу

Service Locator Пример


var Connection = function () {
  this.logger = require("logger")();

  /* реализация логики */
}

Service Locator Достоинства

Service Locator Недостатки

Часть 4 Dependency Injection

martian.png

Dependency Injection Описание

Процесс предоставления внешней зависимости программному компоненту

Dependency Injection Пример Constructor Injection

// adapter      - клиент хранилища (например, REST)
// serializator - сериализатор данных
var Resource = function (adapter, serializator) {
  this.adapter      = adapter;
  this.serializator = serializator;
};

Dependency Injection Пример Setter Injection

var Resource = function ( ) { };
Resource.prototype.setAdapter = function (adapter) {
  this.adapter = adapter;
};
Resource.prototype.setSerializator = function (srl) {
  this.serializator = srl;
};

Dependency Injection Пример Interface Injection

var Injectable = function ( ) { };
Injectable.prototype.inject = function (name, dep) { };

var Resource = function ( ) { Injectable.apply(this); };
Resource.prototype.inject = function (name, dep) {
  this[name] = dep;
};

Dependency Injection Другой пример Interface Injection

Object.prototype.inject = function (name, dep) {
  this[name] = dep;
};

var resource = new Resource();
resource.inject(adapter, serializer);

Dependency Injection Достоинства

Dependency Injection Недостатки

Dependency Injection Пример jQuery



jQuery.fn.pluginName = function ( ) {
  this; // jQuery объект с выборкой элементов
};

Dependency Injection Пример Koa.js


app.use(function * ( ) {
  this;          // Koa Context
  this.request;  // Koa Request
  this.response; // Koa Response
});

Часть 5 IoC Container

martian.png

IoC Container Описание

Программный каркас реализующий DI, и упрощающий его использование

Многие фреймворки являются реализацией IoC-container

IoC Container Схема

container.png

Часть 6 IoC в Ember.js

martian.png

IoC в Ember.js IoC в Ember.js

Ember.js предоставляет IoC-container, и две реализации DI:

IoC в Ember.js Задачи IoC в Ember.js

IoC в Ember.js Пример Service Lookup


App.SessionController = Ember.Controller.extend({
  isSignedIn: false
});

App.IndexController = Ember.Controller.extend({
  needs: [ "session" ],
  isSignedIn: function ( ) {
    return this.get("controllers.session.isSignedIn");
  }.property("controllers.session.isSignedIn");
});

IoC в Ember.js Пример Service Lookup


App.SignInController = Ember.Controller.extend({
  needs: [ "session" ],
  isSignedIn: Ember.computed.alias("controllers.session.isSignedIn"),
  actions: {
    signIn: function ( ) {
      this.set("isSignedIn", true);
    }
  }
});

IoC в Ember.js Dependency Injection API

Использование DI в Ember.js сводится к двум методам:

IoC в Ember.js Регистрация синглтона

var Logger = Ember.Object.extend({
  write: function (msg) {
    console.log(msg);
  }
});

application.register("logger:console", Logger);

IoC в Ember.js Регистрация фабрики

var Logger = Ember.Object.extend({
  write: function (msg) {
    console.log(msg);
  }
});
application.register(
  "logger:console", Logger, { singleton: false }
);

IoC в Ember.js Регистрация инстанса


App.register("logger:console", function (msg) {
  console.log(msg);
}, {
  instantiate: false
});

IoC в Ember.js Инъекция зависимости

Ember.Application.initializer({
  name: "logger",
  initialize: function (container, application) {
    application.register("logger:console", function (msg) {
      console.log(msg);
    }, { instantiate: false });

    application.inject("route", "logger", "logger:console");
  }
});

App.create();

IoC в Ember.js Разрешение зависимости

App = Ember.Application.create({
  Resolver: Ember.DefaultResolver.extend({
    resolveTemplate: function (parsedName) {
      var resolvedTemplate = this._super(parsedName);

      if (resolvedTemplate) {
        return resolvedTemplate;
      }

      return JST[parsedName] || Ember.TEMPLATES["not_found"];
    }
  });
});

IoC в Ember.js Типы зависимостей

IoC в Ember.js Кастомизация Resolver

Кастомизацию разрешения зависимостей используют

IoC в Ember.js В итоге

Вопросы

evilmartians.png