前端设计模式个人汇总

2,410 阅读14分钟

前言

个人汇总前端,包含自我的总结,以及原创实例。个人觉得更加通俗易懂,适合入门者快速入门。欢迎关注。

文章内容包含设计模式的理解,设计模式的基本准则,设计模式的分类,以及常用设计模式应用实例。

均为个人原创汇总,如有不对,希望指出。

本文简介

话题来源
设计模式是什么个人理解
设计模式的基本准则个人理解 + 参考链接:www.jianshu.com/p/62b69282b…
设计模式的分类个人理解 + 参考链接:www.jianshu.com/p/eafc4ca17…
设计模式应用实例个人理解,包括最基本的理解,业务场景,代码场景,优缺点, 以及部分代码实例
文章结语个人理解,难免出现错误,欢迎留言纠正

前端的设计模式是什么

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

前端的设计模式的基本准则

优化代码第一步:单一职责原则
让程序更稳定更灵活:开闭原则
构建扩展性更好的系统:里式替换原则
让项目拥有变化的能力:依赖倒置原则
系统有更高的灵活性:接口隔离原则
更好地扩展性:迪米特原则

设计模式的种类

1.创建型模式
一般用于创建对象。包括:
单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式。
2.结构型模式
重点为“继承”关系,有着一层继承关系,且一般都有“代理”。
包括:适配器模式,桥接模式,组合模式,装饰器模式,
外观模式,享元模式,代理模式,过滤器模式
3.行为型模式
职责的划分,各自为政,减少外部的干扰。
包括:命令模式,解释器模式,迭代器模式,中介者模式,
备忘录模式,观察者模式,状态模式,策略模式,
模板方法模式,访问者模式,责任链模式

前端常用设计模式应用实例:

1.单例模式
基本理解:
    一个极有可能重复出现的“实例”, 如果重复创建,是否消耗性能?如果借助第一次的实例,后续只是对该实例的重复使用,这样就达到了我们节省性能的目的。
业务场景:
    登录弹出框,取消重新弹出时,再显示原来的弹出框,而不是重新创建。
代码场景:
    数据库链接池
相关代码:
    var myLogin = function( fn ){
        var result;
        return function(){
            return result || ( result = '<div>我是登陆框</div>' );
    }
}
2.简单工厂模式
基本理解:
    简单工厂模式叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。
业务场景:
    富士康同时需要生产华为,苹果等手机,
    我们可用一个工厂的模型,生产人只要输入型号,就可以产出对应的手机
优点:
    使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性。
缺点:
    1)如果增加新类型,则需要修改工厂,违背了开放封闭原则(ASD) 
    2)当子类过多或者子类层次过多时不适合使用
相关代码:
   function CreatPhone( type ) {
        retrun new AbstractPhoneFactory( type );
   }
   
   class AbstractPhoneFactory(){
       constructor(options){
            this.phone = null;
            swicth options.type:
                case "huawei":
                    this.phone = new HuaweiFactory();
                    break;
                case "apple":
                    this.phone = new AppleFactory();
                    break;
            }
            retrun this.phone;
       }
   }
   
   class HuaweiFactory(){
       constructor(){
           
       }
       
       
   }
   
    class AppleFactory(){
       
   }
3.抽象工厂模式
基本理解:
    相比简单工厂,多一个抽象对象。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
优点:
    使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性。
缺点:
    1)如果增加新类型,则需要修改工厂,违背了开放封闭原则(ASD) 
    2)当子类过多或者子类层次过多时不适合使用
业务场景:
    如上,如果还需要手机颜色,内存大小。
4.建造者模式
基本理解:
    使用多个简单的对象一步一步构建成一个复杂的对象。
    与工厂模式相比,他里边可能有更多,更复杂的创建的对象。
优点: 
    1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 
    1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
业务场景:
    去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"
5.原型模式
基本理解:
    当想要通过克隆或拷贝对象来生成对象时,这就是原型模式。
优点: 
     1、性能提高。 2、逃避构造函数的约束。
缺点: 
     1、性能提高。 2、逃避构造函数的约束。
业务场景:
    构造函数生成实体
6.适配器模式
基本理解:
    让原来不兼容的两个接口协同工作。可分:类适配器、对象适配器、接口适配器
优化:
    重用:复用的现存的类, 解决了现存类和复用环境要不一致的问题
    低耦合:无需修改原有代码(遵循开闭原则)
缺点:
    过多的使用适配器,的确会让程序看起来更加复杂
业务场景:
    当你的电脑,只支持usb的插头,而鼠标是PS/2接口时,这时候需要一个PS/2跟USB适配器来连接。
代码场景:
    原生安卓adapter适配器,json格式数据的统一

7.桥接模式
基本理解:
    多维度的分离他的抽象部分,使每个维度独立。然后“通过”桥接得到我们想要的结果。
优点:
    1、分离抽象接口及其实现部分。提高了比继承更好的解决方案。
    2、桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
    3、实现细节对客户透明,可以对用户隐藏实现细节。
缺点:
    1、桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
    2、桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
业务场景:
    使用某扣截图标记的时候,是否选一个颜色,再选择一个形状?然后再通过桥接成一个对象。这就是桥接模式。
    
8.组合模式
基本理解:
    强调“部分-整体”的层次结构。组合模式使得用户可以使用一致的方法操作单个对象和组合对象。
    可分:组合关系, 聚合关系
优点:
    无需关系处理的单个对象,还是组合的对象容器,实现容器之间的解耦合。当有新部件时容易添加进来。
缺点:
    客户端需要花更多时间理清类之间的层次关系
业务场景:
    组合关系:多个程序员,归属一个CTO管理。
    聚合关系:一个老师有很多学生,但是每一个学生又属于多个老师。
9.装饰器模式
基本理解:
    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。
优点:
    装饰类和被装饰类可以独立发展,不会相互耦合。
缺点:
    多层装饰比较会显得复杂。
业务实例:
    相框与相片的关系。
代码实例:
    react高阶组件(比如所有的组件加个边框)
10.外观模式
基本理解:
    隐藏复杂的关系。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
优点:
    1、减少系统相互依赖。 2、提高灵活性。 3、提高了安全性。
缺点:
   不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
业务实例:
    去医院挂号时,挂号厅就是“外观”,里边可能包含复杂的医疗关系,但我们只需要通过“挂号台”进行“简单”的挂号。
代码实例:
    组件库
11.享元模式
基本理解:
    可以理解成池技术,String常量池、数据库连接池、缓冲池等,有大量对象的时候,需要缓解的时候。
    性能优化模式。
优点:
    大大减少对象的创建,降低系统的内存,使效率提高。
缺点:
   提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。
案例:
    假设近十年的当天销售额都没有汇总。这时候,有一个按日期查询当天销售额的统计的功能。我们可以查询到该日期的时候,保存这个值,下次查询我们直接获取该值。
代码:
    String常量池、数据库连接池、缓冲池等
    
12.过滤器模式
基本理解:让开发人员使用不同的标准来过滤一组对象。
优点:可快速获取所需要对象。
缺点:要遍历所有的数据。
案例:选择一群人中,已婚男性。
13.代理模式
基本理解:
    一个类代表另一个类的功能。我们创建具有现有对象的对象,以便向外界提供功能接口。
优点: 
    1、职责清晰。 2、高扩展性。
缺点: 
    1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
应用实例:
    1.Windows 里面的快捷方式。
    2.待售点帮忙卖火车票
业务实例:
    img缓冲图
特别注意: 
    1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
    
14.命令模式
基本理解:
    请求以命令的形式包裹在对象中,并传给调用对象。
优点: 
    1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。
缺点:
    使用命令模式可能会导致某些系统有过多的具体命令类。
生活实例:
    遥控器,控制电视机,就是一个命令模式。
实战案例:
    1.我们Npm启动项目命令,也是一个命令模式。
    2.小程序服务通知,由服务端发起一个命令,也是一个命令模式。
15.中介者模式
基本理解:
    提供了一个中介类,该类通常处理不同类之间的通信。
优点: 
    1.降低了类的复杂度,将一对多转化成了一对一。 
    2.各个类之间的解耦。
缺点: 
    中介者庞大时,变得复杂难以维护。
应用实例:
    1.聊天室供用户之间聊天,聊天室就是一个中介
    2.房产中介
实战案例:
    传统前端mvc模式。c可理解为m与v的中介。vuex.
    
16.备忘录模式
基本理解:
优点: 
    给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
缺点: 
    消耗资源,有一定的内存损耗。
应用实例:
    浏览器的页面机制,可回退。
实战案例:
    数据库的事务管理,可回滚。
17.观察者(发布订阅)模式
基本理解:
    即为发布,订阅的过程。定义了对象之间一对多的依赖关系,当对象发生变化,通知对应的属性。
    发布订阅模式属于广义上的观察者模式。
    观察者模式(Vue双向绑定原理了解一下): 观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发(Fire Event)观察者里的事件。
	发布订阅模式: 订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
优点: 
     1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 
     1、太多的话消耗系能。 2、如有回调循环,系统就会崩溃  3、仅只是知道变化,不知怎么发生变化。
业务场景:
    dom点击事件监听。
代码场景:
    EventEmit的使用
18.状态模式
基本理解:
    类的行为是基于它的状态改变的。
优点: 
    1、封装了转换规则。 
    2、把状态封装为枚举,一目了然所有的状态。 3、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点: 
     1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好。
业务场景:
     天气冷的时候,我们穿厚衣服。天气热的时候,我们穿短袖这就是一个状态行为模式。
特别注意:
    在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。
19.策略模式
基本理解:
    针对不同的时间状态,给出不同的算法或者结果。
优点: 
     1、算法可以自由切换。 
     2、避免使用多重条件判断。 
     3、扩展性良好。
缺点: 
    1、策略类会增多。 2、所有策略类都需要对外暴露。
应用实例:
    工作日我们能做什么,非工作日我们能做什么。
    年终奖按员工绩效发放。
代码场景:
    form表达验证。
特别注意: 
    策略多于四个,可考虑混合模式。
20.解释器模式
基本理解:
   当一个“行为”,需要每次解释一个特定的上下文,而且成千上万次,这时候可以定义一个解释器。
优点: 
    1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。
缺点: 
    、可利用场景比较少。 2、对于复杂的文法比较难维护。 3、解释器模式会引起类膨胀。 
实战案例:
    sql打印器

21.模板模式
基本理解:
    但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
优点: 
    1、封装不变部分,扩展可变部分。 
    2、提取公共代码,便于维护。 
    3、行为由父类控制,子类实现。
缺点: 
    每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
应用实例:
    jpa的方法的封装。
    vue的官方api
代码实例:
    vue的solt方法

22.访问者模式
基本理解:
    主要将数据结构与数据操作分离。

23.迭代器模式
基本理解:
    提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
优点: 
    迭代器模式可以控制外部访问容器内部数据的顺序,它支持以不同的方式遍历一个聚合对象。
缺点: 
    增加了系统的复杂性
应用实例:
    Iterable的实现
    each  map都是
23.责任链模式
基本理解:
    用来处理相关事务责任的一条执行链。
优点: 
     1、降低耦合度。它将请求的发送者和接收者解耦。
     2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
缺点: 
    不能保证请求一定被接收
    代码调试时不太方便,可能会造成循环调用
应用实例:
    koa的源码。JS 中的事件冒泡