1024programmer Java Detailed explanation of JavaScript decorator pattern principles and usage examples

Detailed explanation of JavaScript decorator pattern principles and usage examples

The examples in this article describe the principles and usage of the Javascript decorator pattern. Share it with everyone for your reference, the details are as follows:

Here we gradually introduce the decorator pattern through requirements.

Here’s a look at how different car generations have come to embody the decorator pattern.

First, we introduce an interface file – the purpose is to check whether the implementation class fully implements the methods in the interface, the code is as follows,

 //Define a static method to implement direct inspection of the interface and implementation class
 //Don't write Interface.prototype for static methods, because this is written on the prototype chain of the interface
 //We need to write static functions directly to the class level
 //Define an interface class
 var Interface=function (name,methods) {//name: interface name
   if(arguments.length<2){
     alert("must be two parameters")
   }
   this.name=name;
   this.methods=[];//Define an empty array to load the function name
   for(var i=0;i<methods.length;i++){
     if(typeof methods[i]!="string"){
       alert("Function name must be of string type");
     }else {
       this.methods.push( methods[i]);
     }
   }
 };
 Interface.ensureImplement=function (object) {
   if(arguments.length<2){
     throw new Error("Parameters must be no less than 2")
     return false;
   }
   for(var i=1;i

 

(1) Unified interface

  var ShopInterface=new Interface("FirstShop",["getPrice","assemble"]);//Specifies the implementation method

(2) Implement the interface and check internally

  var first=function () {
     //interface implementation part
     this.getPrice=function () {
       document.write(15000+"
") } this.assemble=function () { document.write("Car assembly....
") } Interface.ensureImplement(this,ShopInterface);//Check whether the class implements the interface }

(3) The first car instance

  //First car instance
   var firstShop=new first();
   firstShop.getPrice();
   firstShop.assemble();
   document.write(".............first.............
")

Now we have a new demand. Cars need accessory products such as: speakers (K), leather sofas (M), bumpers (N).

Through analysis, we can know that each accessory product will affect the assembly and price of the car, so what can we think of?

The first option: Modify the interface through

(1) The interface is defined as

  var SecOndInterface=new Interface("SecondInterface",["getPrice","assemble","addK","addM","addN"]);

(2) The class implements the interface and verifies it

  var secOnd=function () {
      var price=15000;
      //Instance interface part
      this.getPrice=function () {
        document.write(price+"
") } this.assemble=function () { document.write("Car assembly....
"); } this.addK=function () { price+=1000; } this.addM=function () { price+=2000; } this.addN=function () { price+=3000; } Interface.ensureImplement(this,SecondInterface);//Will be called when the current object instance }

(3) Second car instance

  //Second car instance
   var secOndShop=new second();
      secondShop.addK();
      secondShop.addM();
      secondShop.addN();
      secondShop.getPrice();
      secondShop.assemble();
      document.write("........................second........................  ..
");

Hey, we seem to have implemented it, but here comes the problem. I changed the interface, but the class I implement this interface does not necessarily have to have K, M, N. "Do I need to modify all the implementation classes that implement this interface?" This is obviously wrong. If I don't change the interface, then I will add subclasses. Is this okay?

The second option is to add subclasses without changing the interface

(1) The interface is still

   var thirdInterface=new Interface("FirstShop",["getPrice","assemble"]);

(2) Car prototype class--implementation interface

  var third=function () {
       this.getPrice=function () {
         document.write(15000+"
"); } this.assemble=function () { document.write("Car assembly....
"); } Interface.ensureImplement(this,thirdInterface); }

(3) Each subcategory

   var thirdM=function () {
       this.getPrice=function () {
         document.write(15000+"
"); } this.assemble=function () { document.write("Car assembly....
"); } Interface.ensureImplement(this,thirdInterface); };

We can’t help but ask, should every subclass be written like this? If there are too many subclasses, we will have to write crazy, so this method is not advisable.

Third option: Use the decorator pattern

Decorators can add new features to prototype objects, transparently wrapping the object in a new object with the same interface.

The specific code is as follows:

(1) The interface remains unchanged, the code is as follows

var comInterface=new Interface("FirstShop",["getPrice","assemble"]);

(2) Target object (prototype) - the original object that needs to be decorated (belongs to the part wrapped inside) - implements the interface and checks it during the instance

 var targetShop = function(){
     this.getPrice = function(){
       return 15000;
     }
     this.assemble =function(){
       document.write("Car assembly....
") } Interface.ensureImplement(this,comInterface);//Interface inspection }

(3) Each decorative class is something that wraps the original object.

#M:

  var carM = function(carShop) {
     this.getPrice = function () {
       return 1000 + carShop.getPrice();
     }
     this.assemble = function () {
       document.write("M assembly....
") } Interface.ensureImplement(this,comInterface);//Interface inspection }

#N:

  var carN = function(carShop){
     this.getPrice = function(){
       return 2000+carShop.getPrice();
     }
     this.assemble =function(){
       document.write("N assembly....
") } Interface.ensureImplement(this,comInterface);//Interface inspection }

#K:

  var carK=function (carShop) {
     this.getPrice=function () {
       return 3000+carShop.getPrice();
     }
     this.assemble=function () {
       document.write("K Assembly....
") } Interface.ensureImplement(this,comInterface);//Interface inspection };

(4) Use various decorations to wrap our cars

  //Packaging car
   var newCar=new carK(new carM(new targetShop));//Cars with K and M
    var newCar2=new carK(new carM(new carN(new targetShop)));
     document.write(newCar.getPrice()+"
"); document.write(newCar2.getPrice());

To summarize, decorators can be used on classes, and they can also be used on functions in classes.

If the original functions are not suitable for your project, and you need to greatly expand the original functions, and do not want to change the original interface, then you are right to use the decorator pattern.

Use the diagram to understand the above model:

Principle diagram of packaging: --Packaging chain

Interested friends can use Online HTML/CSS/Javascript front-end code debugging and running tool: http://tools.jb51.net/code/WebCodeRun to test the above Code execution effect.

For more content related to Javascript, you can also check out the special topics on this site: "Javascript Object-Oriented Introductory Tutorial", "Summary of Javascript Errors and Debugging Techniques", "Summary of Javascript Data Structure and Algorithm Techniques", "Summary of Javascript Traversal Algorithms and Techniques" 》and《Javascript Mathematical Operation Usage Summary》

I hope this article will be helpful to everyone in Javascript programming.

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/697299

author: admin

Previous article
Next article

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索