摘要:前面一段時間對和兩者的關系感到比較困惑我使用的動態語言揉合太多范式在這一點上很難做出明確透徹的區分不過經過這段時間琢磨相對之前感覺要好一些了有了一些自己的想法后面自己的部分會有不少沒有驗證的地方所以應該當成感想來看需要說明我的經驗來自動態語
前面一段時間對 FP 和 OOP 兩者的關系感到比較困惑
我使用的動態語言揉合太多范式, 在這一點上很難做出明確透徹的區分
不過經過這段時間琢磨相對之前感覺要好一些了, 有了一些自己的想法
后面自己的部分會有不少沒有驗證的地方, 所以應該當成感想來看
需要說明, 我的經驗來自動態語言(JavaScript), 相對靜態語言會有很多紕漏
當然這種事情先 Google 是必需的, 我當時微博標記了兩份比較在意的說明:
Functional programming vs Object Oriented programming
我摘錄的原文部分應該很有建設性, 就不翻譯了:
When you anticipate a different kind of software evolution:
Object-oriented languages are good when you have a fixed set of operations on things, and as your code evolves, you primarily add new things. This can be accomplished by adding new classes which implement existing methods, and the existing classes are left alone.
Functional languages are good when you have a fixed set of things, and as your code evolves, you primarily add new operations on existing things. This can be accomplished by adding new functions which compute with existing data types, and the existing functions are left alone.
When evolution goes the wrong way, you have problems:
Adding a new operation to an object-oriented program may require editing many class definitions to add a new method.
Adding a new kind of thing to a functional program may require editing many function definitions to add a new case.
根據估計的未來代碼中是數據或者是操作為主, 會有一定的區分
面向對象適合在新系統中接入新的數據, 函數式適合在原有代碼上增加新的方法
我覺得上邊說的 functional 和純函數的編程可能還有差別..
另一份實在 Haskell 的 Wiki 上,
The Monad.Reader/Issue3/Functional Programming vs Object Oriented Programming
這里摘錄的是在文章當中的一個引用:
To quote:
"The functional approach to programming is to ask "how is data constructed?". This leads to a style of programming where the data constructors are considered primitive, and where data-consuming code accordingly is defined by pattern-matching over these constructors. The object-oriented programmer instead starts out by asking "what can we do with the data?", which fosters the view that it is the data selectors that should be seen as foundational, and that the code of a data-producer consequently should be defined as an enumeration of implementations for these selectors."
What"s telling is the description of the effects (local and non-local) of different types of modification to the program:
"The functional style ensures that adding another data-consumer (a function) is a strictly local change, whereas adding a new data-producer requires extending a datatype with a new constructor, and thus a major overhaul of every pattern-matching function definition. Likewise, in object-oriented programming the addition of a new data-producer (a new class) is a cinch, while the introduction of another data-consumer means the extension of a record type with a new selector, a global undertaking with implications to potentially all existing classes."
不是完全理解, 大義應該有很多相似的地方,
FP 中數據類型是根基, 很容易增加數據操作, 增加數據類型需要大范圍調整
面向對象當中定義數據應有的操作, 增加操作會影響到大量數據擁有的方法(?)
麻煩的是在動態語言當中沒有 Java 也沒有 Haskell 那么多限制, 并不明確
所以看了上邊的解釋, 我其實還是有些糊涂, 雖然是我看到最明確的版本了
不過, immutable 那些特性可不是在這里邊講的,
Functional Programming Patterns (BuildStuff "14)
另外還有一份 FP 的資料, 只看到 slide, 沒找到視頻
其中一張挺有意思, 就是 OOP 里各種范式, FP 都用函數解決掉了
我想說是的, 困惑我的, 是 FP 和 OOP 在思維方式上的巨大差別
而隱藏在后邊的 immutable 特性, 在開始的時候更讓我困惑
后面就開始說我的困惑和理解吧(確實網上的內容我沒有理解透徹)
FP 和 OOP 不是截然對立的思維, 在編寫中實際上和經常相互滲透
OOP 當中, 比如動態語言隨時可能插入 FP 的 List 操作方法
而 FP 當中, 也可能模擬 OOP 對數據封裝和抽象(網上看到 Scheme 有例子, 不熟悉)
在 FP 當中, 很重要的概念是 Composable 和 Purity(可復合, 沒有副作用)
但 OOP 當中并不是不允許組合操作和避免副作用, 同時這些是編程貫穿的主題
Node 腳本的代碼, 模塊化, 減少依賴, 建立在 OOP 之上, 說法和 FP 并沒有太大區別
所以單純在用法上的區別, 我任務應該是由更為基本的規則引起的
加上排除語法, 排除類型, 我還是覺得 immutability 是最為重要的差別
換句話說, 一個名字, 或者參數一致的函數, 每次調用的結果是否完全一樣
FP 做了這樣的限定, 導致編碼的難度上升, 需要模擬每次操作后狀態的改變
在 FP 中, 就是生成一份新的數據, 通過高階函數, 模擬對同一個名字進行操作
但是首先, 共享變量名來進行消息傳遞這一點變得挺困難(或者說特殊)了
在 OOP 當中, 我們期待把大的問題拆解成幾個小的模塊分別解決
比如說, 為每個過程設定一些數據, 封裝然后暴露一些接口, 出來
最終模塊直接通過調用接口, 相互發送接受消息獨立完成工作, 完成整個任務
考慮數據 immutable 的話, 每個模塊內部狀態就不能實現了
那么這部分狀態將被提取出來放到全局, 再作為參數傳回到模塊當中
這時的模塊更像是 pipe 的概念, 整個程序的運行就是在管道當中流動
一個好處是數據不再像 OOP 那樣存在多份, 需要設計機制去同步
后面是最近我在思考 Cumulo 實現的過程考慮到的和想到的問題
這是我第一次拋開框架寫后端代碼, 剛一開始被怎樣組織代碼所困擾
困擾之后我還是用 mutable 數據還消息來勾勒整個消息傳播的方案
嘗試之后我采用一個架構圖描繪了數據怎樣在這個程序當中流動
也許我可以這樣思考程序, 將程序劃分為幾塊, 分別對應功能:
數據結構, 初始的資源和狀態 --> 這是一個適合機器的形態
交互的界面 --> 數據結構轉化為適合人類編寫, 調試, 查看, 交互的形態
業務邏輯 --> 決定數據怎樣改變的操作的規則
架構 --> 操作或者事件, 怎樣正確有效更新整個程序范圍的資源和狀態
程序越大, 思考架構越發困難, 特別是要照顧好多的細節, 細節相互沖突
簡化來說, OOP 似乎很容易想采用消息, 讓每個模塊以監聽的方式更新和同步
而在 FP, 沒有消息, 轉而采用定向的數據流動, 逐個地想做系統狀態進行更新
現在我了解的, OOP 操作簡單, 可是當模塊繁多, 容易造成節奏紊亂, 難于調試
FP 則是不容易設計實現, 現實世界狀態凌亂, 難以符合單向流的形式
另外我也注意到, 就是在微博上發的那條感想:
最近想起王垠那個比喻, 可變數據像 WIFI, 不可變數據像線, WIFI 方便多了. 可是從另一個角度看 WIFI 是短距離穩定, 遠了信號差, 線麻煩是麻煩, 遠距離傳輸損耗小(也不能普通網線...). 可變數據不用面向對象那樣封裝在局部進行控制, 變量多了真心容易亂. 不可變數據呢門檻又高..
mutable 數據, 如果被反復轉發傳送, 很可能會在某些操作當中被更改
當數據容易發生難以預料的更改, 構建大程序也就成了麻煩了
因此對于 mutable 數據, 在本地進行封裝, 不直接對外暴露, 是極為合理的做法
這在 JavaScript 當中, 對象被不斷引用共享, 直到出現 bug, 是很可能發生的事情
那么思考大程序的話, mutable 數據是應該盡量減少的方案
到目前為止, 我所能相對的構建程序最讓我覺得建設性的是這個架構圖
即便真心寫到沒思路了, 好歹還能照著圖用拙劣的代碼補上一些功能上去
對著 FP 和 OOP 這些爭論了許久的功能思考不清楚, 只能按著圖上瞎寫
希望能早點走出這篇迷霧吧..
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/11706.html
摘要:避免脆弱的基類問題。紅牌警告沒有提到上述任何問題。單向數據流意味著模型是單一的事實來源。單向數據流是確定性的,而雙向綁定可能導致更難以遵循和理解的副作用。原文地址 1. 你能說出兩種對 JavaScript 應用開發者而言的編程范式嗎? 希望聽到: 2. 什么是函數編程? 希望聽到: 3. 類繼承和原型繼承的不同? 希望聽到 4. 函數式編程和面向對象編程的優缺點? ...
摘要:前言最近花了不少時間接觸學習的函數式的編程方式,而后為了加深理解,又去折騰。不過幸運的是,天生具備了函數式編程的基本元素,所以學習的起點不會太低。初接觸第一個實例,函數式編程是如何做一個番茄炒雞蛋的。 前言 最近花了不少時間接觸學習javascript的函數式的編程方式,而后為了加深理解,又去折騰haskell。 不同于人們比較熟悉的命令式編程,如面向對象編程(oop),函數式編程(f...
摘要:我們作為前端開發,都應該具有這樣的能力。那么如何才能降低業務開發的復雜度呢細分組件都說模塊化開發,其實在,這些思想規范之前就已經有模塊化開發的規范了,雖然標準從然后隔了年才有了,在那年基本都是函數式開發,一切皆函數。 優秀的程序員總是能優雅的組織自己的代碼,清晰的編寫思路,合理的組織結構劃分,從小的功能組件,到大的模塊結構,都能通過合理的巧妙的搭配,不僅能化復雜為簡單,更能提升代碼運行...
摘要:我們作為前端開發,都應該具有這樣的能力。那么如何才能降低業務開發的復雜度呢細分組件都說模塊化開發,其實在,這些思想規范之前就已經有模塊化開發的規范了,雖然標準從然后隔了年才有了,在那年基本都是函數式開發,一切皆函數。 優秀的程序員總是能優雅的組織自己的代碼,清晰的編寫思路,合理的組織結構劃分,從小的功能組件,到大的模塊結構,都能通過合理的巧妙的搭配,不僅能化復雜為簡單,更能提升代碼運行...
摘要:我們作為前端開發,都應該具有這樣的能力。那么如何才能降低業務開發的復雜度呢細分組件都說模塊化開發,其實在,這些思想規范之前就已經有模塊化開發的規范了,雖然標準從然后隔了年才有了,在那年基本都是函數式開發,一切皆函數。 優秀的程序員總是能優雅的組織自己的代碼,清晰的編寫思路,合理的組織結構劃分,從小的功能組件,到大的模塊結構,都能通過合理的巧妙的搭配,不僅能化復雜為簡單,更能提升代碼運行...
閱讀 2229·2019-08-30 10:51
閱讀 785·2019-08-30 10:50
閱讀 1463·2019-08-30 10:49
閱讀 3130·2019-08-26 13:55
閱讀 1591·2019-08-26 11:39
閱讀 3412·2019-08-26 11:34
閱讀 1937·2019-08-23 18:30
閱讀 3381·2019-08-23 18:22