Understanding JavaScript series (21) : S O. L. I. D the five principles of the interface segregation principle ISP explanation

  • 2020-05-10 17:42:34
  • OfStack

preface

. In this chapter we will interpret the S O. L. I. D5 big principle JavaScript language implementation of article 4, the interface segregation principle ISP (The Interface Segregation Principle).

English text: http: / / freshbrewedcode com/derekgreer / 2012/01/08 / solid - javascript - the - interface - segregation - principle /
Note: the author of this article write more obfuscated, so uncle understand more depressed, just watch, don't get stuck in it
The interface isolation principle is described as:


Clients should not be forced to depend on methods they do not use.

Customers should not be forced to rely on methods they do not use.

When a user-dependent interface method is not used by another user, it must implement the interface. In other words, if one user relies on an interface that is not used but is used by another user, all users who depend on the interface will be affected when other users modify the interface. This is a clear violation of the open close principle and not what we would expect.

Interface isolation principle ISP is similar to single 1 responsibility in that it is used to aggregate functional responsibilities. In fact, ISP can be understood to convert a program with single 1 responsibility into an object with a common interface.

JavaScript interface

How can we abide by this principle? After all, JavaScript doesn't have the features of an interface, and it would be fine if the interface was what we thought it would be by creating an contract decouple using an abstract type provided by a language, but JavaScript has another form of interface. In the book Design Patterns, Elements of Reusable Object-Oriented Software1, we find the definition of the interface:
http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612

Any 1 operation declared by an object contains an operation name, parameter object, and the return value of the operation. We call this the signature of the operator (signature).
All operations declared in an object are called interfaces to that object (interface). The interface of an object represents all requests that occur on that object.
Whether or not a language provides a single construct to represent an interface, all objects have an implicit interface made up of all the properties and methods of that object. Refer to the following code:


var exampleBinder = {};
exampleBinder.modelObserver = (function() {
    /* Private variables */
    return {
        observe: function(model) {
            /* code */
            return newModel;
        },
        onChange: function(callback) {
            /* code */
        }
    }
})(); exampleBinder.viewAdaptor = (function() {
    /* Private variables */
    return {
        bind: function(model) {
            /* code */
        }
    }
})(); exampleBinder.bind = function(model) {
    /* Private variables */
    exampleBinder.modelObserver.onChange(/* The callback callback */);
    var om = exampleBinder.modelObserver.observe(model);
    exampleBinder.viewAdaptor.bind(om);
    return om;
};

The exampleBinder class library above implements bidirectional binding. The public interface exposed by this library is the bind method, among which the functions of change notification and view interaction used in bind are implemented by the separate objects modelObserver and viewAdaptor respectively. These objects are, in a sense, the concrete implementation of the public interface bind method.

Although JavaScript does not provide an interface type to support the object contract, the implicit interface to the object can still be provided to the program user as an contract.

ISP and JavaScript

The next section we discuss is about the effects of violating the interface isolation principle in JavaScript. As you can see above, the implementation of the interface isolation principle in JavaScript programs is unfortunate, but not as powerful as statically typed languages, and the language features of JavaScript sometimes make the so-called interfaces a little sticky.

The realization of decadence

In statically typed languages, one reason for the violation of ISP is corrupt implementation. All the methods defined in Java and C# interfaces must be implemented, and if you only need a few of them, the others must be implemented (either by null or by throwing exceptions). In JavaScript, if only one of the interfaces in one object is needed, it will not solve the problem of corrupt implementation, although it will not force the implementation of the interface above. But this implementation still violates the Richter substitution principle.


var rectangle = {
    area: function() {
        /* code */
    },
    draw: function() {
        /* code */
    }
}; var geometryApplication = {
    getLargestRectangle: function(rectangles) {
        /* code */
    }
}; var drawingApplication = {
    drawRectangles: function(rectangles) {
       /* code */
    }
};

When an rectangle substitute satisfies the getLargestRectangle of the new object geometryApplication, it only needs rectangle's area() method, but it violates LSP (because it doesn't use the draw method that drawRectangles USES).

Static coupling

Another cause of ISP violation in statically typed languages is static coupling, in which interfaces play a major role in a loosely coupled designer. Either in dynamic or in static language and, in some cases, more than one object may need to be in the client users communicate (such as Shared state), the static type of language, the best solution is to use Role Interfaces, it allows users to interact with the object (the object may need to be in more than one role) as its implementation to decouple behavior of users and has nothing to do. In JavaScript there is no such problem, because the objects are decoupled by the particular advantages of dynamic languages.

Semantic coupling

A general cause of the violation of ISP, dynamically and statically typed languages, it is the semantic coupling, the so-called semantic coupling is depend on each other, which is an object behavior depends on the other one object, that means, if a user changes the one act, is likely to affect the other one use of the user. This also violates the single 1 responsibility principle. You can solve this problem by inheritance and object substitution.

scalability

Another reason for the problem is scalability. Many people use the example of callback to demonstrate scalability (such as the successful callback Settings in ajax). If you want to be the interface need to 1 in the implementation and the implementation of object methods, there are a lot of familiar or ISP will become very important, that is to say, when one interface interface becomes a method to realize a lot of demand, the realization of his will is complicated, and is likely to lead to these interfaces to assume a no sticky responsibilities, this is what we often mention fat interface.

conclusion

The dynamic language features in JavaScript make it less important to implement non-sticky interfaces than statically typed languages, but the interface isolation principle still has its place in the JavaScript programming pattern.


Related articles: