Reading notes-JavaScript design Patterns-interface, encapsulation, and chained calls

Source: Internet
Author: User
Tags closure

JavaScript uses design patterns for three main reasons:

    1. maintainability: Design patterns help to reduce the degree of coupling between modules. This makes it easy to refactor code and swap different modules, and makes it easy for programmers to collaborate on large projects.
    2. Communication: Design patterns provide a common set of terminology for dealing with different types of objects. Programmers can succinctly describe how their systems work.
    3. Performance: Using some optimization performance mode, can greatly improve the execution efficiency of the program, such as the ability to enjoy meta-mode and proxy mode

At the same time, abuse of design patterns can have some consequences:

    1. Complexity: Code becomes complex and novice hard to understand
    2. Performance: Most design patterns reduce the performance of the code more or less

Easy to achieve, reasonable use is the difficulty. One suggestion: Try to choose the most suitable one, but don't sacrifice performance too much.

interface: An interface is a means to illustrate what methods the object has, although it indicates the semantics of these methods, but it does not specify the implementation.

imitating interfaces in JavaScript

One: Describe the interface with annotations

/**/var function function function  functionfunction() {}

This imitation is just stuck in the document phase. There is no check on whether the correct method is implemented, nor does it throw an error, relying entirely on consciousness.

Second: Use the property check to imitate the interface:

/*interface composite{function Add (child), function Remove (child), function Getchild (index), interface formitem{Fun Ction Save (); } */varCompositeform =function(id,method,action) { This. implementsinterfaces = [' Composite ', ' FormItem '];}functionAddForm (forminstance) {if(!implements (forminstance, ' Composite ', ' FormItem '){        Throw NewError ("Object does not implement a required interface."); })}functionimplements (object) { for(vari=1;i<arguments.length;i++){        varInterfaceName =Argument[i]; varInterfacefound =false;  for(varj=0;j<object.implementsinterfaces.length;j++){            if(object.implementsinterfaces[j]==InterfaceName) {Interfacefound=true;  Break; }        }        //There are no interfaces found        if(!interfacefound) {            return false; }    }    //all the interfaces were found.    return true;}

Here, Compositeform claims to have implemented the ' Composite ', ' FormItem ' interface, by adding the names of the two interfaces to an array of objects and explicitly declaring their own supported interfaces.

Any function that requires its arguments to be of a particular type can examine this property and throw an exception when the implementation method is not found.

Three, duck-type imitation interface

The idea behind the method set of an object's implementation as the sole criterion for determining that it is not a class is simple: If the object has all the methods with the same name as the method defined by the interface, it can be assumed that it implements this interface.

Definition of the Interface class

/** Define interface methods*/varInterface =function(name,methods) {if(arguments.length!=2){        Throw NewError ("Interface constructor called with" + Arguments.length + "arguments, but expected exactly 2.");    };  This. Name =name;  This. Methods = [];  for(vari = 0,len = methods.length-1; i < Len; i++) {        if(typeofmethods[i]!== ' String '){            Throw NewError ("Interface constructor expects method names to is" + "passed in as a string.")); }         This. Methods.push (Methods[i]); };};/** Extended static verification method for Interface*/interface.ensureimplements=function(obj) {if(arguments.length<2){        Throw NewError ("Function interface.ensureimplements called with" +Arguments.length+ "arguments, but expected at least 2.");    };  for(vari = 0,len = methods.length-1; i < Len; i++) {        varinterface =Arguments[i]; if(interface.constructor!==interface) {            Throw NewError ("Function Interface.ensureimplements expects arguments" + "both and above to be instances of INTERFAC E. ");        };  for(varj = 0,methodslen = Interface.methods.length; j<methodslen; J + +) {            varMETHOD =Interface.methods[j]; if(!object[method]| |typeofObject[method]!== ' function '){                Throw NewError ("Function Interface.ensureImplements:object" + "does not implement the" +Interface.name+ "interface. Method "+ Method +" is not found. ");        };    }; };}

Inherited

Implementation of chain-type inheritance

function Extend (subclass,superclass) {    varfunction() {};     = Superclass.prototype;     New F ();     = Subclass;     = Superclass.prototype;     if (SuperClass.prototype.constructor = = Object.prototype.constructor)        {= superclass;    }}

Superclass is used to weaken the coupling between subclasses and super-classes. Also ensure that the constructor of the superclass is set correctly.

The implementation of prototype inheritance, in fact, is copy inheritance, implemented in the following way.

function Clone (object) {    function  F () {};     = object;     return New F;}

Actually returns an empty object with the given object as its native object.

The implementation of the mixed-element class. There is a reuse method that does not need to use strict inheritance, if you want to use a function in multiple classes, you can expand the way to let these classes share the function, the practice: first create a class containing a variety of common methods, and then use it to extend the other classes, which contains a generic method of the class is called a meta-class.

The implementation method of the mixed element class:

functionaugment (Receivingclass,givingclass) {//if has the third arg    if(arguments.length[2]){         for(varI=2,len = arguments.length;i<len;i++) {Receivingclass.prototype[arguments[i]]=Givingclass.prototype[arguments[i]]; }    }Else{         for(MethodNameinchGivingclass.prototype) {            if(!Receivingclass.prototype[methodname]) {Receivingclass.prototype[methodname]=Givingclass.prototype[methodname]; }        }    }}

Packaging

Encapsulation is the concealment of the data representation and implementation details inside the object. If you want to access a encapsulated object, you can only use the defined operation as a way.

In JavaScript, we don't have keywords, we can only use the concept of closures to create private properties and methods.

There are three basic patterns for JavaScript to create objects.

The portal is open, with an underscore for private methods and properties, and a closed package to create a true private member.

varBook =function(newisbn,newtitle,newauthor) {//Private Properties    varIsbn,title,anthor; functionCHECKISBN (ISBN) {...}; //privileged methods, which can access private variables     This. GETISBN =function(){        returnISBN;    };  This. SETISBN =function(){        if(!CHECKISBN (NEWISBN))Throw NewError (' Book:invalid ISBN. ')); ISBN=NEWISBN;    };  This. GetTitle =function(){        returnNewtitle;    };  This. Settitle =function(newtitle) {title= newtiyle| | ";    };  This. Getauthor =function(){        returnauthor;    };  This. Setauthor =function(newauthor) {author= newauthor| | ";    };  This. SETISBN (NEWISBN);  This. Settitle (Newtitle);  This. Setauthor (Newauthor);}//methods that do not require direct access to private properties can be declared in prototype. Book.prototype ={display:function(){...}}

Higher-level object creation.

varBook = (function(){    //private static Property    varNumofbooks = 0; //private static Methods    functionCHECKISBN (ISBN) {...}; return function(newisbn,newtitle,newauthor) {//Private Properties        varIsbn,title,anthor; //privileged methods, which can access private variables         This. GETISBN =function(){            returnISBN;        };  This. SETISBN =function(){            if(!CHECKISBN (NEWISBN))Throw NewError (' Book:invalid ISBN. ')); ISBN=NEWISBN;        };  This. GetTitle =function(){            returnNewtitle;        };  This. Settitle =function(newtitle) {title= newtiyle| | ";        };  This. Getauthor =function(){            returnauthor;        };  This. Setauthor =function(newauthor) {author= newauthor| | ";        }; Numofbooks++; if(Numofbooks > 50)Throw NewERR (' book:only instances of book can be created. '));  This. SETISBN (NEWISBN);  This. Settitle (Newtitle);  This. Setauthor (Newauthor); }})();//methods that do not require direct access to private properties can be declared in prototype. Book.prototype ={display:function(){...}}

A few simple notes:

    • First, a closure is created with () (), executed immediately, and another function is returned.
    • Second, the return function is assigned to book, which becomes a constructor.
    • Three times, the inner function of the book call is instantiated, and the outer layer is simply used to create a closure that can hold a static private member.
    • Four times, CHECKISBN is designed as a static method, so each instance of book does not generate the static method, which acts on the construction class, not on the instance.
    • Five times, these static methods are included in the closure, so other methods in the closure can be accessed, and only one copy exists in memory.
    • Six times, these methods declare that the private property defined in the constructor cannot be accessed outside the constructor, not the privileged method.
    • Seven times to determine whether a private method should be designed as a static method, a rule of thumb is to see if it accesses any instance data, and if not, it is more efficient to design it as a static method.

Reading notes-JavaScript design Patterns-interface, encapsulation, and chained calls

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.