Nestjs框架: 關于 OOP / FP / FRP 編程

概述

  • 在軟件開發過程中,不同的編程范式為我們提供了多樣化的思維方式與實現路徑
  • 它們不僅影響著代碼的結構和邏輯組織方式,
  • 也深刻影響著項目的可維護性、可擴展性以及團隊協作效率

什么是 OOP、FP 和 FRP?


首先從三個術語的含義入手

1 )OOP(Object-Oriented Programming)

  • 即面向對象編程,是一種將現實世界中的事物抽象為“對象”的編程范式
  • 每個對象擁有自己的屬性和方法,通過類(class)來定義這些對象的共同特征

2 )FP(Functional Programming)

  • 即函數式編程,強調“函數”作為程序的基本構建單元
  • 主張將邏輯封裝在純函數中,注重數據變換而非狀態變化

3 )FRP(Functional Reactive Programming)

  • 即函數式響應式編程,是函數式編程與響應式編程的結合體
  • 適用于處理異步事件流,常用于 UI 編程、事件驅動等場景
  • 這三種編程范式并非彼此對立,而是適用于不同場景的編程風格
  • 它們分別代表了軟件開發中三種重要的抽象方式:對象抽象、函數抽象與事件流抽象

OOP 與 FP 的核心區別與實現對比


以一個實際的前端登錄注冊功能為例,來對比 OOP 和 FP 兩種范式的實現方式

1 )通用頁面結構

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>FP&FRP</title><script src="./index.js" defer></script></head><body><div class="container-sm pt-4"><form class="col-4" id="login-form"><div class="mb-3"><label for="username" class="form-label">用戶名:</label><inputtype="text"class="form-control"name="username"id="username"aria-describedby="username-help"/><div id="username-help" class="form-text"></div></div><div class="mb-3"><label for="password" class="form-label">密碼</label><inputtype="password"name="password"class="form-control"id="password"/><div id="password-help" class="form-text"></div></div><div class="mb-3 form-check"><input type="checkbox" class="form-check-input" id="remember" /><label class="form-check-label" for="remember">記住我</label></div><button type="submit" class="btn btn-primary" id="btn">注冊或登錄</button></form></div></body>
</html>

2 )面向過程編程:傳統邏輯結構

// 獲取form對象
// 當用戶點擊提交按鈕時,獲取用戶輸入的值
// 校驗用戶輸入的值
// 如果校驗通過,模擬發送請求提交表單
const form = document.getElementById('login-form');
const username = document.getElementById('username');
const password = document.getElementById('password');function submitHandler(evt) {evt.preventDefault();const usernameValue = username.value;const passwordValue = password.value;if (usernameValue.trim().length === 0) {alert('用戶名不能為空');return;}if (passwordValue.trim().length < 6) {alert('密碼長度不能小于6位');return;}const user = {username: usernameValue,password: passwordValue,};console.log(user);console.log('用戶' + user.username + '登錄成功');
}form.addEventListener('submit', submitHandler);
  • 在傳統的面向過程編程中,我們通常會按照“順序執行、逐步處理”的方式去實現功能。
  • 例如:
    • 首先完成頁面結構與樣式;
    • 然后綁定表單提交事件;
    • 接著讀取輸入框的值;
    • 再進行輸入校驗;
    • 最后將數據打印或發送請求。
  • 這樣的邏輯雖然直觀,但隨著功能的復雜度增加,會導致代碼冗長、不易維護、邏輯耦合度高

3 ) 函數式編程(FP)的核心實現思路

// 獲取form對象
// 當用戶點擊提交按鈕時,獲取用戶輸入的值
// 校驗用戶輸入的值
// 如果校驗通過,模擬發送請求提交表單
const REQUIRED = 'REQUIRED';
const MIN_LENGTH = 'MIN_LENGTH';// 函數式編程
function validate(value, flag, validatorValue) {if (flag === REQUIRED) {return value.trim().length > 0;}if (flag === MIN_LENGTH) {return value.trim().length > validatorValue;}
}function getUserInput(inputId) {return document.getElementById(inputId).value;
}function createUser(username, password) {if (!validate(username, REQUIRED) || !validate(password, MIN_LENGTH, 6)) {// alert -> 副作用 -> 依賴外部環境(HTTP請求、修改DOM等操作了外部環境)// -> 在函數式編程中,盡量要避免出現副作用throw new Error('用戶名或者密碼不符合要求');}return {username,password,};
}function greet(user) {console.log('用戶' + user.username + '登錄成功');
}function submitHandler(evt) {evt.preventDefault();const usernameValue = getUserInput('username');const passwordValue = getUserInput('password');try {const user = createUser(usernameValue, passwordValue);console.log(user);greet(user);} catch (error) {alert(error.message);}
}function createForm(formId, handler) {const form = document.getElementById(formId);form.addEventListener('submit', handler);
}createForm('login-form', submitHandler);

在函數式編程中,我們通過函數的組合與復用來構建邏輯:

  • 定義一個 createForm(formID, handler) 函數,用于綁定表單提交事件;
  • 定義 submitHandler 函數,用于處理提交后的邏輯;
  • 定義 getInputValues 函數,用于獲取輸入框的值;
  • 定義 validate 函數,用于校驗輸入是否合法;
  • 定義 createUser 函數,用于創建用戶對象并返回;
  • 最后通過 console.log 打印成功信息。

函數式編程的核心特征包括:

  • 純函數:對于相同的輸入,總是返回相同的輸出,沒有副作用;
  • 可組合性:函數之間可以相互調用、組合,形成清晰的數據流;
  • 高復用性:函數可以被多個模塊復用,提升代碼維護效率;
  • 可測試性強:由于函數是獨立的,單元測試更容易實現。

函數式編程非常適合處理數據變換、邏輯解耦和異步流程控制

4 )面向對象編程(OOP)的核心實現思路


在面向對象編程中,我們通過類和對象來組織代碼結構:

// 獲取form對象
// 當用戶點擊提交按鈕時,獲取用戶輸入的值
// 校驗用戶輸入的值
// 如果校驗通過,模擬發送請求提交表單
class Validator {static REQUIRED = 'REQUIRED';static MIN_LENGTH = 'MIN_LENGTH';static validate(value, flag, validatorValue) {if (flag === this.REQUIRED) {return value.trim().length > 0;}if (flag === this.MIN_LENGTH) {return value.trim().length > validatorValue;}}
}class User {constructor(username, password) {this.username = username;this.password = password;}greet() {console.log('用戶' + this.username + '登錄成功');}
}class UserInputForm {constructor() {this.form = document.getElementById('login-form');this.username = document.getElementById('username');this.password = document.getElementById('password');// 這里要注冊第二個submitHandler為什么要使用bind// addEventListener的第二個參數是一個回調函數,回調函數中的this指向的是當前的DOM元素// 但是這里的this,需要指向的是UserInputForm,所以需要使用bind修改this的指向this.form.addEventListener('submit', this.submitHandler.bind(this));}submitHandler(evt) {evt.preventDefault();const usernameValue = this.username.value;const passwordValue = this.password.value;if (!Validator.validate(usernameValue, Validator.REQUIRED) ||!Validator.validate(passwordValue, Validator.MIN_LENGTH, 6)) {alert('用戶名或者密碼不符合要求');return;}const user = new User();user.username = usernameValue;user.password = passwordValue;console.log(user);user.greet();// console.log('用戶' + user.username + '登錄成功');}
}new UserInputForm();
  • 我們定義了三個類:ValidatorUserLoginForm
  • LoginForm 類負責綁定表單事件、讀取輸入、調用校驗器、創建用戶
  • User 類封裝了用戶的屬性和行為(如 greet() 方法)
  • Validator 類提供靜態方法 validate() 來完成輸入校驗

OOP 的三大核心特性是:

  • 封裝性:將數據和操作封裝在一個類中,增強模塊化
  • 繼承性:通過繼承復用已有類的屬性和方法
  • 多態性:同一方法在不同對象中有不同實現

面向對象編程更適合建模現實世界的結構、處理復雜的業務邏輯與狀態管理

5 )函數式響應式編程(FRP)

const btn = document.getElementById('btn');function inputHandler(evt) {if (username.value.trim().length === 0 || password.value.trim().length < 6) {btn.disabled = true;return;}btn.disabled = false;
}
username.addEventListener('input', inputHandler);
password.addEventListener('input', inputHandler);
  • 雖然在本次示例中沒有詳細展開 FRP,但我們可以簡要介紹其核心思想與適用場景

什么是函數式響應式編程?

  • 函數式響應式編程(FRP)是函數式編程與響應式編程的結合,強調對事件流進行函數式處理
  • 它通過將事件流視為可組合、變換的數據流,實現復雜的異步邏輯處理。

典型應用場景

  • 表單實時校驗:當用戶輸入時,自動判斷輸入是否合法,并動態修改按鈕狀態
  • 聊天推薦系統:點擊拒絕推薦后,自動請求新數據并更新界面
  • 實時數據展示:如股票價格、天氣數據等需要響應變化的場景

核心特點

  • 響應式處理事件流:將事件流視為可觀測的數據流,進行函數式操作
  • 異步處理友好:天然適合處理異步、并發、事件驅動的場景
  • 依賴第三方庫:如 RxJS、MobX、Vue 3 的響應式系統(Composition API)等
  • 發布-訂閱模式:通過訂閱事件流來響應數據變化,實現 UI 與狀態的自動同步

OOP 與 FP 應該如何選擇?


在實際開發中,OOP 和 FP 并非非此即彼,而是可以根據項目需求、團隊習慣、技術棧等因素靈活選擇

  • 若項目需要建模復雜業務邏輯、狀態管理、類結構清晰,則更適合使用 OOP
  • 若項目更注重邏輯解耦、數據變換、可測試性與復用性,則更適合使用 FP
  • 若項目涉及大量異步事件、實時響應或復雜事件流處理,則可引入 FRP 或響應式編程框架

此外,現代前端框架(如 React、Vue)已經融合了多種范式的思想:

  • React 更偏向函數式編程,鼓勵使用函數組件和 hooks
  • Vue 3 支持 Composition API,也更適合函數式風格
  • Angular 仍以 OOP 為主,但也在逐步引入響應式編程理念

編程范式之間的關系與發展趨勢

編程范式核心思想關鍵特征適用場景
OOP(面向對象)抽象現實事物為對象封裝、繼承、多態復雜業務、狀態管理
FP(函數式編程)函數為基本單元,強調純函數不可變、無副作用、可組合數據處理、邏輯解耦
FRP(函數式響應式)響應事件流,函數式處理異步友好、流式處理實時響應、UI 變化
  • 未來的開發趨勢是多范式融合,開發者應具備靈活選擇與組合不同編程風格的能力
  • 理解 OOP、FP 和 FRP 的本質,有助于我們在不同的項目中做出更合適的技術選型

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91260.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91260.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91260.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

elememtor 添加分頁功能

各位看官好&#xff0c;最近在忙著使用elementor搭建自己的網站&#xff0c;由于我不是專業的程序員和前端&#xff0c;又沒有很多錢去找外包公司實現自己的設計&#xff0c;所以選擇了elementor. 總的來說這是一個不錯的wordpress 插件&#xff0c;也讓我們這種非專業的網站設…

關于“PromptPilot” 之2 -目標系統:Prompt構造器

目標系統&#xff1a;Prompt構造器想法首先&#xff0c;在抽象層對PromptPilot進行封裝給出提示詞形成過程的全部環節。然后&#xff0c;在 形成一套確定的提示詞后再為 小規模試點方案生成一整套開發工具并配套集成開發環境和指南。最后&#xff0c;在小規模試點成功后進行拓展…

短劇小程序系統開發:重塑影視內容消費格局

在數字化浪潮的推動下&#xff0c;影視內容消費正經歷著深刻的變革。短劇小程序系統開發作為這一變革的重要力量&#xff0c;正在重塑影視內容消費的格局&#xff0c;為用戶帶來更加個性化、便捷化的觀影體驗。傳統影視內容消費往往受到時間和空間的限制&#xff0c;用戶需要前…

一文掌握最新版本Monocle3單細胞軌跡(擬時序)分析

許多大佬的軟件想要構建一個大而美的生態&#xff0c;從 monocle2 開始就能做單細胞的質控、降維、分群、注釋這一系列的分析&#xff0c;但不幸的是我們只知道 monocle 系列還是主要做擬時序分析&#xff0c;一方面是因為 Seurat 有先發優勢&#xff0c;出名要趁早&#xff0c…

spark入門-helloword

我們學習編程語言的時候&#xff0c;第一個程序就是打印一下 “hello world” &#xff0c;對于大數據領域的第一個任務則是wordcount。那我們就開始我們的第一個spark任務吧&#xff01; 下載spark 官方下載地址&#xff1a;Apache Download Mirrors 下載完畢以后&#xff0c…

雷達系統設計學習:自制6GHz FMCW Radar

國外大神自制6GHZ FMCW Radar開源項目: https://github.com/Ttl/fmcw3 引言 之前我做過一個簡單的調頻連續波&#xff08;FMCW&#xff09;雷達&#xff0c;能夠探測到100米范圍內人體大小的物體。雖然它確實能用&#xff0c;但由于預算有限&#xff0c;還有很大的改進空間。 …

系統選擇菜單(ubuntu grub)介紹

好的&#xff0c;我們來詳細解釋一下什么是Ubuntu的GRUB菜單。 簡單來說&#xff0c;GRUB菜單是您電腦啟動時看到的第一個交互界面&#xff0c;它就像一個“系統選擇”菜單&#xff0c;讓您決定接下來要啟動哪個操作系統或進入哪種模式。詳細解釋 1. GRUB是什么&#xff1f; GR…

方案C,version2

實現一個簡單的Helloworld網頁,并通過GitHub Actions自動構建并推送到公開倉庫的gh-pages分支。同時,使用PAT進行認證,確保源碼在私有倉庫中,構建后的靜態文件在公開倉庫中。 重新設計deploy.yml內容如下(針對純靜態文件,無需構建過程): 步驟: 檢出私有倉庫源碼。 由于…

R 語言科研繪圖 --- 其他繪圖-匯總1

在發表科研論文的過程中&#xff0c;科研繪圖是必不可少的&#xff0c;一張好看的圖形會是文章很大的加分項。 為了便于使用&#xff0c;本系列文章介紹的所有繪圖都已收錄到了 sciRplot 項目中&#xff0c;獲取方式&#xff1a; R 語言科研繪圖模板 --- sciRplothttps://mp.…

webpack 原理及使用

【點贊收藏加關注,前端技術不迷路~】 一、webpack基礎 1.核心概念 1)entry:定義入口,webpack構建的第一步 module.exports ={entry:./src/xxx.js } 2)output:出口(輸出) 3)loader:模塊加載器,用戶將模塊的原內容按照需求加載成新內容 比如文本加載器raw-loade…

「日拱一碼」039 機器學習-訓練時間VS精確度

目錄 時間-精度權衡曲線&#xff08;不同模型復雜度&#xff09; 訓練與驗證損失對比 帕累托前沿分析&#xff08;3D&#xff09; 在機器學習實踐中&#xff0c;理解模型收斂所需時間及其與精度的關系至關重要。下面介紹如何分析模型收斂時間與精度之間的權衡&#xff0c;并…

面試刷題平臺項目總結

項目簡介&#xff1a; 面試刷題平臺是一款基于 Spring Boot Redis MySQL Elasticsearch 的 面試刷題平臺&#xff0c;運用 Druid HotKey Sa-Token Sentinel 提高了系統的性能和安全性。 第一階段&#xff0c;開發基礎的刷題平臺&#xff0c;帶大家熟悉項目開發流程&#xff…

負載均衡、算法/策略

負載均衡一、負載均衡層級對比特性四層負載均衡 (L4)七層負載均衡 (L7)工作層級傳輸層 (TCP/UDP)應用層 (HTTP/HTTPS等)決策依據源/目標IP端口URL路徑、Header、Cookie、內容等轉發方式IP地址/端口替換重建連接并深度解析報文性能更高吞吐量&#xff0c;更低延遲需內容解析&…

StackingClassifier參數詳解與示例

StackingClassifier參數詳解與示例 StackingClassifier是一種集成學習方法&#xff0c;通過組合多個基分類器的預測結果作為元分類器的輸入特征&#xff0c;從而提高整體模型性能。以下是關鍵參數的詳細說明和示例&#xff1a; 1. classifiers&#xff08;基分類器&#xff09;…

嵌入式中間件-uorb解析

uORB系統詳細解析 1. 系統概述 1.1 設計理念 uORB&#xff08;Micro Object Request Broker&#xff09;是一個專為嵌入式實時系統設計的發布-訂閱式進程間通信框架。該系統借鑒了ROS中topic的概念&#xff0c;為無人機飛控系統提供了高效、可靠的數據傳輸機制。 1.2 核心特征 …

HTTP.Client 庫對比與選擇

HTTP.Client 庫對比與選擇在 Python 中&#xff0c;除了標準庫 http.client&#xff0c;還有許多功能更強大、使用更便捷的 HTTP 庫。以下是一些常用的庫及其特點&#xff1a;1. Requests&#xff08;最流行&#xff09;特點&#xff1a;高層 API&#xff0c;簡單易用&#xff…

RabbitMQ面試精講 Day 5:Virtual Host與權限控制

【RabbitMQ面試精講 Day 5】Virtual Host與權限控制 開篇 歡迎來到"RabbitMQ面試精講"系列的第5天&#xff01;今天我們將深入探討RabbitMQ中Virtual Host與權限控制的核心機制&#xff0c;這是構建安全、隔離的消息系統必須掌握的重要知識。在面試中&#xff0c;面…

【前端實戰】純HTML+CSS+JS實現蠟筆小新無盡冒險:從零打造網頁版超級瑪麗

摘要&#xff1a;本文將詳細介紹一款完全由HTMLCSSJS實現的網頁版橫版闖關游戲——"蠟筆小新無盡冒險"。游戲采用純前端技術實現&#xff0c;無需任何外部依賴&#xff0c;完美復刻了經典超級瑪麗的核心玩法&#xff0c;并創新性地融入了蠟筆小新角色元素。通過本文&…

[工具類] 網絡請求HttpUtils

引言在現代應用程序開發中&#xff0c;網絡請求是必不可少的功能之一。無論是訪問第三方API、微服務之間的通信&#xff0c;還是請求遠程數據&#xff0c;都需要通過HTTP協議實現。在Java中&#xff0c;java.net.HttpURLConnection、Apache的HttpClient庫以及OkHttp等庫提供了豐…

基于Spring Boot的裝飾工程管理系統(源碼+論文)

一、 開發環境與技術 本章節對開發裝飾工程管理系統------項目立項子系統需要搭建的開發環境&#xff0c;以及裝飾工程管理系統------項目立項子系統開發中使用的編程技術等進行闡述。 1 開發環境 工具/環境描述操作系統Windows 10/11 或 Linux&#xff08;如 Ubuntu&#x…