自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端理解依賴(lài)注入(控制反轉(zhuǎn))

開(kāi)發(fā) 前端
前端的技術(shù)的極速發(fā)展,對(duì)前端同學(xué)來(lái)說(shuō)也是一個(gè)不小的挑戰(zhàn),有各種各樣的東西需要學(xué),在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)被后端同學(xué)嘲諷,對(duì)于前端來(lái)講根本就不存在類(lèi)的概念,很多時(shí)候需要把大量的業(yè)務(wù)代碼堆積在頁(yè)面或者組件中,使組件和頁(yè)面變得特別的臃腫,一旦業(yè)務(wù)邏輯復(fù)雜的情況下,及時(shí)組件化做的很好......
前端的技術(shù)的極速發(fā)展,對(duì)前端同學(xué)來(lái)說(shuō)也是一個(gè)不小的挑戰(zhàn),有各種各樣的東西需要學(xué),在開(kāi)發(fā)過(guò)程中經(jīng)常會(huì)被后端同學(xué)嘲諷,對(duì)于前端來(lái)講根本就不存在類(lèi)的概念,很多時(shí)候需要把大量的業(yè)務(wù)代碼堆積在頁(yè)面或者組件中,使組件和頁(yè)面變得特別的臃腫,一旦業(yè)務(wù)邏輯復(fù)雜的情況下,及時(shí)組件化做的很好,仍然避免不了難以維護(hù)。

之所以會(huì)被后端同學(xué)嘲諷,一基礎(chǔ)掌握不扎實(shí),對(duì)前端理解不到位,二缺乏面向?qū)ο笏枷?,三?duì)業(yè)務(wù)與基礎(chǔ)傻傻分不清楚。ECMAScript 2015與Type Script的推出,提出了一個(gè)很重要的概念就是class(類(lèi))的概念。在沒(méi)有class之前為了前端能夠有類(lèi)的概念,一直都是使用構(gòu)造函數(shù)模擬類(lèi)的概念,通過(guò)原型完成繼承。

雖然前端提出了很多概念(模塊化,組件化...),個(gè)人覺(jué)得面向?qū)ο蟮膽?yīng)用是前端對(duì)于項(xiàng)目以及整體架構(gòu)來(lái)講是一件利器,代碼結(jié)構(gòu)好與壞與面向?qū)ο笥幸欢ǖ年P(guān)系,但不是全部。不過(guò)我們可以借助計(jì)算機(jī)領(lǐng)域的一些優(yōu)秀的編程理念來(lái)一定程度上解決這些問(wèn)題,接下來(lái)簡(jiǎn)單的說(shuō)下依賴(lài)注入(控制反轉(zhuǎn))。

什么是依賴(lài)注入

依賴(lài)注入一般指控制反轉(zhuǎn),是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來(lái)減低計(jì)算機(jī)代碼之間的耦合度。其中最常見(jiàn)的方式叫做依賴(lài)注入,還有一種方式叫依賴(lài)查找。通過(guò)控制反轉(zhuǎn),對(duì)象在被創(chuàng)建的時(shí)候,由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴(lài)的對(duì)象的引用傳遞給它。也可以說(shuō),依賴(lài)被注入到對(duì)象中。

從上面的描述中可以發(fā)現(xiàn),依賴(lài)注入發(fā)生在2個(gè)或兩個(gè)以上類(lèi),比如現(xiàn)在有兩個(gè)類(lèi)A與B類(lèi),如果A是基礎(chǔ)類(lèi)存在的話(huà),B做為業(yè)務(wù)類(lèi)存在,B則會(huì)依賴(lài)于A,上面有一句話(huà)很重要由一個(gè)調(diào)控系統(tǒng)內(nèi)所有對(duì)象的外界實(shí)體將其所依賴(lài)的對(duì)象的引用傳遞給它,個(gè)人理解,在B類(lèi)中使用A類(lèi)的實(shí)例,而不是繼承A類(lèi)。

對(duì)面向?qū)ο罅私獾耐瑢W(xué)應(yīng)該了解,面向?qū)ο?大原則:

  1. 單一職責(zé)
  2. 開(kāi)閉原則
  3. 里氏替換
  4. 依賴(lài)倒置
  5. 接口隔離
  6. 迪米特法則
  7. 組合聚合復(fù)用原則

詳細(xì)解釋參照:面向?qū)ο笾叽蠡驹瓌t(javaScript)

然而使用依賴(lài)注入的事為了降低代碼的耦合程度,提高代碼的可拓展性。以上都是一些面向?qū)ο蟮乃枷?,我們參考一下以上最重要的幾個(gè)原則,層模塊不應(yīng)該依賴(lài)低層模塊。兩個(gè)都應(yīng)該依賴(lài)抽象,抽象不應(yīng)該依賴(lài)具體實(shí)現(xiàn),具體實(shí)現(xiàn)應(yīng)該依賴(lài)抽象。

 

  1. // 球隊(duì)信息不依賴(lài)具體實(shí)現(xiàn) 
  2. // 面向接口即面向抽象編程 
  3. class Fruit { 
  4.     constructor(name) { 
  5.         this.name = name 
  6.     } 
  7. class Tropical { 
  8.     // 此處的參數(shù),是teamInfo的一個(gè)實(shí)例,不直接依賴(lài)具體的實(shí)例 
  9.     // 面向抽象 
  10.     constructor(fruit) { 
  11.         this.fruit = fruit; 
  12.     } 
  13.     info() { 
  14.         console.log(this.fruit.name
  15.     } 
  16. // 將依賴(lài)關(guān)系放到此處來(lái)管理,控制權(quán)也放到此處 
  17. // Tropical和Fruit之間不再有直接依賴(lài) 
  18. // 原本直接掌握Fruit控制權(quán)的Tropical不再直接依賴(lài) 
  19. // 將依賴(lài)控制,落在此處(第三方模塊專(zhuān)門(mén)管理)即為控制反轉(zhuǎn) 
  20. var ym = new Tropical(new Fruit('香蕉')) 
  21. ym.info() 
  22. var kobe = new Tropical(new Fruit('菠蘿')) 
  23. kobe.info() 

 

依賴(lài)注入的作用

初始化被依賴(lài)的模塊

如果不通過(guò)依賴(lài)注入模式來(lái)初始化被依賴(lài)的模塊,那么就要依賴(lài)模塊自己去初始化了

那么問(wèn)題來(lái)了:依賴(lài)模塊就耦合了被依賴(lài)模塊的初始化信息了

注入到依賴(lài)模塊中

被依賴(lài)模塊已經(jīng)被其他管理器初始化了,那么依賴(lài)模塊要怎么獲取這個(gè)模塊呢?

有兩種方式:

  • 自己去問(wèn)
  • 別人主動(dòng)給你

沒(méi)用依賴(lài)注入模式的話(huà)是1,用了之后就是2

想想,你需要某個(gè)東西的時(shí)候,你去找別人要,你需要提供別人什么信息?最簡(jiǎn)單的就是那個(gè)東西叫什么,即你需要提供一個(gè)名稱(chēng)。所以,方式1的問(wèn)題是:依賴(lài)模塊耦合了被依賴(lài)模塊的名稱(chēng)還有那個(gè)別人而方式2解決了這個(gè)問(wèn)題,讓依賴(lài)模塊只依賴(lài)需要的模塊的接口。

依賴(lài)注入的優(yōu)點(diǎn)

依賴(lài)注入降低了依賴(lài)和被依賴(lài)類(lèi)型間的耦合,在修改被依賴(lài)的類(lèi)型實(shí)現(xiàn)時(shí),不需要修改依賴(lài)類(lèi)型的實(shí)現(xiàn),同時(shí),對(duì)于依賴(lài)類(lèi)型的測(cè)試。依賴(lài)注入方式,可以將代碼耦合性降到最低,而且各個(gè)模塊拓展不會(huì)互相影響,

  1. 實(shí)現(xiàn)數(shù)據(jù)訪問(wèn)層,也就是前端你的數(shù)據(jù)請(qǐng)求層
  2. 模塊與接口重構(gòu),依賴(lài)注入背后的一個(gè)核心思想是單一功能原則,這意味著這些對(duì)象在系統(tǒng)的任何地方都可以重用。
  3. 隨時(shí)增加單元測(cè)試,把功能封裝到整個(gè)對(duì)象里面會(huì)導(dǎo)致自動(dòng)測(cè)試?yán)щy或者不可能。將模塊和接口與特定對(duì)象隔離,以這種方式重構(gòu)可以執(zhí)行更先進(jìn)的單元測(cè)試。

Vue中使用

上面寫(xiě)的例子也只是對(duì)依賴(lài)注入見(jiàn)單的使用,在項(xiàng)目過(guò)程中往往就不是這么簡(jiǎn)單了,肯定不會(huì)向例子這么簡(jiǎn)單,而是很復(fù)雜很龐大的一個(gè)項(xiàng)目。項(xiàng)目中分為各種各樣的模塊,這種情況又改如何處理?在JavaScript中常見(jiàn)的就是依賴(lài)注入。從名字上理解,所謂依賴(lài)注入,即組件之間的依賴(lài)關(guān)系由容器在運(yùn)行期決定,形象的來(lái)說(shuō),即由容器動(dòng)態(tài)的將某種依賴(lài)關(guān)系注入到組件之中。

前端項(xiàng)目中并不像后端一樣,各種各樣的類(lèi),雖然前端可以寫(xiě)class,若是React項(xiàng)目的話(huà),還會(huì)好很多,由于其框架使用,全部是基于class但是在vue項(xiàng)目中,又應(yīng)該怎么具體體現(xiàn)呢?頁(yè)面中的業(yè)務(wù)也是可以作為類(lèi)存在最終注入到Vue頁(yè)面中,最終完成業(yè)務(wù)邏輯。

 

 

 

 

通過(guò)依賴(lài)注入到底想要達(dá)到到什么效果呢,依賴(lài)注入最終想要達(dá)成的效果則是,頁(yè)面的表現(xiàn)與業(yè)務(wù)相脫離,從本質(zhì)上來(lái)說(shuō),頁(yè)面的展現(xiàn)形式與業(yè)務(wù)邏輯其實(shí)沒(méi)有根本聯(lián)系的。若使用這種依賴(lài)注入的形式,則可以輕松的把業(yè)務(wù)和頁(yè)面表現(xiàn)分離開(kāi),頁(yè)面更加的專(zhuān)注于展示,而所注入的東西則更加的專(zhuān)注于業(yè)務(wù)的處理。項(xiàng)目也則會(huì)變得容易維護(hù)。

index.vue

  1. <template> 
  2.   <div> 
  3.     <el-button @click="getList" 
  4.               :loadding="loadding">獲取表格數(shù)據(jù)</el-button> 
  5.     <ul> 
  6.       <li v-for="(item,index) of list" 
  7.           :key="index">{{item}}</li> 
  8.     </ul> 
  9.   </div> 
  10. </template> 
  11. <script> 
  12. import operation from "@/business/index/Operation.js"
  13. export default { 
  14.   data() { 
  15.     return { 
  16.       list: [], 
  17.       query:{}, 
  18.       loadding:false 
  19.     } 
  20.   }, 
  21.   methods:{ 
  22.     async getList(){ 
  23.       let {query} = this; 
  24.       this.loadding = true
  25.       try{ 
  26.         this.list = await operation.getData.call(this,query); 
  27.       }catch(error){ 
  28.         console.log(error) 
  29.       } 
  30.       this.loadding =false
  31.     } 
  32.   } 
  33. </script> 
  34. <style> 
  35. @import "@/style/index.vue"
  36. </style> 

 

 

 

operations.js

 

  1. import request from "@/api/errorList/index.js"
  2. class Operation { 
  3.     async getData(query){ 
  4.         //  this 指向Vue實(shí)例 
  5.         try { 
  6.             let res = await request.getErrorList(query); 
  7.             let {list} = res; 
  8.             //  這里可以對(duì)數(shù)據(jù)進(jìn)行二次處理 
  9.             //  寫(xiě)一些其他業(yè)務(wù) 
  10.             Promise.resolve(list); 
  11.         }catch(error){ 
  12.             Promise.reject(error); 
  13.         } 
  14.     } 
  15. }; 
  16. export default new Operation(); 

 

上面也是在項(xiàng)目中的一個(gè)簡(jiǎn)單的應(yīng)用,使頁(yè)面表現(xiàn)數(shù)據(jù)請(qǐng)求與數(shù)據(jù)處理,業(yè)務(wù)相脫離,讓項(xiàng)目變得更加容易維護(hù)。

控制反轉(zhuǎn)這里控制權(quán)從使用者本身轉(zhuǎn)移到第三方容器上,而非是轉(zhuǎn)移到被調(diào)用者上,這里需要明確不要疑惑??刂品崔D(zhuǎn)是一種思想,依賴(lài)注入是一種設(shè)計(jì)模式。

依賴(lài)注入最終想要達(dá)到的目的,首先得為模塊依賴(lài)提供抽象的接口,下來(lái)應(yīng)該能夠注冊(cè)依賴(lài)關(guān)系

在注冊(cè)這個(gè)依賴(lài)關(guān)系后有地方存儲(chǔ)它,存儲(chǔ)后,我們應(yīng)該把被依賴(lài)的模塊注入依賴(lài)模塊中,注入應(yīng)該保持被傳遞函數(shù)的作用域,被傳遞的函數(shù)應(yīng)該能夠接受自定義參數(shù),而不僅僅是依賴(lài)描述。

總結(jié)

在JavaScript中依賴(lài)注入的概念不像Java中被經(jīng)常提到,主要原因是在js中很容易就實(shí)現(xiàn)了這種動(dòng)態(tài)依賴(lài)。其實(shí)我們大部分人都用過(guò)依賴(lài)注入,只是我們沒(méi)有意識(shí)到。即使你不知道這個(gè)術(shù)語(yǔ),你可能在你的代碼里用到它百萬(wàn)次了。希望這篇文章能加深你對(duì)它的了解。

需要注意的是,依賴(lài)注入只是控制反轉(zhuǎn)的一種實(shí)現(xiàn)方式,正確的依賴(lài)管理是每個(gè)開(kāi)發(fā)周期中的關(guān)鍵過(guò)程。JavaScript 生態(tài)提供了不同的工具,作為開(kāi)發(fā)者的我們應(yīng)該挑選最適合自己的工具。

 

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2022-04-30 08:50:11

控制反轉(zhuǎn)Spring依賴(lài)注入

2020-07-14 14:59:00

控制反轉(zhuǎn)依賴(lài)注入容器

2023-12-09 14:29:30

編程語(yǔ)言Go

2024-04-18 08:39:57

依賴(lài)注入控制反轉(zhuǎn)WPF

2024-05-10 07:19:46

IOC依賴(lài)倒置控制反轉(zhuǎn)

2011-05-31 10:00:21

Android Spring 依賴(lài)注入

2009-06-22 10:20:01

Spring IoC容

2017-08-16 16:00:05

PHPcontainer依賴(lài)注入

2022-08-02 07:56:53

反轉(zhuǎn)依賴(lài)反轉(zhuǎn)控制反轉(zhuǎn)

2023-07-11 09:14:12

Beanquarkus

2022-12-29 08:54:53

依賴(lài)注入JavaScript

2024-03-28 10:37:44

IoC依賴(lài)注入依賴(lài)查找

2018-03-12 10:02:30

PHP依賴(lài)注入

2015-09-02 11:22:36

JavaScript實(shí)現(xiàn)思路

2021-09-01 08:58:15

項(xiàng)目 UTFailed

2024-06-12 00:00:01

Java函數(shù)式接口

2024-12-30 12:00:00

.NET Core依賴(lài)注入屬性注入

2024-04-01 00:02:56

Go語(yǔ)言代碼

2025-01-13 00:13:59

VSCode架構(gòu)依賴(lài)注入

2024-05-27 00:13:27

Go語(yǔ)言框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)