Home >Web Front-end >JS Tutorial >Detailed interpretation of the flyweight pattern in JavaScript design pattern programming

Detailed interpretation of the flyweight pattern in JavaScript design pattern programming

亚连
亚连Original
2018-05-21 13:38:57962browse

The flyweight pattern is most suitable for solving performance problems caused by creating a large number of similar objects. This article will summarize the use of the flyweight pattern in JavaScript design pattern programming, including examples of utilization during DOM operations:

The flyweight pattern is different from the general design pattern. It is mainly used to optimize the performance of the program. It is most suitable for solving performance problems caused by a large number of similar objects. Flyweight mode analyzes application objects and parses them into intrinsic and extrinsic data to reduce the number of objects and thereby improve application performance.

Basic knowledge

Flyweight mode reduces the number of objects by sharing a large number of fine-grained objects, thereby reducing object memory and improving application performance. The basic idea is to decompose the components of existing similar objects and expand them into sharable intrinsic data and unshareable extrinsic data. We call the objects of intrinsic data flyweight objects. Usually a factory class is also needed to maintain internal data.
In JS, the Flyweight mode mainly consists of the following roles:
(1) Client: a class used to call the Flyweight factory to obtain intrinsic data, usually the objects required by the application,
(2) Flyweight factory: a class used to maintain flyweight data
(3) Flyweight class: a class that maintains internal data

Implementation and application of flyweight pattern

General implementation

Let’s take an example to illustrate: Apple mass-produces iPhones. Most of the iPhone data such as model and screen are the same, and a few parts of the data are the same. For example, memory is divided into 16G, 32G, etc. Before using flyweight mode, we wrote the code as follows:

function Iphone(model, screen, memory, SN) {
  this. model = model;
  this.screen = screen;
  this.memory = memory;
  this.SN = SN;
}
var phones = [];
for (var i = 0; i < 1000000; i++) {
  var memory = i % 2 == 0 ? 16 : 32;
  phones.push(new Iphone("iphone6s", 5.0, memory, i));
}

In this code, one million iPhones are created, and each iPhone applies independently a memory. But if we look closely, we can see that most iPhones are similar, except that the memory and serial number are different. If it is a program with relatively high performance requirements, we must consider optimizing it.
For programs with a large number of similar objects, we can consider using the flyweight mode to optimize it. We have analyzed that most iPhone models, screens, and memories are the same, so this part of the data can be shared, which is flyweight. The intrinsic data in the model defines the flyweight class as follows:

function IphoneFlyweight(model, screen, memory) {
  this.model = model;
  this.screen = screen;
  this.memory = memory;
}

We define the flyweight class of iPhone, which contains three data: model, screen and memory. . We also need a flyweight factory to maintain this data:

 var flyweightFactory = (function () {
  var iphones = {};
  return {
    get: function (model, screen, memory) {
      var key = model + screen + memory;
      if (!iphones[key]) {
        iphones[key] = new IphoneFlyweight(model, screen, memory);
      }
      return iphones[key];
    }
  };
})();

In this factory, we define a dictionary to save the flyweight object and provide a method Get the flyweight object according to the parameters. If it exists in the dictionary, it will be returned directly. If not, it will be created and returned.
Then we create a client class, which is modified from the iphone class:

 function Iphone(model, screen, memory, SN) {
  this.flyweight = flyweightFactory.get(model, screen, memory);
  this.SN = SN;
}

Then we still generate multiple iphone

var phones = [];
for (var i = 0; i < 1000000; i++) {
  var memory = i % 2 == 0 ? 16 : 32;
  phones.push(new Iphone("iphone6s", 5.0, memory, i));
}
console.log(phones);

The key here is this.flyweight = flyweightFactory.get(model, screen, memory) in the Iphone constructor. This code obtains flyweight data through the flyweight factory. In the flyweight factory, if an object with the same data already exists, the object will be returned directly. Multiple iphone objects share this part of the same data, so the original similar data has been Greatly reduced memory usage.

Application of flyweight mode in DOM

A typical application of flyweight mode is DOM event operation. The DOM event mechanism is divided into event bubbling and event capture. Let’s briefly introduce the two:
Event bubbling: The bound event starts to trigger from the innermost element, and then bubbles to the outermost element.
Event capture: The bound event starts from the outermost element. The element starts to trigger and then passes to the innermost layer
Suppose we have a menu list in HTML

<ul class="menu">
  <li class="item">选项1</li>
  <li class="item">选项2</li>
  <li class="item">选项3</li>
  <li class="item">选项4</li>
  <li class="item">选项5</li>
  <li class="item">选项6</li>
</ul>

Click on the menu item and perform the corresponding operation, we To bind events through jQuery, you usually do this:

$(".item").on("click", function () {
  console.log($(this).text());
})

Bind events to each list item, and click to output the corresponding text. There is no problem in this way for the time being, but if it is a very long list, especially if it is a very long list on the mobile terminal, there will be performance problems, because each item is bound to an event and takes up memory. But these event handlers are actually very similar, so we need to optimize them.

$(".menu").on("click", ".item", function () {
  console.log($(this).text());
})

Event binding in this way can reduce the number of event handlers. This method is called event delegation, and it also uses the flyweight pattern. principle. The event handler is the common inner part, and each menu item's respective text is the outer part. Let’s briefly talk about the principle of event delegation: when you click a menu item, the event will bubble up from the li element to the ul element. When we bind the event to ul, we actually bind an event, and then use the target in the event parameter event to Determine which element was clicked, for example, the first low-level li element, event.target is li, so that you can get the specific clicked element, and perform different processing according to different elements.

Summarize

Flyweight mode is a means of optimizing program performance. It reduces the number of objects by sharing common data to optimize the program. Flyweight mode is suitable for scenarios with a large number of similar objects and high performance requirements. Because the flyweight mode requires the separation of internal and external data, which increases the logical complexity of the program, it is recommended to use the flyweight mode only when performance is required.

Benefits of the flyweight model:
It can reduce the resource requirements of web pages by several orders of magnitude. Even if the application of flyweight mode cannot reduce the number of instances to one, you can still benefit a lot from it.

This kind of saving does not require extensive modification of the original code. After creating the manager, factory, and flyweight, the only modification to the code that needs to be made is to change from directly instantiating the target class to calling a method of the manager object.

Disadvantages of flyweight mode:
If it is used in unnecessary places, the result will be detrimental to the efficiency of the code. While this mode optimizes the code, it also increases its complexity, which makes debugging and maintenance difficult.

The reason why it hinders debugging is because now there are three places where things can go wrong: the manager, the factory, and the flyweight.

This optimization will also make maintenance more difficult. Instead of a clear structure composed of objects encapsulating data, what you now face is a bunch of fragmented and messy things. The data is saved in at least two places. It is best to annotate the internal and external data.

This optimization should only be performed when necessary. A trade-off must be made between operational efficiency and maintainability. If you're not sure whether you need to use flyweight mode, you probably don't need it. Flyweight mode is suitable for situations where the system resources are almost fully used and some kind of optimization is obviously needed.

This mode is particularly useful for Javascript programmers because it can be used to reduce the number of DOM elements used on a web page, knowing that these elements consume a lot of memory. Combining this pattern with organizational patterns such as the Composite pattern can develop complex, feature-rich web applications that can run smoothly in any modern Javascript environment.

Applicable occasions of flyweight mode:
A large number of resource-intensive objects must be used in web pages. If only a few such objects are used, this optimization is not cost-effective.

At least part of the data stored in the object can be converted into external data. Furthermore, storing this data outside the object should be relatively inexpensive, otherwise the performance implications of this approach are virtually meaningless. Objects that contain a lot of basic code and HTML content may be better suited for this optimization.

After separating the external data, the number of unique objects is relatively small.

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

javascriptSeveral methods of array definition (graphic tutorial)

AboutjavascriptFlow control statement collection (graphic tutorial)

In-depth understanding and practical combat of javascript Function function (attached Code)

The above is the detailed content of Detailed interpretation of the flyweight pattern in JavaScript design pattern programming. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn