js的几种设计模式

参考:https://juejin.cn/post/6844903469397049352
https://segmentfault.com/a/1190000017787537
https://www.w3cschool.cn/zobyhd/pyunfozt.html

1、工厂模式

【简单工厂模式】:可以理解为解决多个相似的问题【提示框,只是提示的文字需要修改】

// 创建苹果类
class Apple {
  constructor(){
    this.name = 'apple'
  }
  getColor(){
    return 'Red'
  }
}

// 创建香蕉类
class Banana {
  constructor(name){
    this.name = 'banana'
    this.count = 10
  }
  getCount(){
    return this.count--
  }
}

class Fruits {
  constructor(type){
    switch(type){
      case 'apple':
        return new Apple()
      case 'banana':
        return new Banana()
    }
  }
}

const apple = new Fruits('apple')
const banana = new Fruits('banana')

【抽象工厂模式】:将其成员对象的实列化推迟到子类中子类可以重写父类接口方法以便创建的时候指定自己的对象类型【各种UI组件,根据你要的类型不同(比如:按钮,提示框,表格等)】参考链接

2、 单例模式

两个特点:一个类只有一个实例,并且提供可全局访问点 全局对象是最简单的单例模式:window
demo:登录弹出框只需要实例化一次,就可以反复用了

// 实现单例模式弹窗
var createWindow = (function(){
    var div;
    return function(){
        if(!div) {
            div = document.createElement("div");
            div.innerHTML = "我是弹窗内容";
            div.style.display = 'none';
            document.body.appendChild(div);
        }
        return div;
    }
})();
document.getElementById("Id").onclick = function(){
    // 点击后先创建一个div元素
    var win = createWindow();
    win.style.display = "block";
}

3、模块模式

模块模式的思路是为单体模式添加私有变量和私有方法能够减少全局变量的使用
demo:返回对象的匿名函数。在这个匿名函数内部,先定义了私有变量和函数

var singleMode = (function(){
    // 创建私有变量
    var privateNum = 112;
    // 创建私有函数
    function privateFunc(){
        // 实现自己的业务逻辑代码
    }
    // 返回一个对象包含公有方法和属性
    return {
        publicMethod1: publicMethod1,
        publicMethod2: publicMethod1
    };
})();

4、代理模式

代理对象可以代替本体被实例化,并使其可以被远程访问
demo: 虚拟代理实现图片的预加载

class MyImage {
    constructor() {
        this.img = new Image()
        document.body.appendChild(this.img)
    }
    setSrc(src) {
        this.img.src = src
    }
}

class ProxyImage {
    constructor() {
        this.proxyImage = new Image()
    }

    setSrc(src) {
        let myImageObj = new MyImage()
        myImageObj.img.src = 'file://xxx.png'  //为本地图片url
        this.proxyImage.src = src
        this.proxyImage.onload = function() {
            myImageObj.img.src = src
        }
    }
}

var proxyImage = new ProxyImage()
proxyImage.setSrc('http://xxx.png') //服务器资源url

5、缓存代理

缓存代理的含义就是对第一次运行时候进行缓存,当再一次运行相同的时候,直接从缓存里面取,这样做的好处是避免重复一次运算功能,如果运算非常复杂的话,对性能很耗费,那么使用缓存对象可以提高性能;
demo:计算值的加法,如果之前已经算过,取缓存,如果没有算过重新计算。

6、命令模式

有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道请求的操作是什么,此时希望用一种松耦合的方式来设计程序代码;使得请求发送者和请求接受者消除彼此代码中的耦合关系。
demo:几个按钮绑定不同的事件,然后bindEvent(el, event);

7、模板方法模式

一、模板方法模式:一种只需使用继承就可以实现的非常简单的模式。
二、模板方法模式由两部分组成,第一部分是抽象父类,第二部分是具体的实现子类。
demo: 比如泡茶、冲咖啡的步骤都是一样的,抽出父类,Child.prototype = new Parent();然后重写里面的步骤(方法)

8、策略模式

定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换
demo:年终奖的薪水的几倍,是按照一个个等级来划分的,A级别是3倍,B级别是2倍,C级别是1倍,那么就可以写三个等级方法,然后封装在一个方法里,传入薪水和等级就ok了

9、发布订阅模式介绍

发布—订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知。
demo: 比如你向买房,只要把手机给房产中介,房产中介一有消息就发布消息。

var list = {
	arr: [],
	subscribe: function(fn) {
		this.arr.push(fn);
	},
	notify: function() {
		this.arr.forEach(fn => fn());
	}
};

var fn1 = function() {
	console.log(1)
}
var fn2 = function() {
	console.log(2)
}
list.subscribe(fn1);
list.subscribe(fn2);
list.notify();

10、中介者模式

中介者模式的作用是解除对象与对象之间的耦合关系,增加一个中介对象后,所有的相关对象都通过中介者对象来通信,而不是相互引用,所以当一个对象发送改变时,只需要通知中介者对象即可。中介者使各个对象之间耦合松散,而且可以独立地改变它们之间的交互。
demo:卖手机,颜色和数量判断加入购物车按钮是否可用

11、装饰者模式

动态的给类或对象增加职责的设计模式。
装饰器模式并不去深入依赖于对象是如何创建的,而是专注于扩展它们的功能这一问题上。装饰器模式相比生成子类更为灵活。

var Car = function() {}
Car.prototype.drive = function() {
    console.log('乞丐版');
}

var AutopilotDecorator = function(car) {
    this.car = car;
}
AutopilotDecorator.prototype.drive = function() {
    this.car.drive();
    console.log('启动自动驾驶模式');
}

var car = new Car();
car = new AutopilotDecorator(car);
car.drive();    //乞丐版;启动自动驾驶模式;

12、适配器模式

适配器模式主要解决两个接口之间不匹配的问题,不会改变原有的接口,而是由一个对象对另一个对象的包装。
demo:两个地图(2个类),他们有一个共同方法但是名字不同,这时候需要定义适配器类, 对其中的一个类进行封装。

class GooleMap {
    show() {
        console.log('渲染谷歌地图')
    }
}

class BaiduMap {
    display() {
        console.log('渲染百度地图')
    }
}


// 定义适配器类, 对BaiduMap类进行封装
class BaiduMapAdapter {
    show() {
        var baiduMap = new BaiduMap()
        return baiduMap.display()
    }
}

function render(map) {
    map.show()
}

render(new GooleMap())         // 渲染谷歌地图
render(new BaiduMapAdapter())  // 渲染百度地图

你可能感兴趣的:(js,js设计模式,单例模式,工厂模式,发布订阅者模式,装饰者模式)