亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > JavaScript > 正文

深入理解JavaScript系列(22):S.O.L.I.D五大原則之依賴倒置原則DIP詳解

2024-05-06 16:16:10
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了深入理解JavaScript系列(22):S.O.L.I.D五大原則之依賴倒置原則DIP詳解,本文講解了DIP and JavaScript、何時依賴注入等內容,需要的朋友可以參考下
 

前言

本章我們要講解的是S.O.L.I.D五大原則JavaScript語言實現的第5篇,依賴倒置原則LSP(The Dependency Inversion Principle )。

英文原文:http://freshbrewedcode.com/derekgreer/2012/01/22/solid-javascript-the-dependency-inversion-principle/
依賴倒置原則

依賴倒置原則的描述是:

A. High-level modules should not depend on low-level modules.  Both should depend on abstractions.
   高層模塊不應該依賴于低層模塊,二者都應該依賴于抽象

B. Abstractions should not depend upon details.  Details should depend upon abstractions.
   抽象不應該依賴于細節,細節應該依賴于抽象
依賴倒置原則的最重要問題就是確保應用程序或框架的主要組件從非重要的底層組件實現細節解耦出來,這將確保程序的最重要的部分不會因為低層次組件的變化修改而受影響。

該原則的第一部分是關于高層模塊和低層模塊之間的耦合方式,在傳統的分成架構中,高層模塊(封裝了程序的核心業務邏輯)總依賴于低層的一些模塊(一些基礎點)。當應用依賴倒置原則的時候,關系就反過來了。和高層模塊依賴于低層模塊不同,依賴倒置是讓低層模塊依賴于高層模塊里定義的接口。舉例來說,如果要給程序進行數據持久化,傳統的設計是核心模塊依賴于一個持久化模塊的API,而根據依賴倒置原則重構以后,則是核心模塊需要定義持久化的API接口,然后持久化的實現實例需要實現核心模塊定義的這個API接口。

該原則的第二部分描述的是抽象和細節之間的正確關系。理解這一部分,通過了解C++語言比較有幫助,因為他的適用性比較明顯。

不像一些靜態類型的語言,C++沒有提供一個語言級別的概念來定義接口,那類定義和類實現之間到底是怎么樣的呢,在C++里,類通過頭文件的形式來定義,其中定義了源文件需要實現的類成員方法和變量。因為所有的變量和私有方法都定義在頭文件里,所以可以用來抽象以便和實現細節之前解耦出來。通過定只定義抽象方法來實現(C++里是抽象基類)接口這個概念用于實現類來實現。

DIP and JavaScript

因為JavaScript是動態語言,所以不需要去為了解耦而抽象。所以抽象不應依賴于細節這個改變在JavaScript里沒有太大的影響,但高層模塊不應依賴于低層模塊卻有很大的影響。

在當靜態類型語言的上下文里討論依賴倒置原則的時候,耦合的概念包括語義(semantic)和物理(physical)兩種。這就是說,如果一個高層模塊依賴于一個低層模塊,也就是不僅耦合了語義接口,也耦合了在底層模塊里定義的物理接口。也就是說高層模塊不僅要從第三方類庫解耦出來,也需要從原生的低層模塊里解耦出來。

為了解釋這一點,想象一個.NET程序可能包含一個非常有用的高層模塊,而該模塊依賴于一個低層的持久化模塊。當作者需要在持久化API里增加一個類似的接口的時候,不管依賴倒置原則有沒有使用,高層模塊在不重新實現這個低層模塊的新接口之前是沒有辦法在其它的程序里得到重用的。

在JavaScript里,依賴倒置原則的適用性僅僅限于高層模塊和低層模塊之間的語義耦合,比如,DIP可以根據需要去增加接口而不是耦合低層模塊定義的隱式接口。

為了來理解這個,我們看一下如下例子:

復制代碼代碼如下:

$.fn.trackMap = function(options) {
    var defaults = {
        /* defaults */
    };
    options = $.extend({}, defaults, options);

 

    var mapOptions = {
        center: new google.maps.LatLng(options.latitude,options.longitude),
        zoom: 12,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    },
        map = new google.maps.Map(this[0], mapOptions),
        pos = new google.maps.LatLng(options.latitude,options.longitude);

    var marker = new google.maps.Marker({
        position: pos,
        title: options.title,
        icon: options.icon
    });

    marker.setMap(map);

    options.feed.update(function(latitude, longitude) {
        marker.setMap(null);
        var newLatLng = new google.maps.LatLng(latitude, longitude);
        marker.position = newLatLng;
        marker.setMap(map);
        map.setCenter(newLatLng);
    });

    return this;
};

var updater = (function() {
    // private properties

    return {
        update: function(callback) {
            updateMap = callback;
        }
    };
})();

$("#map_canvas").trackMap({
    latitude: 35.044640193770725,
    longitude: -89.98193264007568,
    icon: 'http://bit.ly/zjnGDe',
    title: 'Tracking Number: 12345',
    feed: updater
});

 

在上述代碼里,有個小型的JS類庫將一個DIV轉化成Map以便顯示當前跟蹤的位置信息。trackMap函數有2個依賴:第三方的Google Maps API和Location feed。該feed對象的職責是當icon位置更新的時候調用一個callback回調(在初始化的時候提供的)并且傳入緯度latitude和精度longitude。Google Maps API是用來渲染界面的。

feed對象的接口可能按照裝,也可能沒有照裝trackMap函數的要求去設計,事實上,他的角色很簡單,著重在簡單的不同實現,不需要和Google Maps這么依賴。介于trackMap語義上耦合了Google Maps API,如果需要切換不同的地圖提供商的話那就不得不對trackMap函數進行重寫以便可以適配不同的provider。

為了將于Google maps類庫的語義耦合翻轉過來,我們需要重寫設計trackMap函數,以便對一個隱式接口(抽象出地圖提供商provider的接口)進行語義耦合,我們還需要一個適配Google Maps API的一個實現對象,如下是重構后的trackMap函數:

復制代碼代碼如下:

$.fn.trackMap = function(options) {
    var defaults = {
        /* defaults */
    };

 

    options = $.extend({}, defaults, options);

    options.provider.showMap(
        this[0],
        options.latitude,
        options.longitude,
        options.icon,
        options.title);

    options.feed.update(function(latitude, longitude) {
        options.provider.updateMap(latitude, longitude);
    });

    return this;
};

$("#map_canvas").trackMap({
    latitude: 35.044640193770725,
    longitude: -89.98193264007568,
    icon: 'http://bit.ly/zjnGDe',
    title: 'Tracking Number: 12345',
    feed: updater,
    provider: trackMap.googleMapsProvider
});


在該版本里,我們重新設計了trackMap函數以及需要的一個地圖提供商接口,然后將實現的細節挪到了一個單獨的googleMapsProvider組件,該組件可能獨立封裝成一個單獨的JavaScript模塊。如下是我的googleMapsProvider實現:
復制代碼代碼如下:

trackMap.googleMapsProvider = (function() {
    var marker, map;

 

    return {
        showMap: function(element, latitude, longitude, icon, title) {
            var mapOptions = {
                center: new google.maps.LatLng(latitude, longitude),
                zoom: 12,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            },
                pos = new google.maps.LatLng(latitude, longitude);

            map = new google.maps.Map(element, mapOptions);

            marker = new google.maps.Marker({
                position: pos,
                title: title,
                icon: icon
            });

            marker.setMap(map);
        },
        updateMap: function(latitude, longitude) {
            marker.setMap(null);
            var newLatLng = new google.maps.LatLng(latitude,longitude);
            marker.position = newLatLng;
            marker.setMap(map);
            map.setCenter(newLatLng);
        }
    };
})();


做了上述這些改變以后,trackMap函數將變得非常有彈性了,不必依賴于Google Maps API,相反可以任意替換其它的地圖提供商,那就是說可以按照程序的需求去適配任何地圖提供商。

 

何時依賴注入?

有點不太相關,其實依賴注入的概念經常和依賴倒置原則混在一起,為了澄清這個不同,我們有必要來解釋一下:

依賴注入是控制反轉的一個特殊形式,反轉的意思一個組件如何獲取它的依賴。依賴注入的意思就是:依賴提供給組件,而不是組件去獲取依賴,意思是創建一個依賴的實例,通過工廠去請求這個依賴,通過Service Locator或組件自身的初始化去請求這個依賴。依賴倒置原則和依賴注入都是關注依賴,并且都是用于反轉。不過,依賴倒置原則沒有關注組件如何獲取依賴,而是只關注高層模塊如何從低層模塊里解耦出來。某種意義上說,依賴倒置原則是控制反轉的另外一種形式,這里反轉的是哪個模塊定義接口(從低層里定義,反轉到高層里定義)。

總結

這是五大原則的最后一篇了,在這5篇文字里我們看到了SOLID如何在JavaScript里實現的,不同的原則在JavaScript里通過不同的角度來說明的。(大叔注:其實大叔覺得雖然是有點不倫不類,但從另外一個層面上說,大體的原則在各種語言上其實還是一樣的。)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲乱亚洲乱妇无码| 国产精品久久久久久久7电影| 亚洲女人被黑人巨大进入| 日韩精品福利在线| 国产va免费精品高清在线观看| 国产精品第1页| 午夜精品在线视频| 国产一区二区免费| 国产精品嫩草影院久久久| 国产精品青青在线观看爽香蕉| 色狠狠久久aa北条麻妃| 国产亚洲福利一区| 九色精品免费永久在线| 国产精品色午夜在线观看| 亚洲美腿欧美激情另类| 国产精品一区二区三区久久久| 国内精品视频在线| 欧美香蕉大胸在线视频观看| 欧美夫妻性视频| 久久精品99国产精品酒店日本| 尤物九九久久国产精品的分类| 久久免费视频这里只有精品| 日韩成人在线观看| 在线播放国产一区二区三区| 国产精品亚洲视频在线观看| 成人激情视频在线播放| 亚洲性xxxx| 97久久伊人激情网| 日韩av在线天堂网| 欧美日韩亚洲激情| 国产精品91久久久| 欧美激情在线视频二区| 最新国产成人av网站网址麻豆| 亚洲美女性生活视频| 日本精品久久电影| 国产ts人妖一区二区三区| 国产精品自拍偷拍视频| 国产亚洲视频在线观看| 亚洲精品视频中文字幕| 国产精品美女主播| 国产高清视频一区三区| 国产99视频精品免视看7| 国产一区av在线| 久久影院免费观看| 91久久久久久| 中文字幕日韩有码| 午夜精品福利视频| 国产亚洲视频在线| 中文字幕在线看视频国产欧美| 亚洲国产精品电影在线观看| 欧美性受xxxx黑人猛交| 日韩av在线免播放器| 欧美性资源免费| 北条麻妃一区二区三区中文字幕| 欧美日韩激情小视频| 久久这里有精品视频| 久久久国产一区二区三区| 久久久久久久久久久久久久久久久久av| 久久久久久尹人网香蕉| 久久伊人精品一区二区三区| 岛国av在线不卡| 国产一区二区久久精品| 97在线免费观看视频| 日韩欧美在线视频日韩欧美在线视频| 国产亚洲精品成人av久久ww| 久久天天躁狠狠躁夜夜爽蜜月| 欧美在线一区二区视频| 久久国产精品久久久久久久久久| 亚洲第一色在线| 亚洲香蕉伊综合在人在线视看| 日韩av一区二区在线观看| 在线视频欧美性高潮| 日韩美女免费观看| 国产欧亚日韩视频| 亚洲美腿欧美激情另类| 伊人av综合网| 国产精品亚洲一区二区三区| 久久99精品久久久久久琪琪| 成人做爰www免费看视频网站| 国产精品国语对白| 欧美成年人视频网站欧美| 精品视频—区二区三区免费| 懂色av中文一区二区三区天美| 成人网中文字幕| 超薄丝袜一区二区| 欧洲美女免费图片一区| 91久久久久久久久久| 一本大道亚洲视频| 精品日本高清在线播放| 久久综合五月天| 国产日韩欧美电影在线观看| 亚洲毛片在线观看.| 亚洲乱码一区二区| 91情侣偷在线精品国产| 国产欧美精品日韩精品| 亚洲精品av在线播放| 日本老师69xxx| 日韩毛片在线观看| 成人黄色大片在线免费观看| 精品欧美国产一区二区三区| 国产中文字幕日韩| 91国产视频在线| 国产午夜精品免费一区二区三区| 欧美特黄级在线| 欧美大全免费观看电视剧大泉洋| 日韩精品中文字幕在线观看| 亚洲精品国产拍免费91在线| 丝袜美腿精品国产二区| 午夜伦理精品一区| 日韩网站在线观看| 日韩福利伦理影院免费| 日本一区二三区好的精华液| 国产精品成人一区| 日韩欧美a级成人黄色| 国产精品专区h在线观看| 中文欧美在线视频| 北条麻妃一区二区三区中文字幕| 久久精品国产亚洲一区二区| 亚洲欧美制服另类日韩| 亚洲理论片在线观看| 亚洲视频在线看| 成人性教育视频在线观看| 久久久久久噜噜噜久久久精品| 久热精品视频在线观看一区| 国产精品美女免费| 欧美日韩激情视频| 欧美性极品少妇精品网站| 亚洲欧美国产日韩天堂区| 国产精品女人久久久久久| 欧美久久精品午夜青青大伊人| 国产欧美一区二区三区在线看| 日韩h在线观看| 欧美日韩免费观看中文| 美女扒开尿口让男人操亚洲视频网站| 欧美大码xxxx| 久久91亚洲精品中文字幕| 日韩中文字幕网址| 97婷婷大伊香蕉精品视频| 亚洲一区二区中文| 国产精品第一第二| 久久久久亚洲精品成人网小说| 2019av中文字幕| 亚洲一区中文字幕在线观看| 精品久久久久久久中文字幕| 久热精品视频在线观看一区| 日韩午夜在线视频| 俺去亚洲欧洲欧美日韩| 亚洲视频一区二区三区| 在线观看日韩欧美| 亚洲国产97在线精品一区| 992tv成人免费视频| 久久亚洲私人国产精品va| 最近更新的2019中文字幕| 国产视频久久久久久久| 亚洲va久久久噜噜噜| 91香蕉嫩草影院入口| 久久久久五月天| 亚洲国产精品久久久| 日韩在线视频网| 欧美日韩在线观看视频小说| 国产日韩在线看片| 国外日韩电影在线观看| 91精品视频在线播放| 国产精品视频久久久久|