1. 什么是设计模式
通俗来讲,就是日常使用设计的一种惯性思维。因为对应的这种思维,以及对具体的业务或者代码场景,有着具体的优势,而后成为行业中的一种“设计模式”。
2. 为什么使用设计模式
设计模式是各种业务场景的最佳实践,有助于我们在写日常业务中时,提高自身的思路。例如单例模式,就可以用于登陆框,模态框等场景。每种设计模式,必然有其适合应用的场景,灵活运用设计模式,可以提高代码的可维护性,还可提升自身思维能力。
3. 设计模式的基本准则
- 优化代码第一步:单一职责原则
- 让程序更稳定更灵活:开闭原则
- 构建扩展性更好的系统:里式替换原则
- 让项目拥有变化的能力:依赖倒置原则
- 系统有更高的灵活性:接口隔离原则
- 更好地扩展性:迪米特原则
4. 设计模式的种类
4.1创建型模式
一般用于创建对象。包括: 单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式。
4.2结构型模式
重点为“继承”关系,有着一层继承关系,且一般都有“代理”。 包括:适配器模式,桥接模式,组合模式,装饰器模式, 外观模式,享元模式,代理模式,过滤器模式
4.3行为型模式
职责的划分,各自为政,减少外部的干扰。 包括:命令模式,解释器模式,迭代器模式,中介者模式, 备忘录模式,观察者模式,状态模式,策略模式, 模板方法模式,访问者模式,责任链模式
5. 前端常见的设计模式
5.1 外观模式
外观模式是最常见的设计模式之一,它为子系统中的一组接口提供一个统一的高层接口,使子系统更容易使用。简而言之外观设计模式就是把多个子系统中复杂逻辑进行抽象,从而提供一个更统一、更简洁、更易用的API。很多我们常用的框架和库基本都遵循了外观设计模式,比如JQuery就把复杂的原生DOM操作进行了抽象和封装,并消除了浏览器之间的兼容问题,从而提供了一个更高级更易用的版本。
5.1.1 应用场景
- 设计初期,应该要有意识地将不同的两个层分离,比如经典的三层结构,在数据访问层和业务逻辑层、业务逻辑层和表示层之间建立外观Facade
- 在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观Facade可以提供一个简单的接口,减少他们之间的依赖。
5.1.2 优点
- 减少系统相互依赖。
- 提高灵活性。
- 提高了安全性
5.1.3 缺点
不符合开闭原则如果要改东西很麻烦,继承重写都不合适。
5.2 单例模式
顾名思义,单例模式中Class的实例个数最多为1。当需要一个对象去贯穿整个系统执行某些任务时,单例模式就派上了用场。而除此之外的场景尽量避免单例模式的使用,因为单例模式会引入全局状态,而一个健康的系统应该避免引入过多的全局状态。
5.2.1 应用场景
- 定义命名空间和实现分支型方法
- 登录框
- vuex 和 redux中的store
5.2.2 优点
- 划分命名空间,减少全局变量
- 增强模块性,把自己的代码组织在一个全局变量名下,放在单一位置,便于维护
- 且只会实例化一次。简化了代码的调试和维护
5.2.3 缺点
- 由于单例模式提供的是一种单点访问,所以它有可能导致模块间的强耦合
- 从而不利于单元测试。无法单独测试一个调用了来自单例的方法的类,而只能把它与那个单例作为一 个单元一起测试
5.3 工厂模式
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型
5.3.1 应用场景
- 如果你不想让某个子系统与较大的那个对象之间形成强耦合,而是想运行时从许多子系统中进行挑选的话,那么工厂模式是一个理想的选择
- 将new操作简单封装,遇到new的时候就应该考虑是否用工厂模式;
5.3.2 优点
- 创建对象的过程可能很复杂,但我们只需要关心创建结果。
- 构造函数和创建者分离, 符合“开闭原则”
- 一个调用者想创建一个对象,只要知道其名称就可以了。
- 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
5.3 .3 缺点
- 添加新产品时,需要编写新的具体产品类,一定程度上增加了系统的复杂度
- 考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度