Factory mode, singleton mode and mediator mode in js

Factory mode, singleton mode and mediator mode in js

1. Factory mode

  • After data is passed in and processed in the function, a local variable is generated, and finally return this local variable
  • Because local variables are returned, even if the same data is passed in, the generated things are different (different reference addresses)
function ce(type,style){
    var elem=document.createElement(type);
    Object.assign(elem.style,style);
    return elem;
}

var div1=ce("div");
var div2=ce("div");
var p=ce("p");
console.log(div1===div2);    //false the div generated each time is different

2. Singleton mode

  • In contrast to the factory mode, the singleton mode generates the same thing every time because it returns the global
  • It is often used in classes and methods to assign global attributes and return variables after instantiation

Create the largest container when using scenario 1 component encapsulation

function createElem(){
    if(!elem) elem=document.createElement("div");
    return elem;
}
var a=createElem();
var b=createElem();
console.log(a===b);  //true because it is not created for the first time. After creation, subsequent ones are not created, and all returns are for the first time

Acquisition of instantiated objects in scenario 2

class Box{
    static _instance
    constructor(){

    }
    static getInstance(){
        if(!Box._instance)Box._instance=new Box();
        return Box._instance;
    }

}

var a=Box.getInstance()      
var b=Box.getInstance();
console.log(a===b);

For the acquisition of instantiated objects in the complex writing method class of scenario 2, the use of dynamic methods does not need to be used by instances

class Box{
    constructor(){

    }
    static get instance(){
        if(!Box._instance){
            Object.defineProperty(Box,"_instance",{    //Adding attributes to the Box class is equivalent to static_ instance 
                value:new Box()
            })
        }
        return Box._instance;
    }

    play(){
        console.log("play");
    }
    run(){
        console.log("run");
    }
}

var a=Box.instance
var b=Box.instance;
console.log(a===b);

Box.instance.play();    //Dynamic methods mimic the use of static methods
Box.instance.run();

3. Intermediary model

  • The purpose of the mediator pattern is to decouple the code (often used in conjunction with the singleton pattern)

  • The implementation method of the intermediary mode is described by telling stories
    1. Incomplete decoupling: there are three clients: client A, client B and middleman. Both clients buy and sell houses in the middleman's office building. Customer A took out his mobile phone and sent A message to the middleman. After receiving the message, the middleman took out his mobile phone and gave it to the middleman
    Customer B sends a message. After receiving the message, customer B starts to act.
    Explanation: customer a, customer B and middleman are class A, class B, class model (intermediary class) and html respectively. In html, class A and class B become two attributes of class model after instantiation respectively,
    ---A calls the method, in which the method calling model sends data, the method under model receives data, calls the method of class B to send messages, and the method under class B receives messages

    2. Complete decoupling: the example is roughly the same as incomplete decoupling. The difference is that when the model receives data and sends data to class B, it uses event throwing to achieve the effect of complete decoupling

After reading the story, let's see how the code is implemented

  • HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="module">   //Introduce customer A, customer B, customer C and middleman model
        import A from "./js/A.js";    
        import B from "./js/B.js";
        import C from "./js/C.js";
        import Model from "./js/Model.js";


        new C();   // C is completely decoupled, and the effect can be achieved by new
        Model.instance.a=new A();   //Customers A and B become the attributes of the model
        Model.instance.b=new B();
        Model.instance.a.run();  //Customer A calls its next method
    </script>
</body>
</html>
  • Class A
import Model from "./Model.js";  

export default class A{
    constructor(){

    }
    run(){
        Model.instance.data=100;   //Send message to middleman model
    }
}
  • Class model
export default class Model extends EventTarget{
    _data=0;
    constructor(){
        super();
    }
    static get instance(){
        if(!Model._instance){
            Object.defineProperty(Model,"_instance",{
                value:new Model()
            })
        }
        return Model._instance;
    }
    set data(value){
        this._data=value;    //Received data sent by class A
        Model.instance.b.play(value);     //Call the method under class B and send data to class B 
        
        var evt=new Event("data");  //Send events to class C and send data to realize complete decoupling
        this.dispatchEvent(evt);  
    }
    get data(){
        return this._data;
    }
}
  • Class B
export default class B{
    constructor(){

    }
    play(n){    //After receiving the data sent by class model (Class A), start the execution
        console.log(n);    
    }
}
  • Class C
import Model from "./Model.js";

export default class C{
    constructor(){
        Model.instance.addEventListener("data",e=>this.datahandler(e));   //Listen to the events thrown by the class model and get the data sent
    }
    datahandler(e){
        // console.log(Model.instance.data);
        console.log(e);
    }

}

At this point, a simple mediator model ends

Posted by _SAi_ on Mon, 23 May 2022 04:06:28 +0300