概述

  • 在软件开发过程中,不同的编程范式为我们提供了多样化的思维方式与实现路径
  • 它们不仅影响着代码的结构和逻辑组织方式,
  • 也深刻影响着项目的可维护性、可扩展性以及团队协作效率

什么是 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…