In-depth understanding of JavaScript design Patterns

Source: Internet
Author: User

Design Patterns

Design patterns are naming, abstracting, and identifying common design structures that are useful for reusable object-oriented design. Design patterns determine the classes and their entities, their roles and collaborations, and their assigned responsibilities.

Each design pattern focuses on an object-oriented design challenge or problem. It describes whether it can be used under the constraints of other designs, the consequences and gains and losses after using it. Because we have to eventually implement our design patterns, each design pattern provides examples of code to illustrate the implementation.

While design patterns are described as object-oriented, they are based on solutions that have been implemented by mainstream object-oriented languages ... ".

Kinds

Design patterns can be divided into several different types. In this part we will be divided into three categories: creation design pattern, structure design pattern, behavior design pattern.

Create Design Patterns

The creation design pattern focuses on the mechanism method of object creation, through which objects are created in a way that adapts to the working environment. The basic object creation method may add additional complexity to the project, and the purpose of these patterns is to solve the problem by controlling the creation process.

Some of the patterns that fall into this category are: Constructor mode (Constructor), Factory mode (Factory), abstract Factory mode (abstraction), prototype mode (PROTOTYPE), Singleton mode (Singleton), and builder mode (builder).

Structural Design Patterns

structural patterns focus on the composition of objects and the way in which they are commonly recognized to implement relationships between different objects. This pattern helps to change a part of the system, and the entire system structure does not need to change. The model also helps to reorganize parts of the system that do not achieve a certain purpose.

The modes under this category are: Decoration mode, appearance mode, enjoy meta mode, adapter mode and proxy mode.

Behavioral Design Patterns

Behavioral Patterns focus on improving or streamlining communication between different objects in the system.

Behavioral patterns include: iteration mode, Mediator mode, observer pattern, and visitor pattern.

Below, we will deepen our understanding of design patterns by introducing each of the common design patterns separately.

Constructor mode

A constructor is a special function that initializes an object when the memory of the new object is allocated. The object constructor is used to create a special type of object, first it is intended to be used by the object, and secondly, when the object is first created, by receiving parameters, the constructor is used to assign values to the properties and methods of the member.

Because JavaScript does not support the concept of classes, you must initialize the object by using the new keyword through the constructor. A basic constructor code is as follows:

function Car (model, year, miles) {   This.model = model;  This.year = year;  This.miles = miles;   this.tostring = function () {    return This.model + "have done" + This.miles + "Miles";  };}  Use://We can sample a carvar civic = new Car ("Honda Civic", "20000"), var mondeo = new Car ("Ford Mondeo", 2010, 5000); Open the browser console to view the output values of the ToString () method for these objects//outputs of the ToString () methods being called on//these objectsconsole.log (Civic.tos Tring ()); Console.log (mondeo.tostring ());

However, it is cumbersome to inherit, and functions such as ToString are redefined in each object created by the car constructor. So we're going to use prototypes to implement the best constructors:

function Car (model, year, miles) {   This.model = model;  This.year = year;  This.miles = miles; }  //Note Here we use the note here, the We are using Object.prototype.newMethod instead of//Object.prototype, To avoid US redefining the prototype object Car.prototype.toString = function () {  return This.model + "have done" + This.miles + "Miles";}; Use: var civic = new Car ("Honda Civic", "20000"), var mondeo = new Car ("Ford Mondeo", 2010, 5000); Console.log (Civic.tostring ()); Console.log (mondeo.tostring ());

Factory mode

A factory can provide a common interface for creating objects, where we can specify the type of factory objects we want to create. It's easy to say, like a water dispenser, coffee or milk depends on which button you press.

The simple factory model can be embodied in the creation of Ajax objects, can be understood through the $.ajax method in jquery, or it can be understood by an Ajax method that I write myself, with the address: Http://runjs.cn/code/j5dkikwu


Ajax ("Test002.txt", {type: "GET", Data:{name: "Liuf", Age:23},onsuccess:function (RESPONSETEXT,XHR) { document.getElementById ("Input"). Value=responsetext;},onfail:function () {//document.write ("fail");});

Ajax is actually a factory method, as to whether to use the Get method or the Post method, is determined by the following code. That's what I said earlier. "A factory can provide a public interface for creating objects, where we can specify the type of factory objects we want to be created."

Single-Case mode

The singleton pattern is called because it restricts a class to have only one instantiated object . The classic implementation is to create a class that contains a method that, when no object exists, creates a new instance object. If the object exists, this method simply returns a reference to the object. But JavaScript is inherently non-class, so simply put, is not created, there is no direct use to create.

So let's take a look at the real case, and a mask layer appears after clicking on a button, which is a common requirement. The code is as follows:

var createmask = function () {    return Document,body.appendchild (  document.createelement (div)  );} $ (' button '). Click (function () {    var mask  = Createmask ();    Mask.show (); })

The problem with this writing is that every call to Createmask creates a new div, although it can remove it while hiding the mask layer, but this can still lead to performance loss, so the following improvements are made to create the div at the beginning of the page, with the following code:

var mask = document.body.appendChild (document.createelement (' div ')); $ (' button '). Click (function () {    mask.show ();})

This ensures that the page will only create a mask layer, but there is also a problem, that is, if the user does not need to use this div, it is not in vain to create it. So we can use a variable to determine whether a DIV has been created, the code is as follows:

var mask; var createmask = function () {if (mask) return mask; else{mask = Document,body.appendchild (  document.createelement (d IV)  ); return mask; } }

This looks good, but does mask, as a global variable, cause pollution? So the best way to do this is as follows:

var createmask = function () {  var mask;  return function () {       Return mask | | (Mask = document.body.appendChild (document.createelement (' div.))  }} ()

This is what we said earlier, "No creation, no direct use." Yes, the singleton mode is so simple, the design pattern is not difficult, in fact, we have been useful in programming, but we did not find it.

Bridging mode

Bridging mode separates the implementation part from the abstract part so that the two can change independently. Bridging mode is very common when implementing APIs.

Let's take JavaScript's foreach method as an example:


ForEach = function (ary, FN) {for  (var i = 0, L = ary.length; i < L; i++) {    var c = ary[i];    if (Fn.call (c, I, c) = = = False) {      return false;}}   }

As you can see, the foreach function does not care about the specific implementation in FN . The logic inside the FN is not affected by the rewrite of the foreach function.

Use the following code:

foreach ([n/A], function (i, n) {  alert (n*2)}) foreach ([n/A], function (i, n) {   alert (n*3)})


Appearance mode

The appearance pattern is a ubiquitous pattern, and the façade mode provides a high-level interface, which makes the client or subsystem calls more methods. Like what:

var getName = function () {  return ' Svenzeng '}var getsex = function () {   return ' man '}

Now I'm going to call two methods, I can use a higher-level interface to invoke:

var getuserinfo = function () {  var info = getName () + getsex ();  return info;}

This makes it easy to assemble, and if you write two to a function in the first place, you cannot call one of them alone.


Enjoy meta mode

The enjoy meta-mode is a classic structured solution for optimizing repetitive, slow, and inefficient data sharing code. The goal is to reduce the use of memory in your application (for example, application configuration, status, and so on) by sharing as much data as possible with related objects. In layman's words, the use of meta-mode is used to reduce the number of objects required by the program.

For example, a waterfall stream in a Web page, or a WEBQQ friend list, creates a new div every time you pull down. So what if there's a pair of div? Isn't the browser a dead card? So we will think of a way to remove the div that has disappeared out of sight, so that the page can maintain a certain number of nodes, but the frequent deletion and addition of nodes, will bring a lot of performance overhead.

You can use the enjoy meta mode at this time, and enjoy meta mode to provide some shared objects for reuse. For example, the page can only display 10 div, which is always in the user's line of sight in the 10 div can be written as the enjoyment of the yuan.

The principle is actually very simple, put the newly hidden div into an array, when the div needs to be taken from the array, if the array is not already, and then re-create a. The div in this array is the sharing element, each of which can be used as a carrier for any user information. The code is as follows:

var Getdiv = (function () {    var created = [];    var create = function () {          return Document.body.appendChild (document.createelement (' div '));    }    var get = function () {         if (created.length) {              return created.shift ();          } else{                return Create ();           }     } /* A hypothetical event that listens for a div that just disappears out of sight, and can actually be implemented by listening to the scroll bar position *      /userinfocontainer.disappear (function (div) {              Created.push (div);        }) }) ()  var div = getdiv ();  div.innerhtml = "${userinfo}";

Adapter mode

The adapter pattern is to convert the interface of one class into another interface that the customer wants. In layman's words, it will be like an Apple phone can not be poor in the computer chassis, there must be a converter, and this converter is the adapter.

In the program, the adapter mode is often used to fit 2 interfaces, for example, you are now using a custom JS library. There's a method $id () that gets the node based on the ID. One day you think the $ in jquery is more cool, but you don't want your engineers to learn new libraries and grammars. That one adapter will get you to do the job.

$id = function (ID) {   return jQuery (' # ' + ID) [0];}

So you don't have to change one more.

Proxy mode

The proxy mode is to manipulate the access to one object to another proxy object. In a more general sense, programmers write daily newspapers, and the daily papers are eventually reviewed by the director, but if everyone is sent directly to the Director, the Director will not be able to work. So each person will send their daily newspaper to their leader, and then forwarded by the leader to the director. The leader is the agent.

There are many scenarios in which the proxy mode is used in programming, such as when a large number of DOM operations are done, we create the document fragments first, and then unify them into the DOM tree.

Examples are as follows:


Broker mode

The mediator pattern is the shared-by-observer object in the Observer pattern. The direct publish/subscribe relationship between objects in this system is sacrificed, instead of maintaining the central node of a communication. There is a difference between the broker pattern and the proxy pattern, the difference is as follows:

The Mediator object allows the objects to be decoupled from each other without needing to refer to each other, and can independently change the interaction between the transparent. In layman's words, banks can also be seen as intermediaries between depositors and lenders. Depositor a doesn't care who borrowed his money at last. Lender B also does not care about whose deposits the money he borrowed comes from. Because of the presence of intermediaries, this transaction has become so convenient.

In programming, is the controller in the famous MVC structure a mediator? Take backbone for example. The data in a mode is not sure which view is used last. The data required for view can also be from any mode. All binding relationships are determined in controler. The mediator turns the complex many-to-many relationship into 2 relatively simple 1-to-many relationships.

The sample code is as follows:

var mode1 = Mode.create (),  mode2 = Mode.create (), var view1 = View.create (),   view2 = View.create (), var controler1 = Controler.create (mode1, View1, function () {  view1.el.find (' div '). bind (' click ', Function () {    this.innerhtml = mode1.find (' data ');  } )}) var controler2 = controler.create (Mode2 view2, function () {  view1.el.find (' div '). bind (' click ', function () { c6/>this.innerhtml = mode2.find (' data ');  } )})
Observer pattern

The observer pattern is such a design pattern. An object, called the Observer, maintains a set of objects called observers that depend on the observer, who automatically notifies them of any changes in their state.

When an observer needs to notify the observer of some change, it will use the broadcast method, which may contain some data specific to this notification.

When a particular observer is no longer required to accept notification from the observer it is registering, the observer can remove it from the group being maintained.

The popular point of view is that the interviewer is the observer, and the person waiting to be notified is the observer.

The DOM events that are normally touched in JavaScript are actually an embodiment of the Observer pattern:


Div.onclick  =  function Click () {    alert (' click ')}

As soon as you subscribe to the div's Click event, when you click on the div, the click function executes.

The observer pattern can be very good for decoupling between modules, and if a multi-person project, I am responsible for map and gamer mode:


LoadImage (  imgary,  function () {map.init (); Gamer.init (); } )
<p> and others responsible for the maintenance of LoadImage method, if one day, I want to add a sound module, and I have no right to use other people's code, only empty waiting for others to come back add: </p><pre name= "code" class= " HTML ">loadimage (  imgary,  function () {map.init (); Gamer.init (); Sount.init (); } )

So we can make the following changes:

Loadimage.listen (' Ready ', function () {     map.init ()}) Loadimage.listen ("Ready", function () {    gamer.init ();}) Loadimage.listen (' Ready ', function () {    sount.init ();})

After the loadimage is complete, no longer cares about what the future will send, it only needs to send a signal:


Loadimage.trigger (' ready ');


All objects listening to the ready event will be notified. This is the application scenario for the Observer pattern.


Speaking of which, the usual design patterns are finished, and a deeper understanding of the JavaScript series will come to an end.







Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

In-depth understanding of JavaScript design Patterns

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.