
曾探
本书是根据JavaScript语言的特性专门针对JavaScript语言全面总结的设计模式。全书共分为三个部分,第一部分讲解了JavaScript语言面向对象和函数式编程的知识及其在设计模式方面的作用;第二部分通过一步步完善的代码示例,由浅入深地讲解了16个设计模式;第三部分讲述了面向对象的设计原则及其在设计模式中的体现,以及一些常见的面向对象编程技巧和日常开发中的代码重构。 书中所有示例均来自作者长期的开发实践,与实际开发密切相关,适合Web前端开发人员阅读。
基本涵盖所有常见设计模式,章节内容安排较好,先是一个生动的示例作为引子,说明模式的用途,然后是代码实现,最后结合实际项目,比较未应用模式和应用模式之后的区别。 “设计模式”就是对的代码实现遇到对的场景的一种结合。甚至模式之间有不少相似之处,大都有着抽象、分离、封装的影子,但因为意图不同,用法不同,就成为了不同的模式。 书的后半部分加入了一些代码设计的原则,比如:单一职责、最小知识、开放-封闭等,很有指导意义。 值得一提的是,并不一定要处处遵守模式或者原则,就像我们不主张过早优化一样。书中有一句引用能够很好地说明:“愚弄我一次,应该羞愧的是你。再次愚弄我,应该羞愧的是我。”当我们多次被愚弄,或许就是要优化代码的时候~ 五星推荐。
之前也读过设计模式,这回读的时候,有了工作经历,就能发现自己写的哪些还能优化,确实有的书就得多度几遍,学以致用才是最好的读书方式。
正如书中的笔记说的:突然之间感觉,我领会了一点JS OOP的精髓了。 这本书写的真的很棒,例子不多,但是却由浅入深,是设计模式的入门书籍,实用不枯燥。设计模式的场景是无穷的,掌握并不断在工作中实践,才是设计模式真正的魅力。但是一味堆砌模式也是不可取的,以不变应万变也是模式的一种提倡。
学习设计模式还是非常有必要的,可能我们自己也不太常用或者会用,但是一旦别人用了,我们起码要能看懂。讲设计模式的书有很多,和js关联的却没有很多,本书实践性比较强,学习的过程中最好自己敲一遍例子,这样能记得扎实一些。但是这本书也有不足的地方,很多理论的地方讲的不是很清晰,推荐大家看一下《设计模式之禅》这本书,虽然是java语言的,但是并不妨碍读,书中的知识挺全的,可以看看查缺补漏,这两本书都非常推荐
提供了面向对象和函数式两种范式的设计模式思路
本书以JavaScript语言特性为根基,将设计模式的理论与实际开发紧密结合,各章节核心内容可总结如下: 基础篇 - 第1章 面向对象的JavaScript:JavaScript作为基于原型的动态语言,其面向对象机制与传统面向类的语言有显著差异。对象本质上是属性的集合,包括数据属性和访问器属性,方法则作为函数属性存在。继承通过原型链实现,每个对象的 __proto__ 指向原型对象,原型上的属性和方法可被实例共享。书中推荐“寄生组合继承”,通过创建父类原型的副本并修正构造函数指向,既避免了原型属性共享的问题,又减少了构造函数的调用次数,是较优的继承实现方式。 - 第2章 this、call和apply:this的指向是JavaScript中的核心难点,其具体指向由函数的调用方式决定,主要有四种绑定规则:默认绑定时,函数独立调用,this指向全局对象(严格模式下为 undefined );隐式绑定时,函数作为对象方法被调用,this指向该对象;显式绑定通过 call 、 apply 或 bind 实现,可强制改变this指向;new绑定时,构造函数通过 new 调用,this指向新创建的实例对象。 call 和 apply 功能相似,均用于改变this指向,区别在于参数传递方式, call 接收参数列表, apply 接收数组或类数组对象,它们在实现继承、借用方法等场景中应用广泛。 - 第3章 闭包和高阶函数:闭包是指函数能够访问其声明时所在的作用域,即便函数在外部被调用,其核心是作用域链的保留。闭包在模块化开发中可用于封装私有变量,仅暴露公共接口,也可用于延迟执行,如在定时器、事件回调中保存上下文状态。高阶函数是指接收函数作为参数或返回函数的函数,常见应用包括函数节流与防抖(用于控制高频事件的执行频率)、柯里化(将多参数函数转换为单参数函数序列,增强函数的灵活性)等。 设计模式篇 - 第4章 单例模式:单例模式的核心是确保一个类仅有一个实例,并提供全局访问点。其基本实现思路是通过一个变量标记实例是否已创建,若已创建则返回现有实例,否则新建实例。透明单例让用户可像使用普通类一样创建实例,通过闭包隐藏实例标记;惰性单例则在首次需要时才创建实例,避免了不必要的资源浪费,适用于弹窗、全局状态管理等场景。 - 第5章 策略模式:策略模式的本质是定义一系列算法,将每个算法封装为独立的策略对象,使算法可灵活切换,从而避免大量的条件判断。模式包含策略类(封装具体算法,提供统一接口)和环境类(接收策略对象并调用其算法)。在表单验证场景中,传统方式用 if...else 判断不同字段的验证规则,而策略模式将规则封装为策略对象,新增规则只需扩展策略对象,无需修改验证逻辑,符合开放-封闭原则。 - 第6章 代理模式:代理模式为对象提供一个替代对象,以控制对原对象的访问。常见的代理类型包括保护代理(控制不同用户对原对象的访问权限,如过滤未登录用户的操作)、虚拟代理(延迟原对象的创建,直到真正需要时再初始化,如图片懒加载先显示占位图,加载完成后替换)、缓存代理(缓存函数计算结果,避免重复计算,如缓存加法等函数的结果)等,代理模式在权限控制、性能优化等方面有重要应用。 - 第7章 迭代器模式:迭代器模式提供一种遍历集合元素的统一接口,屏蔽不同集合的内部结构差异,方便对数组、对象、Map等不同数据结构进行遍历。内部迭代器将迭代逻辑封装在内部,用户只需传入集合和处理函数(如 forEach );外部迭代器则由用户控制迭代过程,可手动调用 next 方法遍历,灵活性更高。通过实现不同数据结构的迭代器,可统一遍历方式,简化操作。 - 第8章 发布-订阅模式:发布-订阅模式(又称观察者模式)定义了对象间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都会收到通知并自动更新。模式包含发布者(维护订阅者列表,提供订阅、取消订阅和发布通知的方法)和订阅者(提供接收通知的回调函数)。该模式适用于事件系统、状态管理等场景,能有效解决异步编程中的回调地狱问题,例如多个异步操作完成后通过发布事件触发回调。 - 第9章 命令模式:命令模式将请求封装为对象,使请求的发送者与接收者解耦,支持请求的参数化、排队、撤销等操作。模式包含命令对象(封装请求的接收者和执行方法 execute )、调用者(触发命令的执行)和接收者(实际执行请求的对象)。在遥控器控制家电等场景中,命令模式将“打开”“关闭”等请求封装为命令对象,遥控器作为调用者触发命令,家电作为接收者执行操作,实现了发送者与接收者的解耦。 - 第10章 组合模式:组合模式主要用于处理树形结构,让单个对象和组合对象(子节点集合)具有一致的接口,方便对整个树形结构进行操作。例如在菜单系统中,菜单项(单个对象)和子菜单(组合对象)都可调用 add 方法添加子元素、 render 方法渲染自身,用户无需区分是单个对象还是组合对象,简化了对树形结构的处理。 - 第11章 模板方法模式:模板方法模式由父类定义算法的骨架,而将算法中的某些步骤延迟到子类中实现,子类可以重写这些步骤,但不能改变算法的整体结构。这种模式实现了代码复用,父类的模板方法固定了算法流程,子类通过重写部分步骤扩展功能,例如咖啡制作的流程固定(煮水、冲泡、倒入杯子等),拿铁、美式等不同咖啡只需重写“冲泡”步骤。 - 第12章 享元模式:享元模式的核心是复用相似对象,减少内存占用,其关键是分离“内部状态”(可共享的部分)和“外部状态”(个性化的部分)。例如在游戏中,大量士兵对象可以共享武器模型等内部状态,而位置等外部状态则各不相同,通过享元模式可避免创建大量相似对象,节省内存资源。 - 第13章 职责链模式:职责链模式让多个对象依次处理请求,每个对象都可以决定自己处理请求还是将其传递给下一个对象,从而避免请求的发送者与接收者之间的直接耦合。在表单验证等场景中,不同的验证规则(如非空验证、长度验证、格式验证等)可组成一条职责链,依次对数据进行检查,符合条件则传递给下一个,不符合则返回错误信息。 - 第14章 中介者模式:中介者模式通过一个中介者对象来封装一系列对象之间的交互,使这些对象不需要直接相互引用,从而减少对象间的耦合。例如在聊天室中,用户之间不直接发送消息,而是通过聊天室中介者转发,用户只需与中介者交互,简化了对象间的关系,降低了系统的复杂性。 - 第15章 装饰者模式:装饰者模式动态地给对象添加额外的功能,而不改变对象的原有结构,相比继承更加灵活。它可以在不修改原对象的情况下,通过包装的方式扩展功能,且可以动态添加或移除装饰。例如给函数添加日志功能时,可创建一个装饰器函数包装原函数,在执行原函数前后输出日志,而不修改原函数代码。 - 第16章 状态模式:状态模式允许对象在其内部状态发生变化时改变其行为,仿佛对象本身改变了类。模式将对象的不同状态封装为独立的状态对象,每个状态对象实现了该状态下的行为,当对象的状态改变时,会切换到相应的状态对象。例如电梯有运行、停止、开门、关门等状态,每个状态下的行为不同,通过状态模式可清晰管理电梯在不同状态下的操作。 - 第17章 适配器模式:适配器模式用于转换一个接口为另一个接口,使原本不兼容的类能够协同工作。它解决了不同接口之间的匹配问题,例如当系统需要调用一个第三方接口,而该接口的参数格式或返回值格式与系统内部不一致时,可通过适配器进行转换,使系统能够正常使用该接口。 - 第18章 外观模式:外观模式为子系统中的一组接口提供一个统一的高层接口,简化了子系统的使用。它隐藏了子系统的复杂性,外部只需与外观接口交互,无需了解子系统的内部细节。例如封装多个DOM操作方法(如创建元素、添加样式、绑定事件等)为一个外观方法,外部调用该方法即可完成一系列操作,简化了代码。 - 第19章 桥接模式:桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。它解决了抽象和实现之间的强耦合问题,例如在设计图形时,可将图形的形状(抽象部分)与颜色(实现部分)分离,形状和颜色可以独立扩展,通过桥接将两者结合,形成不同的图形(如红色圆形、蓝色方形等)。 实践与扩展篇 - 第20章 设计原则:本章强调了设计模式背后的核心原则,如开放-封闭原则(对扩展开放,对修改关闭)、单一职责原则(一个类只负责一个功能领域的相应职责)、依赖倒置原则(依赖抽象,不依赖具体实现)等。这些原则是指导设计模式合理应用的基础,帮助开发者避免过度设计,确保系统具有良好的可扩展性、可维护性。 - 第21章 代码重构:结合设计模式讲解了如何对现有代码进行优化,提升代码的可读性、可维护性和可扩展性。例如当代码中存在大量的条件判断时,可使用策略模式替代;当需要为对象动态添加功能时,可使用装饰者模式等。重构的过程是逐步应用设计模式,使代码结构更清晰,更符合设计原则。 - 后续章节:多围绕实际开发场景展开,探讨了设计模式的组合使用(如将策略模式与模板方法模式结合,发挥各自优势)、在主流框架(如Vue、React)中的应用等。强调设计模式是解决问题的思想和方法论,而非固定的代码模板,在实际开发中需根据项目的复杂度和需求灵活选用,避免生搬硬套。 本书的核心价值在于将设计模式与JavaScript的语言特性深度融合,注重实际应用,通过大量实例展示了如何运用设计模式解决开发中的痛点问题,帮助开发者写出更优雅、更易维护的代码。
适合作为设计模式的初学者来入门设计模式,书中没有像其他较大型的书一样将23种设计模式分为三类,也没有讲完全部的模式,只是讲了一些JS或者说前端领域常用的模式,将来有时间可以再看看其他设计模式相关读物。总结一下看完的感悟:为了写出更好维护更易扩展更好读同时也尽可能优化一下性能的代码,我们提炼出了一些写代码的原则,包括但不限于开放封闭原则,最小知识原则等等,但原则过于抽象,为了让程序员更方便的写出符合原则的代码,才有了设计模式,可以认为,设计模式就是符合其中部分或全部原则的代码模板,让我们能够有意的写出好的代码。但无论是设计模式还是原则,都只是一种建议或者说指导,完全可以不遵守,实际的业务中,大多数代码基本都不会考虑这些,这才成就了我们常说的屎山代码。一般来说,优秀的开源框架或工具会运用较多优秀的设计模式,即使是业务代码中用到了设计模式,往往也不是一开始就那样设计的,大多情况下都是先草草了事,然后真正迎来一定程度的需求增加而导致的代码重构时,才现去重构代码,运用模式。
作者使用通俗易懂的正反例来突出设计模式的优点,在介绍设计模式的优点时准确的体现出使用场景。虽然优秀的设计模式可以为我们带来高质量的代码,为后期维护奠定良好的基础,但是不要捡了芝麻丢了西瓜,要根据需求和具体的场景去使用,过度的设计会带来代码的复杂度。 已经是一名快四年的前端开发了,阅读此书的过程中回想起开发过程的代码时难免羞愧,羞愧于“差不多就行了”、“功能没问题就行了”等等敷衍了事的话语。 直到某一天,我告诉自己,我应该成为一名优秀的程序员,内心告诉我想成为优秀的程序员必须是一个不断完善的过程,技术是,人亦是。 当我阅读每一种设计模式的时候,脑海里会浮现出工作中遇到的需求场景,其实很多时候我们都在用这些模式,却不知晓。也会发现原来通过这些优秀的模式可以写出这么易读、灵活、易维护的代码,作者为我的代码世界打开了一扇窗,接下来我会回头看看以前写的代码,琢磨琢磨有没有更好的方式。希望大家在编程的道路上越来越秃出!
总体上还好,用js的思维去看传统面向对象的设计模式是比较独特的。不过在现在ts和es6盛行,写法上与传统编译时语言很接近了。
本书写的很不错,由浅入深通俗易懂,可以帮助代码写的更好。尤其是像JS这样的动态语言,如果代码结构设计的不好,很容易写出难以重用和维护的代码。 前端之路中,设计模式是必须涉及的知识,这本书就不错,可以当做入门书籍。