前端框架中的设计模式 | 青训营

70 阅读4分钟

1.什么是设计模式

通俗来讲,就是日常使用设计的一种惯性思维。因为对应的这种思维,以及对具体的业务或者代码场景,有着具体的优势,而后成为行业中的一种“设计模式”。

2.设计模式的基本准则

优化代码第一步:单一职责原则

让程序更稳定更灵活:开闭原则

构建扩展性更好的系统:里式替换原则

让项目拥有变化的能力:依赖倒置原则

系统有更高的灵活性:接口隔离原则

更好地扩展性:迪米特原则

3.设计模式的种类

a.创建型模式

一般用于创建对象。包括:单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式。

b.结构型模式

重点为“继承”关系,有着一层继承关系,且一般都有“代理”。包括:适配器模式,桥接模式,组合模式,装饰器模式,外观模式,享元模式,代理模式,过滤器模式

c.行为型模式

职责的划分,各自为政,减少外部的干扰。包括:命令模式,解释器模式,迭代器模式,中介者模式,备忘录模式,观察者模式,状态模式,策略模式,模板方法模式,访问者模式,责任链模式

5.前端比较常用的设计模式

1.组合模式

定义:将对象组合成树形结构以表示“部分-整体”的层次结构。

    constructor(name) {
        this.fileName = name;
        this.children = [];
    }
    add(child) {
        this.children.push(child);
    }
    scan() {
        console.log("Folder:" + this.fileName);
        for (const child of this.children) {
            child.scan();
        }
    }
}
class File {
    constructor(name) {
        this.fileName = name;
    }
    add() {}
    scan() {
        console.log("File:" + this.fileName);
    }
}

const folder1 = new Folder("first");
folder1.add(new File("file1"));
folder1.add(new File("file2"));
const folder2 = new Folder("secend");
folder2.add(new File("file3"));
folder1.add(folder2);

folder1.scan();

这样,通过调用第一个文件夹的扫描方法就能调用所有子元素的扫描方法。

a) 组合模式在组件开发中的应用:

组合模式适合一些容器组件场景,通过外层组件包裹内层组件,这种方式在 Vue 中称为 slot 插槽,在React中为props.children,外层组件可以轻松的获取内层组件的 props 状态,还可以统一控制内层组件的渲染,组合模式能够直观反映出 父 -> 子组件的包含关系,如下最简单的组合模式例子。

    <GroupPatternsItem name='《React进阶实践指南》' />
    <GroupPatternsItem name='《React设计模式》' />
    <GroupPatternsItem isShow name='《React进阶实践指南》' />
    <GroupPatternsItem isShow={false} name='《Nodejs深度学习手册》' />
    <div>hello,world</div>
</GroupPatterns>

我们直观上看到 GroupPatterns 和 GroupPatternsItem 并没有做某种关联,但是却无形的联系起来。这种就是组合模式的精髓所在,这种组合模式的组件,给使用者感觉很舒服,因为大部分工作,都在开发组合组件的时候处理了。所以编写组合模式的嵌套组件,对锻炼开发者的 组件封装能力是很有帮助的。

2.单例模式

定义:保证一个类只有一个实例, 一般先判断实例是否存在,如果存在直接返回, 不存在则先创建再返回,这样就可以保证一个类只有一个实例对象.

作用:1.模块间通信。2.保证某个类的对象的唯一性3.防止变量污染

单例模式适用于全局只能有一个实例对象的场景,单例模式的一般结构如下:

    let instance;
    return function(age) {
        if (instance) {
            return instance;
        }
        this.age = age;
        return instance = this;
    }
})();
CreateSinglePattern.prototype.getAge = function() {
    return  this.age
}

let young = new CreateSinglePattern('18');
let old = new CreateSinglePattern('108');

console.log(young === old); // true
console.log(young.getAge());  // '18'
console.log(old.getAge());  // '18'

通过闭包缓存实例,后续不管new多少次都是同一个实例。

a) 单例模式在vuex中的应用:


function install (_Vue) {
  if (Vue && _Vue === Vue) {
    {
      console.error(
        '[vuex] already installed. Vue.use(Vuex) should be called only once.'
      );
    }
    return
  }
  Vue = _Vue;
  applyMixin(Vue);
}

可以看出,如果重复注册的话会进行报错处理,通过这种方式,可以保证一个 Vue 实例(即一个 Vue 应用)只会被 install 一次 Vuex 插件,所以每个 Vue 实例只会拥有一个全局的 Store。

3.工厂模式

简单工厂模式

简单工厂模式是由一个工厂对象来创建某一类产品的实例。

工厂方法模式

工厂方法模式可以理解为升级版的简单工厂模式,是对产品类的抽象,使其创建多类产品的实例。简单工厂模式是创建同一类的某个产品,而工厂方法模式是创建多类产品的实例。它其实是将多个产品类进行抽象化,可以通过这个工厂对这些类创建相应类的实例。

抽象工厂模式

抽象工厂模式是对类的工厂的抽象,用于创建不同的类,而不是创建类的实例。