


Detailed explanation of the classic JavaScript design pattern singleton pattern
Peter Seibel, the author of "Practical Common Lisp", once said that if you need a pattern, there must be something wrong. The problem he refers to is that because of the inherent flaws of language, he has to find and summarize a universal solution.
Whether it is weakly typed or strongly typed, static or dynamic language, imperative or declarative language, every language has its inherent advantages and disadvantages. A Jamaican athlete has some advantages in sprinting and even boxing, but lacks in practicing yoga.
Warlock and Shadow Priest can easily become an excellent support, but an enemy Mage flying around the map with Macon on his back will be a little awkward. Switching to a program, it may take a lot of effort to implement decorators in static languages, but js can throw methods on objects at any time, so that the decorator pattern has become a standard in js. It's tasteless.
There are relatively few books about Javascript Design Pattern, "Pro javaScript Design" Patterns" is a relatively classic book, but the examples in it are quite lengthy, so I will summarize my understanding based on the codes I have written at work. If there is any deviation in my understanding, please feel free to correct me.
The definition of singleton mode is to generate the only instance of a class, but js itself is a "classless" "language. Many articles about js design patterns use {} as a singleton, which barely makes sense. Because there are many ways to generate objects in js, let's take a look at another more meaningful singleton.
There is such a common requirement. When a button is clicked, a mask layer needs to pop up on the page. For example, when you click to log in at web.qq.com.
#The code that generates the gray background mask layer is easy to write.
var createMask = function(){ return document,body.appendChild( document.createElement(p) ); } $( ‘button’ ).click( function(){ Var mask = createMask(); mask.show(); })
The problem is , this mask layer is globally unique, so every time createMask is called, a new p will be created. Although it can be removed when the mask layer is hidden, it is obviously unreasonable to do so.
Look again The second option is to create this p at the beginning of the page. Then use a variable to reference it.
var mask = document.body.appendChild( document.createElement( ”p’ ) ); $( ”button’ ).click( function(){ mask.show(); } )
In this way, only the page will be created A mask layer p, but another problem arises. Maybe we will never need this mask layer, which is a waste of p. Any operation on the dom node should be very stingy.
What if we can use a variable to determine whether p has been created?
var mask; var createMask = function(){ if ( mask ) return mask; else{ mask = document,body.appendChild( document.createElement(p) ); return mask; } }
Looks good, here we have indeed completed a function that generates a single column object. Let's take a closer look at what is wrong with this code.
First of all, this function has certain side effects. The reference to the external variable mask is changed within the function body. In a multi-person collaboration project, createMask is an unsafe function. On the other hand, the global variable mask is not It's not necessary. Let's improve it again.
var createMask = function(){ var mask; return function(){ return mask || ( mask = document.body.appendChild( document.createElement(‘p’) ) ) } }()
Use a simple closure to wrap the variable mask, at least for the createMask function, it is closed.
You may see this and feel that the singleton model is too simple. Indeed, some design patterns are very simple. Even if you have never paid attention to the concept of design patterns, you have used some designs in your daily code unknowingly. Patterns. Just like many years ago when I understood what the old man’s cart was, I also thought about it. It turns out that this is the old man’s cart. The 23 design patterns in GOF have also been used for a long time in software development. Patterns that exist and are used repeatedly. If the
programmerdoes not clearly realize that he has used certain patterns, then he may miss a more appropriate design next time (this passage is from "Yukihiro Matsumoto's Programming World" ).Back to the topic, the previous singleton still has shortcomings. It can only be used to create a mask layer. What if I need to write a function to create a unique xhr object? Can it be done? Find a general singleton wrapper.
Functions in js are of the first type, which means that functions can also be passed as parameters. Take a look at the final code.
var singleton = function( fn ){var result;return function(){return result || ( result = fn .apply( this, arguments ) );}} var createMask = singleton( function(){ return document.body.appendChild( document.createElement(‘p’) ); })
Use a variable to save the first A one-time return value, if it has been assigned, then the variable will be returned first in subsequent calls. The code that actually creates the mask layer is passed to the singleton wrapper through the
callback function. This method is actually called Bridge mode. About the bridge mode, I will talk about it a little later.However, the singleton function is not perfect, it still needs a variable result. Register the reference of p. Unfortunately, the functional characteristics of js are not enough to completely eliminate declarations and statements.
Related articles:
Detailed explanation of JavaScript design pattern classic strategy pattern
JavaScript design pattern classic simple factory pattern code example
##javascript design Detailed introduction to the observer pattern
The above is the detailed content of Detailed explanation of the classic JavaScript design pattern singleton pattern. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

In the Java framework, the difference between design patterns and architectural patterns is that design patterns define abstract solutions to common problems in software design, focusing on the interaction between classes and objects, such as factory patterns. Architectural patterns define the relationship between system structures and modules, focusing on the organization and interaction of system components, such as layered architecture.

The decorator pattern is a structural design pattern that allows dynamic addition of object functionality without modifying the original class. It is implemented through the collaboration of abstract components, concrete components, abstract decorators and concrete decorators, and can flexibly expand class functions to meet changing needs. In this example, milk and mocha decorators are added to Espresso for a total price of $2.29, demonstrating the power of the decorator pattern in dynamically modifying the behavior of objects.

1. Factory pattern: Separate object creation and business logic, and create objects of specified types through factory classes. 2. Observer pattern: allows subject objects to notify observer objects of their state changes, achieving loose coupling and observer pattern.

Design patterns solve code maintenance challenges by providing reusable and extensible solutions: Observer Pattern: Allows objects to subscribe to events and receive notifications when they occur. Factory Pattern: Provides a centralized way to create objects without relying on concrete classes. Singleton pattern: ensures that a class has only one instance, which is used to create globally accessible objects.

The Adapter pattern is a structural design pattern that allows incompatible objects to work together. It converts one interface into another so that the objects can interact smoothly. The object adapter implements the adapter pattern by creating an adapter object containing the adapted object and implementing the target interface. In a practical case, through the adapter mode, the client (such as MediaPlayer) can play advanced format media (such as VLC), although it itself only supports ordinary media formats (such as MP3).

TDD is used to write high-quality PHP code. The steps include: writing test cases, describing the expected functionality and making them fail. Write code so that only the test cases pass without excessive optimization or detailed design. After the test cases pass, optimize and refactor the code to improve readability, maintainability, and scalability.

The Guice framework applies a number of design patterns, including: Singleton pattern: ensuring that a class has only one instance through the @Singleton annotation. Factory method pattern: Create a factory method through the @Provides annotation and obtain the object instance during dependency injection. Strategy mode: Encapsulate the algorithm into different strategy classes and specify the specific strategy through the @Named annotation.

The advantages of using design patterns in Java frameworks include: enhanced code readability, maintainability, and scalability. Disadvantages include complexity, performance overhead, and steep learning curve due to overuse. Practical case: Proxy mode is used to lazy load objects. Use design patterns wisely to take advantage of their advantages and minimize their disadvantages.
