前端理解依賴注入(控制反轉)

前端的技術的極速發展,對前端同窗來講也是一個不小的挑戰,有各類各樣的東西須要學,在開發過程當中常常會被後端同窗嘲諷,對於前端來說根本就不存在類的概念,不少時候須要把大量的業務代碼堆積在頁面或者組件中,使組件和頁面變得特別的臃腫,一旦業務邏輯複雜的狀況下,及時組件化作的很好,仍然避免不了難以維護。前端

之因此會被後端同窗嘲諷,一基礎掌握不紮實,對前端理解不到位,二缺少面向對象思想,三對業務與基礎傻傻分不清楚。ECMAScript 2015Type Script的推出,提出了一個很重要的概念就是class(類)的概念。在沒有class以前爲了前端可以有類的概念,一直都是使用構造函數模擬類的概念,經過原型完成繼承。vue

雖然前端提出了不少概念(模塊化,組件化...),我的以爲面向對象的應用是前端對於項目以及總體架構來說是一件利器,代碼結構好與壞與面向對象有必定的關係,但不是所有。不過咱們能夠藉助計算機領域的一些優秀的編程理念來必定程度上解決這些問題,接下來簡單的說下依賴注入(控制反轉)。java

什麼是依賴注入

依賴注入通常指控制反轉,是面向對象編程中的一種設計原則,能夠用來減低計算機代碼之間的耦合度。其中最多見的方式叫作依賴注入,還有一種方式叫依賴查找。經過控制反轉,對象在被建立的時候,由一個調控系統內全部對象的外界實體將其所依賴的對象的引用傳遞給它。也能夠說,依賴被注入到對象中。編程

從上面的描述中能夠發現,依賴注入發生在2個或兩個以上類,好比如今有兩個類AB類,若是A是基礎類存在的話,B作爲業務類存在,B則會依賴於A,上面有一句話很重要由一個調控系統內全部對象的外界實體將其所依賴的對象的引用傳遞給它,我的理解,在B類中使用A類的實例,而不是繼承A類。segmentfault

對面向對象瞭解的同窗應該瞭解,面向對象7大原則:後端

  1. 單一職責
  2. 開閉原則
  3. 里氏替換
  4. 依賴倒置
  5. 接口隔離
  6. 迪米特法則
  7. 組合聚合複用原則

詳細解釋參照:面向對象之七大基本原則(javaScript)設計模式

然而使用依賴注入的事爲了下降代碼的耦合程度,提升代碼的可拓展性。以上都是一些面向對象的思想,咱們參考一下以上最重要的幾個原則,層模塊不該該依賴低層模塊。兩個都應該依賴抽象,抽象不該該依賴具體實現,具體實現應該依賴抽象。api

// 球隊信息不依賴具體實現
// 面向接口即面向抽象編程
class Fruit {
    constructor(name) {
        this.name = name
    }
}
class Tropical {
    // 此處的參數,是teamInfo的一個實例,不直接依賴具體的實例
    // 面向抽象
    constructor(fruit) {
        this.fruit = fruit;
    }
    info() {
        console.log(this.fruit.name)
    }
}
// 將依賴關係放到此處來管理,控制權也放到此處
// Tropical和Fruit之間再也不有直接依賴
// 本來直接掌握Fruit控制權的Tropical再也不直接依賴
// 將依賴控制,落在此處(第三方模塊專門管理)即爲控制反轉
var ym = new Tropical(new Fruit('香蕉'))
ym.info()
var kobe = new Tropical(new Fruit('菠蘿'))
kobe.info()

依賴注入的做用

初始化被依賴的模塊架構

若是不經過依賴注入模式來初始化被依賴的模塊,那麼就要依賴模塊本身去初始化了
那麼問題來了:依賴模塊就耦合了被依賴模塊的初始化信息了框架

注入到依賴模塊中

被依賴模塊已經被其餘管理器初始化了,那麼依賴模塊要怎麼獲取這個模塊呢?

有兩種方式:

  • 本身去問
  • 別人主動給你

沒用依賴注入模式的話是1,用了以後就是2

想一想,你須要某個東西的時候,你去找別人要,你須要提供別人什麼信息?最簡單的就是那個東西叫什麼,即你須要提供一個名稱。因此,方式1的問題是:依賴模塊耦合了被依賴模塊的名稱還有那個別人而方式2解決了這個問題,讓依賴模塊只依賴須要的模塊的接口。

依賴注入的優勢

依賴注入下降了依賴和被依賴類型間的耦合,在修改被依賴的類型實現時,不須要修改依賴類型的實現,同時,對於依賴類型的測試。依賴注入方式,能夠將代碼耦合性降到最低,並且各個模塊拓展不會互相影響,

  1. 實現數據訪問層,也就是前端你的數據請求層
  2. 模塊與接口重構,依賴注入背後的一個核心思想是單一功能原則,這意味着這些對象在系統的任何地方均可以重用。
  3. 隨時增長單元測試,把功能封裝到整個對象裏面會致使自動測試困難或者不可能。將模塊和接口與特定對象隔離,以這種方式重構能夠執行更先進的單元測試。

Vue中使用

上面寫的例子也只是對依賴注入見單的使用,在項目過程當中每每就不是這麼簡單了,確定不會向例子這麼簡單,而是很複雜很龐大的一個項目。項目中分爲各類各樣的模塊,這種狀況又改如何處理?在JavaScript中常見的就是依賴注入。從名字上理解,所謂依賴注入,即組件之間的依賴關係由容器在運行期決定,形象的來講,即由容器動態的將某種依賴關係注入到組件之中。

前端項目中並不像後端同樣,各類各樣的類,雖然前端能夠寫class,如果React項目的話,還會好不少,因爲其框架使用,所有是基於class可是在vue項目中,又應該怎麼具體體現呢?頁面中的業務也是能夠做爲類存在最終注入到Vue頁面中,最終完成業務邏輯。

o_7A56115D-CE2F-43e4-A824-35975D35502F.png

經過依賴注入到底想要達到到什麼效果呢,依賴注入最終想要達成的效果則是,頁面的表現與業務相脫離,從本質上來講,頁面的展示形式與業務邏輯其實沒有根本聯繫的。若使用這種依賴注入的形式,則能夠輕鬆的把業務和頁面表現分離開,頁面更加的專一於展現,而所注入的東西則更加的專一於業務的處理。項目也則會變得容易維護。

index.vue

<template>
  <div>
    <el-button @click="getList"
              :loadding="loadding">獲取表格數據</el-button>
    <ul>
      <li v-for="(item,index) of list"
          :key="index">{{item}}</li>
    </ul>
  </div>
</template>
<script>
import operation from "@/business/index/Operation.js";
export default {
  data() {
    return {
      list: [],
      query:{},
      loadding:false
    }
  },
  methods:{
    async getList(){
      let {query} = this;
      this.loadding = true;
      try{
        this.list = await operation.getData.call(this,query);
      }catch(error){
        console.log(error)
      }
      this.loadding =false;
    }
  }
}
</script>
<style>
@import "@/style/index.vue";
</style>

operations.js

import request from "@/api/errorList/index.js";
class Operation {
    async getData(query){
        //  this 指向Vue實例
        try {
            let res = await request.getErrorList(query);
            let {list} = res;
            //  這裏能夠對數據進行二次處理
            //  寫一些其餘業務
            Promise.resolve(list);
        }catch(error){
            Promise.reject(error);
        }
    }
};
export default new Operation();

上面也是在項目中的一個簡單的應用,使頁面表現數據請求與數據處理,業務相脫離,讓項目變得更加容易維護。

控制反轉這裏控制權從使用者自己轉移到第三方容器上,而非是轉移到被調用者上,這裏須要明確不要疑惑。控制反轉是一種思想,依賴注入是一種設計模式。

依賴注入最終想要達到的目的,首先得爲模塊依賴提供抽象的接口,下來應該可以註冊依賴關係
在註冊這個依賴關係後有地方存儲它,存儲後,咱們應該把被依賴的模塊注入依賴模塊中,注入應該保持被傳遞函數的做用域,被傳遞的函數應該可以接受自定義參數,而不只僅是依賴描述。

總結

JavaScript中依賴注入的概念不像Java中被常常提到,主要緣由是在js中很容易就實現了這種動態依賴。其實咱們大部分人都用過依賴注入,只是咱們沒有意識到。即便你不知道這個術語,你可能在你的代碼裏用到它百萬次了。但願這篇文章能加深你對它的瞭解。

須要注意的是,依賴注入只是控制反轉的一種實現方式,正確的依賴管理是每一個開發週期中的關鍵過程。JavaScript 生態提供了不一樣的工具,做爲開發者的咱們應該挑選最適合本身的工具。

相關文章
相關標籤/搜索