2019-06-02 | 设计模式 | UNLOCK | 更新时间:2019-12-30 16:45

JS 的设计模式介绍(一)

你可能需要了解的

什么是设计模式

设计模式是一种思想,代表着最佳的实践方案。设计模式是开发人员在开发过程中面临对一般问题对解决方案,这些解决方案是众多开发人员经过实践和错误总结所归纳出来的

什么是 反模式?

如果我们认为模式是一种最佳的解决方案,那么反模式则代表着一次教训,反模式有两个概念:描述对于一个特殊的问题,提出一个糟糕的解决方案,得到一个糟糕的结果;描述如何解决上述方案,并提出一个好的解决方案

设计模式的目的

为了解决问题,为了重用代码,让代码能更好的被理解。为了保证代码的可靠性,让代码编制实现工程化,设计模式提供了一个标准的术语系统,且具体到特定的情景

GOF (四人帮)

在 1994 年,由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。

四位作者合称 GOF(四人帮,全拼 Gang of Four)。

设计模式的类型

根据设计模式参考书中所提到的23种设计模式,它们分为三大类,创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)

创建型 结构型 行为型
单例模式 适配器模式 观察者模式
原型模式 装饰器模式 迭代器模式
工厂模式 代理模式 策略模式
抽象工厂模式 外观模式 模板方法模式
建造者模式 桥接模式 职责链模式
组合模式 命令模式
享元模式 备忘录模式
状态模式
访问者模式
中介者模式
解释器模式

在实际生产中,设计模式并不是千篇一律的照搬,也存在着许许多多的变体,有的在不同的编程环境中可能就不太适用,看自己的需求来。

单例模式

单例模式的定义:保证一个类仅一个实例,并提供一个访问它的全局变量。实现原理并不复杂,无非是用一个变量来标准是否已经为某个类创建过实例,如果是则返回之前创建的对象,(应用场景:提示弹窗;点击多少次都只出现一个弹窗。)

名称 描述
优点 划分命名空间,减少全局变量。避免对共享资源的多重占用,节约系统资源
缺点 可能导致模块间的强耦合,不利于单元测试;不适用于变化的对象;
var Siglecon=(function(){
    var instance;
    function init(){
        // 私有方法和变量
        var _string="私有变量";
        var _random=Math.random();
        function _log(){
          console.log(_string)
        }
        return { 
            // 公有变量和方法
            getName:function(){
              return _string
            },
            log:"公有变量",
        };      
    };
    return {
        // 如果存在实例,则指向同一个实例
        getInstance:function(){
            if(!instance){
                instance=init();
            };
            return instance;
        }
    }
})();

var sigle=Siglecon.getInstance()

构造器模式

在面向对象中,构造器是一个新建对象的内存被分配后,用来初始化该对象的一个特殊函数,js 通过 new 关键字调用一个函数,这个函数被当做构造器来使用,我们则通过this来实现构造函数的运用

function Gender(x){
  this.gender=x
}
Gender.prototype.toString=function(){
  return '此人性别为'+this.gender
}
let Jack=new Gender('男')
Jack.toString()

原型模式

“四人帮”称原型模式是一种基于现有对象模板,通过克隆方式创建对象的模式;那么js中则是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象

var car={
    name:'大众',
    toLog:function(){
        console.log('汽车')
    }
}
// Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
var youCar=Object.create(car)

// Object.create()方法可以传入第二个参数来实现对新创建对象属性的添加
var myCar=Object.create(car,{
    id:{
        value:'asd',   // 值
        writable:false, // 可写
        configurable:true // 能否使用delete、能否需改属性特性、或能否修改访问器属性
    }
})

工厂模式

工厂模式是用于创建对象(视为工厂里的产品)的设计模式,其创建对象时无需指定创建对象的具体类。既提供一个创建对象的公共接口

工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型

let  factory=function(role) {
    function superman() {
        this.name ='超级管理员',
        this.role = ['修改密码', '发布消息', '查看主页']
    }
    function commonMan() {
        this.name = '普通游客',
        this.role = ['查看主页']
    }
    switch(role) {
        case 'superman':
        return new superman();
        break;
        case 'man':
        return new commonMan();
        break;
        default:
        throw new Error('参数错误')
    }
}

// 根据参数的不同创建不同的对象
let superman = factory('superman');
let man = factory('man');