深刻理解 Daze.js 之 IoC 容器原理

簡介

Daze.js 底層經過容器的模式設計,全部功能都是基於這個容器進行構建,經過容器,咱們能夠實現解耦、依賴注入等功能git

依賴

咱們建立一個普通的類github

class Example{
  // ...
}
複製代碼

而後再建立一個可能會被依賴的類函數

class Attr {
  constructor(attr1, attr2, attr3) {
    this.attr1 = attr1
    this.attr2 = attr2
    this.attr3 = attr3
  }
}
複製代碼

第一個類依賴了第二個類ui

class Example {
  constructor() {
    this.attr = new Attr(1, 2, 3)
  }
}
複製代碼

這種形式就是咱們最多見的模式,簡單的依賴關係,看起來也還ok,可是若是依賴多了呢?this

class Example {
  constructor() {
    this.attr1 = new Attr1()
    this.attr2 = new Attr2()
    // ...more
  }
}
複製代碼

咱們能夠看到,每次實例化 Example 的時候都須要實例化對應依賴的對象spa

爲了解決這個問題,有人就提出了工廠模式設計

工廠模式

爲了實現這個功能,咱們須要一個能夠實例化不一樣依賴的工廠code

class Factory {
  build(type) {
    switch(type) {
      case 'car':
        return new Car()
      case 'plane':
        return new Plane()
      default:
        return
    }
  }
}
複製代碼

有了這個工廠,咱們就能夠只修改工廠的種類就能夠自動實例化不一樣的依賴對象了對象

class Example {
  constructor(attrs) {
    const factory = new Factory()
    for (const attr of attrs) {
      factory.build(attr)
    }
  }
}

// 實例化依賴 Car 和 Plane 的類
const example1 = new Example(['car', 'plane'])
// 實例化依賴 Car 的類
const example2 = new Example(['car'])
複製代碼

依賴注入

咱們能夠看到,剛剛的工廠其實只是把多個依賴轉移到了對工廠的依賴,工廠內部仍是須要手動增長各類以來的生產線,如何解決這個問題呢,那就是依賴注入get

咱們改造一下Example的類

class Example {
  construtor(attr) {
    this.attr = attr
  }
}

const car = new Car()
const example = new Example(car)
複製代碼

咱們把內部的依賴在外部實例化而後經過構造函數或者其餘方法注入到類中,這就是依賴注入,是否是很簡單,理解了依賴注入後,咱們就能夠開始 IoC容器了

IoC 容器

無論如何,如今都是經過手動注入的方式進行以來管理,那麼咱們可不能夠自動化管理依賴呢,咱們只要聲明須要注入的依賴便可,這時候 IoC 容器出現了

class Container {
  constructor() {
    this.binds = {}
    this.instances = {}
  }
  
  bind(abstract, concrete) {
    if (typeof concrete === 'function') {
      this.binds[abstract] = concrete
    } else {
      this.instances[abstract] = concrete
    }
  }
  
  make(abstract, args = []) {
    if (this.instances[abstract]) return this.instances[abstract]
    return this.binds[abstract](this, ...args)
  }
}
複製代碼

一個 IoC 容器就粗略的完成了,咱們來試驗一下它是如何工做的

// 建立容器實例
const container = new Container()

// 告訴容器須要如何實例化 example
container.bind('example', (_container, attr) => {
  return new Example(_container.make(attr))
})

// 告訴容器如何實例化 car
container.bind('car', () => {
  return new Car()
})

// 告訴容器如何實例化 plane
container.bind('plane', () => {
  return new Plane()
})

// 根據參數建立 Example 實例
container.make('example', 'car')
container.make('example', 'plane')

複製代碼

這個能夠用來實例一種依賴的容器,只要稍加修改就能夠支持多依賴管理,你們能夠本身動手試試~~~~~

固然 Daze.js 容器不止這些功能, 還有自動實例化、實例標籤、上下文注入等等.....

傳送門:

官網:dazejs.org

項目地址: github.com/dazejs/daze

相關文章
相關標籤/搜索