js中的工厂模式,单例模式,中介者模式

js中的工厂模式,单例模式,中介者模式

1.工厂模式

  • 传入数据,函数内进行加工后,生成一个局部变量,最后return这个局部变量
  • 因为返回的是局部变量,所以即使传进的是一样的数据,生成的东西也不一样(引用地址不同)
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   每次生成的div都不同

2.单例模式

  • 单例模式和工厂模式相反,每次生成的东西都是一样的,因为其返回的是全局的
  • 经常用在类中,方法中实例化后赋值全局的属性,返回变量

使用情景1 组件封装时创建最大的容器

function createElem(){
    if(!elem) elem=document.createElement("div");
    return elem;
}
var a=createElem();
var b=createElem();
console.log(a===b);  //true   因为第一次没有,创建之后,后面的不创建,返回的都是第一次的

使用情景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);

使用情景2的复杂写法 类中实例化对象的获取,动态方法的使用不在需要实例使用

class Box{
    constructor(){

    }
    static get instance(){
        if(!Box._instance){
            Object.defineProperty(Box,"_instance",{    //给Box类增加属性   相当于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();    //动态方法模仿静态方法的使用
Box.instance.run();

3.中介者模式

  • 中介者模式的目的:实现代码的解耦(经常和单例模式来一起使用)

  • 中介者模式实现方式,下面我用讲故事的方法来阐述
    1.不完全解耦: 有客户A和客户B、中间人共3人,这两个客户都在中间人的办公楼中买卖房子。客户A拿出手机给中间人发了一个消息,中间人接收到这个消息后,拿出手机给
    客户B发送一条消息,客户B接收到消息后,开始行动。
    解释:客户A、客户B、中间人分别是类A,类B,类model(中介者类),html,在html中,类A和类B分别实例化后,成为类model的两个属性,
    ---A调用方法,方法中调用model的方法发送数据,model下的方法接收到,调用类B的方法发送消息,类B下的方法接收到消息

    2.完全解耦 :示例和不完全解耦大致相同,不同的是model收到数据后,向类B发送数据时,用的是事件的抛发,达到了完全解耦的效果

故事看完了,看看代码具体怎么实现

  • 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">   //引入客户A,客户B,客户C,中间人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是完全解耦,是要new就能实现效果
        Model.instance.a=new A();   //客户 A和B成为model的属性
        Model.instance.b=new B();
        Model.instance.a.run();  //客户A 调用其下方法
    </script>
</body>
</html>
  • 类A
import Model from "./Model.js";  

export default class A{
    constructor(){

    }
    run(){
        Model.instance.data=100;   //给中间人 model发送消息
    }
}
  • 类 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;    //接收到类A发送的数据
        Model.instance.b.play(value);     //调用类B下的方法,向类B发送数据 
        
        var evt=new Event("data");  //向类C抛发事件,发送数据,实现完全解耦
        this.dispatchEvent(evt);  
    }
    get data(){
        return this._data;
    }
}
  • 类 B
export default class B{
    constructor(){

    }
    play(n){    //接收到类model(类A发送的)数据后,开始执行
        console.log(n);    
    }
}
  • 类C
import Model from "./Model.js";

export default class C{
    constructor(){
        Model.instance.addEventListener("data",e=>this.datahandler(e));   //侦听类model抛发出来的事件,获取其发送出来的数据
    }
    datahandler(e){
        // console.log(Model.instance.data);
        console.log(e);
    }

}

到此,一个简单的中介者模式结束

原文地址:https://www.cnblogs.com/94-Lucky/p/13498725.html