iT邦幫忙

2022 iThome 鐵人賽

DAY 2
1
Modern Web

致 JavaScript 開發者的 Functional Programming 新手指南系列 第 2

Day 2 :初探設計典範(1):FP 的崛起、沒落、東山再起(修正版)

  • 分享至 

  • xImage
  •  

在前一章節中,我們曾經聊到初級前端工程師在撰寫或是學習 JavaScript 會遇到的元件封裝問題,但除了元件的封裝外,相信大家也會有以下疑惑:

  • 要怎麼預防臭蟲誕生,或是降低其數量?
  • 如何提高程式碼的復用性及可維護性?
  • 如何優化我的 JavaScript 效能,及為什麼要優化 JavaScript?

其實這些都可以透過導入 FP 來解決,在了解 FP 是什麼以前,我們首先要了解設計典範的概念。

什麼是設計典範?

設計典範(Programming Paradigm)意指的是:特定的程式設計風格。

在 JavaScript 中,最常被大家提起的設計典範有:物件導向程式設計(Object-oriented Programming,簡稱 OOP)與函式程式設計(Functional Programming,簡稱 FP),兩者最大的差異在於,物件導向設計是以實作物件為基礎,而在 FP 中我們使用函式來解決所有的問題。

當然,僅僅是一兩句話很難將 FP 的所提供的思維與方法簡單說完,其中甚至更牽涉到一些複雜的 JavaScript 底層的實作原理,但沒關係,我們之後都會一一聊到。

在切入 FP 及相關必備知識前,我們先來聊聊關於 FP 興起到沒落的演進史,及直到最近才又興起的原因。

FP 的興起

FP 的概念最早由二十世紀初的數學家 Alonzo Church 所提出的 Lambda 演算法,這套演算法主要是使用變數綁定及抽換變數的方式來進行函式的應用。

而同一時期的數學家 Alan Turing,沒錯!就是電影《模擬遊戲》( Imitation Game)的那個數學天才主角艾倫・圖靈,其發明的圖靈機(Turing Machine)也驗證了 Lambda 演算法的可行性,而 FP 一切就從這裡開始,圖靈因此還獲得了電腦科學之父的美稱。

在 Lambda 演算法中,可以說是函式為王,任何東西都可以是函式,包括單純的數字。

將函式作為成構成軟體服務最小的原子單位,完全展現了這個演算法所要呈現的概念。在 Lambda 演算法中,有幾個很著名的特色:

  1. 函式通常是匿名的
  2. 只進行一元運算
  3. 函式可以作為參數或是回傳值
  4. 映射概念

當然這些特色套用在 JavaScript 也完全適用,在之後我們深入了解 JavaScrpit 這門語言的特性後,就更能理解為什麼我們在 JavaScript 中結合 Lambda 演算法可以變得如此強大。

FP 的沒落與東山再起

二十世紀中期,網際網路開始發展起來的年代,也正是物件導向設計的興起,當時候 Java 這門語言熱門到連網頁腳本語言的雛形(也就是當時的 JavaScript )都要拿它的名字與設計架構作為借鑒。

於是在現代網頁 ES6 規範普遍化以前,基本上都是物件導向獨大的世代。

當然,在之後我們深入了解 JavaScrpit 這門語言的特性後,也會知道 JavaScript 是一個四不像的物件導向語言,而這個四不像的特性為後世的我們帶來了許多麻煩,例如:為了要讓 JavaScript 的出錯率降低,我們還要導入一些其他的工具來限制它的撰寫風格。

於是,相對於複雜的物件導向,在現代網頁的技術逐漸進步且技術統一後,比物件實作更單純不少的函式,也就是我們接下來要聊的 FP 設計典範,漸漸開始東山再起,也讓前端開發者除了物件導向設計外,多了其他更方便且簡易的設計典範選擇。

但隨著 FP 的再次興起,另外一種討論聲浪也隨之而起:「在 JavaScript 中,是 OOP 好?還是 FP 更好?」

針對 OO 與 FP 的世紀之戰,我個人非常認同《Composing Software》一書中所提到的概念,作者 Eric Elliott 說道:「探討這個問題是很沒意義的,幾乎所有自己所看過的大型服務,都不會是完全的物件導向設計或是 FP ,更多時候是混著用的。

JavaScript 主要的開發者 Brendan Eich 在其 2008 年《Popularity》一文中提及 JavaScript 是一個符合當時開發者習慣所誕生的語言,當時 Brendan Eich 基於「在瀏覽器中實作 Scheme(註一)」的承諾條件,加入網景公司(註二),然而來自網景公司高層的命令:Brendan Eich 著手開發的這門語言「要長得像 Java」,讓這門語言成了長得像物件導向,但其實是以原型導向設計及 FP 設計理念為原型的 JavaScript。

現在大家知道問題出在哪了吧?

我們的最終的目的終究是為了要解決軟體架構中的問題,若是可以有效解決問題且好維護的方法就是好方法,因此在本系列文章中,也不會針對 OOP 與 FP 設計典範的差異進行深入討論,更多還是專注在如何透過 JavaScript 這門語言來學習 FP,並且透過 FP 讓我們的程式碼的品質更好。

在下一個章節中,我們就要來看看 FP 主要要透過怎麼樣的方式,讓開發者們可以透過函式來解決大部分的問題,且透過什麼樣的機制來讓程式碼可以更加嚴謹,產生更少的錯誤,那我們就下一章節見啦!

註解:

  1. Scheme 是一個 LISP 家族語言,LISP 系列的語言最早出現在 1950 年代末期,是受到 Alonzo Church 的 Lambda 演算法影響所實作出來的程式語言,LISP 語言開創許多程式語言的重要特性,例如:樹狀結構(Tree Data Structure)、記憶體回收機制(Garbage Collection)、動態型別(Dynamic Typing)、條件表達式(Conditional Expression)、高階函式(High Order Function)與遞迴(Recursion)的概念。許多程式語言深受 LISP 家族語言影響,JavaScript 便是其中之一,JavaScript 開發者 Brandan Eich 曾在部落格表述 JavaScript 就是基於 Scheme 這門程式語言所實作出來的。
  2. 網景通訊公司(Netscape Communications Corporation),簡稱網景,為最早應用 JavaScript 這門語言的網際網路通訊公司,為早期網頁時代的領域龍頭,後因為 Netscape 瀏覽器不敵微軟旗下之 Internet Explorer(IE)瀏覽器,公司經營每況愈下,於 2007 年被威訊媒體(Verizon Media)旗下子公司 AOL 收購,Netscape 瀏覽器則於 2008 年停止支援。

參考資料:

  1. wikipedia - software design pattern
  2. wikipedia - lambda calculus
  3. wikipedia - Alan Mathison Turing
  4. wikipedia - Scheme
  5. wikipedia - LISP
  6. wikipedia - tree data structure
  7. wikipedia - Netscape
  8. Brendan Eich - Popularity
  9. Eric Elliot (2019). Composing Software: An Exploration of Functional Programming and Object Composition in JavaScript(pp. 13-17).

上一篇
Day 1: 致 JavaScript 開發者的 Functional Programming 指南(修正版)
下一篇
Day 3:初探設計典範(2):FP 簡介(修正版)
系列文
致 JavaScript 開發者的 Functional Programming 新手指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
良葛格
iT邦新手 2 級 ‧ 2022-09-06 11:38:16

雖然電腦科學界在名詞方面通常沒有嚴謹的定義,不過談到設計模式(Design pattern),狹義而言是指 Gof 的 23 個設計模式,廣義而言就是指一些程式元件實作時的模式。

至於 OO 或 FP,一般是使用 paradigm 這個名詞(你的下一篇文就用了 Multi-paradigm 這個形容),通常可譯為典範之類。

非常感謝大大的提醒 > <
自己確實對 paradigm 與 Design pattern 定義有點模糊,這邊後續會再把內文修正回來,非常感謝!!

良葛格 iT邦新手 2 級 ‧ 2022-09-13 16:54:41 檢舉

如果你想從現代語言裡,去試著理解 FP,可以參考一下這邊:
https://openhome.cc/zh-tw/pattern/functional/

我會再去閱讀的,非常感謝!

我要留言

立即登入留言