Prototype

Prototype is the creation pattern. It is neither a factory nor a direct New. Instead, it creates objects as copies.

Intent: Specify the type of object to create with prototype instances, and create new objects by copying these prototypes.

For example,

If you don’t understand the above description, it doesn’t matter. Design patterns need to be used in daily work. Examples will help you understand better.

Do the key

Obviously, for the sake of house security, we should try to make sure that each key can only open one door. Each key structure is more or less different, but very similar. The person who makes the key makes a new one according to the key you give him exactly the same.

Two state tables

When the website does non-stop maintenance, suppose the maintenance content is to pay 100 yuan more cash to each premium member account, now need to change the database table. Known:

  1. The database table has tens of millions of data, among which there are thousands of advanced members. In order to facilitate the call, it has been cached in the middle layer, and the corresponding cache will be updated after the database corresponding ID is updated.
  2. It takes several minutes for thousands of data modification statements to be executed, and you can’t accept the problem of user data being out of sync in those minutes.

A common practice is to generate a copy of the premium membership list, instead of the database cache results, as long as the database reads the corresponding membership ID from the copy list, add a column of status flags to the data table, the copy is removed after the operation, update the premium membership cache.

But how do you make copies of the premium membership list? If re-query from tens of millions of user data directly, there will be a high database query cost.

Template components

In a general-purpose scaffolding system, we can set a block that is dragged to a page as a “template”, which can be dragged again as a new component to any point and instantiated any time. Actually, it’s a piecewise copy and paste, so how do you do that?

Intention to explain

The solution to the above problems is very simple, is based on the existing object to copy, the efficiency is higher than a New one, or factory mode.

Intent: Specify the type of object to create with prototype instances, and create new objects by copying these prototypes.

A prototype instance is an object chosen to copy a template, such as the prototype key you give your boss in the key example. Existing cached premium membership lists in both state tables; The component selected from the template component. Then, copy these prototypes to create the objects you want.

To think abstractly, if each key follows the Prototype interface and provides the clone() method to copy itself, you can quickly copy any key. The key factory can’t solve the problem that every key is different. All we need is an exact copy of one key. It’s easiest to make a copy.

In the advanced member status table example, the cost of querying the database is high, but the time is negligible if you just copy the already queried list, so the most economical solution is to copy directly rather than reconnect to the database through factory mode and execute the query.

This is especially true of template components, where there are no base classes for defining so many component instances. As long as each component provides a clone() function, it can immediately copy any component instance, which is undoubtedly the most cost-effective solution.

As you can see from this point, the essence of prototyping is that objects provide clone() methods, which can be difficult to implement with varying degrees of difficulty.

Generally speaking, it is recommended to use deep copy for copying in prototype mode. After all, new objects should not affect old objects. However, when the performance of deep copy is relatively high, the combination of deep and shallow copy can be considered, that is, shallow copy is used for unmodified data in new objects and deep copy is used for data that may be modified.

chart

Prototype is an interface that describes how an object can clone itself (for example, it must have a Clone () method). ConcretePrototype is a concrete implementation of cloning. Different objects have different implementations to copy themselves.

The code example

The following example is written in typescript.

class Component implements Prototype {
  / * ** component name* /
  private name: string
 / * ** Component versions* /  private version: string   / * ** Copy itself* /  public clone = (a)= > {  // The constructor is omitted, presumably passing name and version  return new Component(this.name, this.version)  } } Copy the code

As you can see, the Component that implements the Prototype interface must implement the Clone method so that any Component that performs a copy can call the Clone function directly, regardless of how each Component is implemented.

This shows that the prototype pattern is similar to the Factory and Builder patterns in that it hides the details of creating objects.

When used, we can create a new object like this:

const newComponent = oldComponent.clone()
Copy the code

There are two points to note here: In general, it is not recommended to add arguments to the Clone function if the generated object is to be modified twice, as this can result in inconsistent interfaces. We can provide some set functions to the object instance for secondary modification. In addition, the clone function should consider the performance. As mentioned above, the combination of deep and shallow copies can be considered. At the same time, it should be noted that the copy function may not even be realized when the object has reference relationship or even circular reference.

disadvantages

Every design pattern has its drawbacks, but as stated in every issue, the drawbacks do not mean that the design pattern is not good, but that there are problems in certain scenarios, we just need to avoid these scenarios and use the corresponding design pattern in reasonable scenarios.

The downside of prototyping:

  1. Each class has to be implementedcloneMethod, the implementation of the class is somewhat intrusive, to modify the existing class, violating the open closed principle.
  2. When a class calls another object, if deep copy is to be implemented, the corresponding object must also be implementedcloneMethod, the overall link may be particularly long, the implementation is more troublesome.

conclusion

The prototype pattern is usually used in conjunction with the factory pattern. The factory method receives an instance that matches the prototype pattern and can call its Clone function to create and return a new object. The code looks something like this:

// buildComponentFactory creates objects internally with targetComponent.clone() instead of New or calling other factory functions.
const newComponent = buildComponentFactory(new Component())
Copy the code

Here’s a final diagram to quickly understand the prototype pattern:

Design Patterns — Prototype Patterns · Issue #277 · dT-fe /weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.

Pay attention to the front end of intensive reading wechat public account

Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)

This article is formatted using MDNICE