JS的五大设计模式

  • 1.单例模式
    单例模式的定义:保证一个类仅仅有一个实例,并提供一个访问他的全局访问点。
    意义:有的时候,一些对象我们仅仅需要一个,比如说线程池、全局缓存、浏览器中的window对象,我 们在前端也经常会使用到单例,当我们点击登录按钮的时候,我们会出现一个登录的副创,这个浮窗是唯 一的,无论我们点击多少次,这个浮窗仅仅会被创建一次,那么这个button就应该使用单例模式来进行 创建。
        //懒汉式单例
        function Singleton() { 
            if(!Singleton.instance) {
                Singleton.instance = {
                    name : "abc"
                }
            }
            return Singleton.instance;
        }
        
        var s1 = new Singleton();
        var s2 = new Singleton();
        console.log(s1==s2);
        
        //饿汉式单例
        var A = (function(){ 
            var instance =  {
                ele : document.createElement("div"),
                init : function(){
                    
                },
                close: function(){
                    
                }
            }
            return function(){
                return instance;
            }
        })();
        
        var a1 = new A();
        var a2 = new A();
        console.log( a1 == a2);
  • 2.代理模式
    代理模式是一种对程序对象进行控制性访问的一类解决方案。
    引入代理模式,其实是为了实现单一 职责的面向对象设计原则。
    单一职责其实就是指在一个类中(js中通常指对象和函数等),应仅有一个引起它变化的原因。这 样会帮助程序设计具有良好的健壮和高内聚特性,从而当变化发生时,程序设计会尽量少的受到意 外破坏。代理模式有多种方法,保护代理、远程代理、虚拟代理、缓存代理等。但在javascript 中,代理模式最常用到的两种方法是虚拟代理和缓存代理。
    下面来说一下缓存代理

    缓存代理可以为一些开销大的运算结果提供暂时存储,在下次运算时,如果传递进来的参数和之前的一致,则可以直接返回前面存储的结果

		function ajax(options) {	
            if(!ajax.cache) ajax.cache = {};
            //判断缓存中是否存在数据
            if( ajax.cache[options.url] ) { 
                options.success(ajax.cache[options.url]);
            } else {
                $.ajax({
                    type : options.type,
                    url : options.url,
                    success : function(data) {
                        //存入缓存
                        ajax.cache[options.url] = data; 
                        options.success(data);
                    }
                });
            }
        }
        
        ajax({
            type: "get",
            url: "xxxxxx",
            success: function(data){
                console.log(data);
            }
        })
  • 3.适配器模式
    将一个类(对象)的接口(方法或者属性)转化成另外一个接口以满足用户需求,使类(对象)之间 接口的不兼容问题通过适配器得以解决。
      class Pro {
            playgame() {
                console.log("play game....");
            }
        }
        
        class Ipad extends Pro {
            
        }
        class Iphone extends Pro {
            phonecall() {
                console.log("phone call....");
            }
        }
        
        function test(product){
            product.playgame();
            product.phonecall();
        }
        
        let pad1 = new Ipad();
        let phone1 = new Iphone();
        
        
		function Adapter(target) {
            this.playgame = function(){
                if(target.playgame) {
                    target.playgame();
                } else {
                    console.warn("该产品不支持playgame方法");
                }
                
            }
            this.phonecall = function(){
                if(target.phonecall) {
                    target.phonecall();
                } else {
                    console.warn("该产品不支持phonecall方法");
                }
            }
        }
        
        test(phone1);
        test( new Adapter(pad1) );
  • 4.策略模式

    策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。 使用策略 模式的优点如下:
    优点:

    1. 策略模式利用组合,委托等技术和思想,有效的避免很多if条件语句。
    2. 策略模式提供了开放-封闭原则,使代码更容易理解和扩展。
    3. 策略模式中的代码可以复用。
		function TankFactory(){
            if(!TankFactory.instance) {
                TankFactory.instance = (function(){
                    var tanklist = {
                        "小猫i" : function(){ },
                        "小狗" : function(){ },
                        "小熊" : function(){ }
                    }
                    return {
                        create : function(type){
                            return new tanklist[type]();
                        }
                    }
                })();
            }
            return TankFactory.instance;
        }
        
        var factory = new TankFactory();
        var factory2 = new TankFactory();
        var factory3 = new TankFactory();
        
        var tank1 = factory.create("小狗");
        var tank2 = factory.create("小猫");
        
        
        //var tab = document.createElement("image");
        
        
        class TankFactory {
            constructor() {
                if(!TankFactory.instance) {
                    TankFactory.instance = (function(){
                        var tanklist = {
                            "小猫" : function(){ },
                            "小狗" : function(){ },
                            "小熊" : function(){ }
                        }
                        return {
                            create : function(type){
                                return new tanklist[type]();
                            }
                        }
                    })();
                }
                return TankFactory.instance;
            }
        }
  • 5.观察者模式
    观察者模式( 又叫发布者-订阅者模式 )应该是最常用的模式之一. 在很多语言里都得到大量应用. 包括 我们平时接触的dom事件. 也是js和dom之间实现的一种观察者模式.
document.body.addEventListener("click", function() {
    alert("Hello World")
}false )
document.body.click() //模拟用户点击

以上js就是观察者,DOM就是被观察者,给DOM添加点击事件就相当于订阅了DOM,当DOM被点击,DOM就会通知js触发‘ alert(“Hello World”)
下面就是观察者模式的一个伪代码来帮助大家理解

		class 邮箱 {
            constructor() {
                this.emplist = [];
            }
            发布() {
                this.emplist.forEach(emp=>{
                    emp.接受消息("abc");
                })
            }
            订阅(emp){
                this.emplist.push(emp);
            }
            退订(emp) {
                let index = this.emplist.indexOf(emp);
                this.emplist.splice(index,1);
            }
        }
        
        class Employee {
            constructor(name) {
                this.name = name;
            }
            接受消息(msg) {
                console.log(`${this.name}收到了新的消息!!`);
            }
        }
        
        let qqemail = new 邮箱();
        
        let zhangsan = new Employee("zhangsan");
        let lisi = new Employee("lisi");
        
        qqemail.订阅(zhangsan)
        qqemail.订阅(lisi);

你可能感兴趣的:(js)