Learning JavaScript design pattern (Interface) _ javascript skills

Source: Internet
Author: User
This article mainly guides you through the JavaScript design mode. It focuses on interfaces, and provides examples to illustrate what interfaces are and analyze them in detail. Interested friends can refer to them. 1. Interface Overview

1) What is an interface?

An interface provides a means to describe the methods that an object should have. Although it can indicate the semantics of these methods, it does not specify how these methods should be implemented.

2) benefits of interfaces

  • Promotes code reuse.

The interface can tell programmers which methods are implemented by a class to help them use this class.

  • It helps to stabilize the communication modes before different classes.
  • Testing and debugging can also be easier.

In a weak javascript language, it is difficult to track Type Mismatch Errors. Using Interfaces makes it easier to find such errors, because if an object is not of the required type or there is no necessary method to implement it, then you will get a clear error message containing useful information. In this way, logical errors can be restricted to methods rather than object structures.

  • The interface also makes the code more stable.

Because any changes to the interface must be reflected in all classes that implement it. If an operation is added to an interface and a class implementing it does not add the operation, you will see an error immediately.

3) interface disadvantages

Javascript is a language with strong image performance, mainly thanks to its weak type features. The use of interfaces strengthens the role of types in a certain program. This reduces the language flexibility. Javascript does not provide built-in support for interfaces, but there is always a risk of trying to imitate the built-in functions of other languages.

The biggest problem with using interfaces in js is that it is impossible for other programmers to comply with your defined interfaces. In other languages, the interface concept is built-in. If someone defines a class that implements an interface, the compiler will ensure that the class does implement this interface. In javascript, you must manually implement an interface for a class. Coding specifications and helper classes can provide some help, but this problem cannot be completely eliminated. If other programmers in the project do not take interfaces seriously, the use of these interfaces cannot be guaranteed. Unless the project owner agrees to use the interface and checks it, many values of the interface will not be reflected.

2. Simulate interfaces in javascript

Three methods of interface imitation in javascript: annotation description method, attribute check method, duck pattern recognition method.

No technology is perfect, but the combination of the three is basically satisfactory.

1) Comments and descriptions interface implementation

Imitating interfaces with comments is the simplest method, but the effect is the worst. This method imitates the practices in other Page Object languages and uses the interface and implements keywords, but puts them in comments to avoid syntax errors. As follows:

// There are three methods for defining interfaces in javascript: // 1. annotation description/*** interface Composite {* function add (obj); * function remove (obj ); * function update (obj);} advantages: programmers can have reference disadvantages: There are a lot of disadvantages. It is just an excuse for the scope of the document. If you do not implement all the methods, the program can still run, it's too loose. Difficult to test and debug * // Implement of interface Compositevar CompositeImpl = function () {/* this. add = function (obj) {}; this. remove = function (obj) {}; this function-defined method will generate a new method when instantiating an object, and each method of strength is different. So use the following method: */CompositeImpl. prototype. add = function (obj) {} CompositeImpl. prototype. remove = function (obj) {} CompositeImpl. prototype. update = function (obj) {}} var c1 = new CompositeImpl (); var c2 = new CompositeImpl () alert (c1.add = c2.add)

This kind of imitation is not very good. It does not check to ensure that Composite actually implements the correct method set, nor throws errors to inform programmers of problems in the program. In the end, it mainly belongs to the scope of program documents. In this way, the compliance with the interface conventions is completely self-conscious.

2) interfaces for property Detection

This method is more rigorous. All classes explicitly declare the interfaces they implement, and objects that want to deal with these classes may check these declarations. The interfaces are still comments, but now you can check an attribute to find out what interfaces a class claims to implement.

/*** Interface Composite {* function add (obj); * function remove (obj); * function update (obj ); *} * interface FormItem {* function select (obj); *} * // CompositeImpl implements interface Composite, FormItem var CompositeImpl = function () {// displayed inside the class, receives the implemented interface. In general, this is a specification. // Our Project Manager: defines an array for the internal class and the name must be fixed. this. interfaceImplments = ['composite ', 'formitem']; CompositeImpl. prototype. add = function (obj) {aler T ("Xiao Pingguo");} CompositeImpl. prototype. remove = function (obj) {} CompositeImpl. prototype. update = function (obj) {}/* CompositeImpl. prototype. select = function (obj) {}* // defines the function detection to determine whether the current object has implemented all the functions checkCompositeImpl (instance) {if (! IsImplments (instance, 'composite ', 'formitem') {throw new Error ('object cannot implements all the interface ');};} // common detection methods (core methods). The main purpose is to determine whether the sample object has implemented related interfaces. function isImplments (object) {// actual function object of the arguments object for (var I = 1, len = arguments. length; I <len; I ++) {// note that the value starts from 1 and is determined by method one by one. Var interfaceName = arguments [I]; // receives and implements the name var interfaceFound = false for each interface; // determines whether the method is implemented or fails? InterfaceImplments is defined in the specification. for (var j = 0; j <object. interfaceImplments. length; j ++) {if (object. interfaceImplments [j] = interfaceName) {interfaceFound = true; break ;}; // if not, false if (! InterfaceFound) {return false ;};} return true ;}var c1 = new CompositeImpl (); checkCompositeImpl (c1); c1.add ();

In this example, CompositeImpl declares that it has implemented the Composite interface, and adds the two interface names to an array named implementsInterfaces. Class explicitly declares what interfaces are supported. Any function that requires a specific type of parameter can check this attribute and throw an error when the required interface does not declare the column.

This method has several advantages. It provides instructions on the interfaces implemented by the class. If the required interface is not included in the list of interfaces that the class declares to support, you will see an error message. By using these errors, you can force other programmers to declare these interfaces.

The main drawback of this method is that it does not ensure that the class actually implements the self-implemented interface. You only know whether the interface is implemented by yourself. When creating a class, declare that it implements an interface, but then it misses one of the methods specified by this interface. This error is common. At this time, all the checks can pass, but the method does not exist, which will bury a hidden danger in the code. In addition, it takes some additional work to explicitly declare the interfaces supported by the class.

3) Duck Pattern Recognition Interface

In fact, it is not important for a class to declare which interfaces it supports, as long as it has methods in these interfaces. Duck-style model (this name comes from James Whitomb Riley's famous saying: "walking like a duck and screaming as a duck") is based on this understanding. It sets the method set implemented by the object as the unique criterion for judging whether it is an instance of a class. This technology can be used to check whether a class has implemented an interface. The idea behind this method is simple: if an object has all the methods with the same name as the method defined by the interface, it can be considered as implementing this interface. You can use an auxiliary function to ensure that the object has all the necessary methods:

/* The third method for implementing interfaces: Duck-type identification interface (perfect implementation method) core idea: the main purpose of a class implementation interface: all of these methods are implemented (detection methods) and fully object-oriented code is unified, implement decoupling * // 1. Interface Class --- Class Interface ==> instantiate parameters of multiple interfaces/*** Interface classes? Several * parameter 1: Interface name * parameter 2: Set of receiving methods (array) */var Interface = function (name, methods) {// determine the number of parameters of the interface if (arguments. length! = 2) {throw new Error ('the instance interface constructor arguments shocould be 2');}; this. name = name; // this. methods = methods; this. methods = []; for (var I = 0, len = methods. length; I
 
  

Unlike the other two methods, this method does not use annotations. All of these aspects can be enforced. The ensureImplements function requires at least two parameters. The first parameter is the object to be checked. Other parameters are interfaces for checking the object. This function checks whether the object represented by the first parameter implements all the methods declared by those interfaces. If any method is missing, it will throw an error, which contains useful information such as the missing method and the name of the interface that is not correctly implemented. This check can be used in any code where an object needs to implement an interface. In this example, the addForm function adds a form object only when it supports all necessary methods.

Although duck pattern recognition may be the most useful of the three methods above, it also has some disadvantages. In this method, the class does not declare the interfaces implemented by itself, which reduces the reusability of the code and lacks the self-descriptive methods of the other two methods. It requires an auxiliary class Interface and an auxiliary function ensureImplements. Besides, it only cares about the method name and does not check the parameter name, number, or type.

3. Use Cases of Interface classes

Strict type checks are not always wise. Many js programmers do not have to use interfaces or the checks it provides, and they have been working for years. When using the design pattern to implement a complex system, an interface can best reflect its value. It seems to reduce the flexibility of javascript, but in fact, because the use of interfaces can reduce the coupling between objects, it improves the flexibility of code. The interface can make the function more flexible, because you can pass any type of parameters to the function and ensure that it only uses the objects with the necessary methods.

4. Interface Class usage

It is the most important step to determine whether the interface is cost-effective in the code. The benefits of interfaces may not be obvious for small and less troublesome projects, but they only increase complexity. You need to weigh the advantages and disadvantages on your own. If you think that the advantages and disadvantages of using interfaces in projects are greater than the disadvantages, you can refer to the following instructions:
1) include the Interface class into the HTML file.
2) Check all methods in the Code with objects as parameters one by one. Find out the methods required by the normal operation of the Code for these object parameters
3) create an Interface object for every different method set you need.
4) Remove all explicit checks for constructors. Because we use a duck-like pattern, the object type is no longer important.
5) replace the original constructor check with Interface. ensureImplements.

Example
Suppose you want to create a class, which can convert some automated test results into formats suitable for viewing on the web page. The constructor of this class takes the instance of a TestResult class as the parameter. It will format and output the data encapsulated by the TestResult object at the customer's request.
Original Definition:

Var ResultFormatter = function (resultsObject) {if (! (ResultsObject instanceof TestResult) {throw newError ("ResultsFormatter: constructor requires an instance of TestResult extends argument. ")} this. resultsObject = resultsObject;} ResultFormatter. prototype. renderResults = function () {var dateOfTest = this. resultsObject. getDate (); var resultsArray = this. resultsObject. getResults (); var resultsContainer = document. createElement ('P'); var resultsHeader = document. createElement ("h3"); resultsHeader. innerHTML = "TestResults from" + dateOfTest. toUTCString (); resultsContainer. appendChild (resultsHeader); var resultList = document. createElement ("ul"); resultsContainer. appendChild (resultList); for (var I = 0, len = resultsArray. length; I
   
    

The constructor of this class checks the parameters to ensure that they are indeed instances of the TestResult class. If the parameter cannot be displayed, the constructor throws an error. With this guarantee, when writing the renderResults method, you can determine that the getDate and getResults methods are available. In fact, this does not guarantee that the required methods are implemented. The TestResult class may be modified, so that it no longer has the getDate () method. In this case, the check in the constructor can still pass, but the renderResults method fails.

In addition, this check of the constructor imposes some unnecessary restrictions. It does not allow instances of other classes to be used as parameters, even if they could have been used as intended. For example, a method named WeatherData also has the getDate and getResults methods. It can be used well by the ResultFormatter class. However, the explicit type check will prevent any instances that use the WeatherData class.
The solution is to delete the check using instanceOf and replace it with an interface. First, we need to create this interface:

//ResultSetInterface.var ResultSet =new Interface(“ResultSet”,[‘getDate','getResults']);

The code above creates a new instance of the Interface object. The first parameter is the interface name, and the second parameter is a string array. Each string is a required method name. With this interface, you can use the Interface Check to replace the instanceOf check.

var ResultFormatter = function(resultsObject){ Interface.ensureImplements(resultsObject,ResultSet); this.resultsObject = resultsObject;}ResultFormatter.prototype.renderResults= function(){ …}

The renderResults method remains unchanged. The constructor uses the ensureImplements method instead of the instanceof operator. The constructor can now accept instances of WeatherData or any other classes required for implementation. We only modified several lines of the ResultFormatter class code to make the check more accurate and tolerant.

5. Interface-dependent Design Mode

  • Factory Model
  • Combination Mode
  • Decoration Mode
  • Command mode

The above is an introduction to the implementation of interfaces in the JavaScript design mode. I hope this will help you learn more.

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.