
曾探
本書是根據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這樣的動態語言,如果代碼結構設計的不好,很容易寫出難以重用和維護的代碼。 前端之路中,設計模式是必須涉及的知識,這本書就不錯,可以當做入門書籍。