In-depth understanding of the JavaScript series: S.o.l.i.d Five Principles of dependency inversion principle dip

Source: Internet
Author: User

Preface This chapter is to explain the s.o.l.i.d Five principles of JavaScript implementation of the 5th, the dependency inversion principle LSP (the Dependency inversion Principle). English Original: http://freshbrewedcode.com/derekgreer/2012/01/22/solid-javascript-the-dependency-inversion-principle/the dependency inversion principle relies on the inversion principle described as: a. High-level modules should not depend on low-Level modules.   Both should depend on abstractions. High-level modules should not be dependent on the lower layer, both of which should be dependent on abstract B.  Abstractions should not depend upon details.   Details should depend upon abstractions. Abstractions should not be dependent on detail, and the most important issue in which details should depend on the principle of abstract dependency inversion is to ensure that the main components of the application or framework are decoupled from the non-essential underlying component implementation details, which ensures that the most important parts of the program are not affected by changes to the lower-level components. The first part of the principle is about the coupling between high-rise and low-level modules, and in traditional partitioning architectures, high-level modules (which encapsulate the core business logic of the program) rely on some of the lower-layer modules (some base points). When applying the dependency inversion principle, the relationship is reversed. Unlike high-level modules, which rely on lower-layer modules, dependency inversion is the interface that allows low-level modules to rely on defined interfaces in high-rise modules. For example, if you want to make data persistence for a program, the traditional design is that the core module relies on a persistence module's API, and after refactoring based on the dependency inversion principle, the core module needs to define the persistent API interface, and then the persisted implementation instance needs to implement this API interface defined by the core module. The second part of the principle describes the correct relationship between abstraction and detail. Understand this part by understanding C++language is helpful, because his applicability is more obvious. Unlike some static types of languages, C+ + does not provide a language-level concept for defining interfaces, what is the definition between class and class implementation, in C + +, the class is defined in the form of a header file that defines the class member methods and variables that the source file needs to implement. Because all variables and private methods are defined in the header file, they can be abstracted to be decoupled from the implementation details. Implemented by defining only abstract methods (C + +The concept of an abstract base class) interface is used to implement a class. DIP and JavaScript because JavaScript is a dynamic language, it does not need to be abstracted to understand decoupling. So abstraction should not depend on details This change does not have much effect in JavaScript, but high-level modules should not be dependent on low-layer modules but have a big impact. When the dependency inversion principle is discussed in the context of a statically typed language, the concept of coupling includes both semantic (semantic) and physical (physical). This means that if a high-level module relies on a lower-layer module, which is not only coupled with the semantic interface, it is coupled with the physical interface defined in the underlying module. This means that the high-level modules are not only decoupled from the third-party libraries, but also decoupled from the native low-layer modules. To explain this, imagine a. NET program may contain a very useful high-level module, which relies on a low-layer persistence module. When the author needs to add a similar interface to the Persistence API, no matter whether the dependency inversion principle is used or not, the high-level module cannot be reused in other programs without re-implementing the new interface of the lower-layer module. In JavaScript, the applicability of the dependency inversion principle is limited to semantic coupling between the high-level module and the lower-layer module, for example, the dip can increase the interface as needed instead of coupling the implicit interface defined by the lower-layer module. To understand this, let's take a look at the following example: $.fn.trackmap=function(options) {varDefaults = {        /*Defaults*/    }; Options=$.extend ({}, defaults, options); varMapoptions ={Center:NewGoogle.maps.LatLng (options.latitude,options.longitude), zoom:12, MapTypeId:google.maps.MapTypeId.ROADMAP}, Map=NewGoogle.maps.Map ( This[0], mapoptions), POS=NewGoogle.maps.LatLng (options.latitude,options.longitude); varMarker =NewGoogle.maps.Marker ({position:pos, title:options.title, Icon:options.icon});    Marker.setmap (map); Options.feed.update (function(latitude, longitude) {Marker.setmap (NULL); varNEWLATLNG =Newgoogle.maps.LatLng (latitude, longitude); Marker.position=newlatlng;        Marker.setmap (map);    Map.setcenter (NEWLATLNG);    }); return  This;};varUpdater = (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}); In the above code, there is a small JS class library that transforms a div into a map to display the location information of the current trace. The Trackmap function has 2 dependencies: A third-party Google Maps API and a location feed. The role of the Feed object is to invoke a callback callback (provided at initialization time) when the icon position is updated and to pass in latitude latitude and precision longitude. The Google Maps API is used to render the interface. The interface of the feed object may or may not be designed according to the requirements of the Trackmap function, in fact, his role is very simple, focus on the simple different implementation, do not need and Google Maps so dependent. The Trackmap is semantically coupled with the Google Maps API, and if you need to switch between different map providers, then you have to rewrite the Trackmap function so that you can fit different provider. In order to flip the semantic coupling of the Google Maps class library, we need to rewrite the design trackmap function so that we can semantically couple an implicit interface (abstraction out of the interface of the map provider provider), and we need a fit for Google Maps. An implementation object for the API, the following is the reconstructed Trackmap function: $.fn.trackmap=function(options) {varDefaults = {        /*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}); In this release, we redesigned the TRACKMAP function and the required map provider interface, and then moved the implementation details to a separate Googlemapsprovider component that could be individually encapsulated into a single JavaScript module. Here is my Googlemapsprovider implementation: Trackmap.googlemapsprovider= (function() {    varmarker, map; return{showmap:function(element, latitude, longitude, icon, title) {varMapoptions ={Center:Newgoogle.maps.LatLng (latitude, longitude), Zoom:12, MapTypeId:google.maps.MapTypeId.ROADMAP}, POS=Newgoogle.maps.LatLng (latitude, longitude); Map=NewGoogle.maps.Map (element, mapoptions); Marker=NewGoogle.maps.Marker ({position:pos, title:title, Icon:icon            });        Marker.setmap (map); }, Updatemap:function(latitude, longitude) {Marker.setmap (NULL); varNEWLATLNG =NewGoogle.maps.LatLng (latitude,longitude); Marker.position=newlatlng;            Marker.setmap (map);        Map.setcenter (NEWLATLNG); }    };}) (); After making these changes, the Trackmap function becomes very resilient and does not have to rely on the Google Maps API to replace any other map provider, which means that it can be adapted to any map provider according to the needs of the program. When to rely on injection? Somewhat less relevant, in fact, the concept of dependency injection is often mixed with the dependency inversion principle, in order to clarify this difference, we need to explain: Dependency injection is a special form of control inversion, reversing the meaning of how a component obtains its dependence. Dependency injection means that a dependency is provided to a component rather than a component to obtain a dependency, which means creating a dependent instance, requesting the dependency through the factory, and requesting the dependency through the service locator or the initialization of the component itself. The dependency inversion principle and dependency injection are all concerned with dependency and are used for inversion. However, the dependency inversion principle does not focus on how the component obtains dependencies, but only on how the high-level modules are decoupled from the lower-layer modules. In a sense, the dependency inversion principle is another form of control inversion in which the module defines the interface (defined from the lower layer and reversed to the upper level). Summing up this is the last of the five principles, and in these 5 words we see how solid is implemented in JavaScript, and different principles are explained in JavaScript in different ways. (Uncle Note: In fact, although the uncle feels a bit nondescript, but from another level, the general principle in all languages is actually the same. Synchronization and recommendation this article has been synchronized to the directory index: in-depth understanding of JavaScript series in-depth understanding of the JavaScript series, including the original, translation, reprint and other types of articles, if it is useful to you, please recommend supporting a, to the power of the uncle writing. 

In-depth understanding of the JavaScript series: S.o.l.i.d Five Principles of dependency inversion principle dip

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.