当前位置: 首页 > news >正文

编程思想——FP、OOP、FRP、AOP、IOC、DI、MVC、DTO、DAO

个人简介

👀个人主页: 前端杂货铺
🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展
📃个人状态: 研发工程师,现效力于中国工业软件事业
🚀人生格言: 积跬步至千里,积小流成江海
🥇推荐学习:🍍前端面试宝典 🎨100个小功能 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js实战 🍒Three.js

🌕个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧

文章目录

    • FP、OOP、FRP
      • Functional Programming:函数式编程。
      • Object Oriented Programming:面向对象式编程
      • Functional Reative Programming: 函数式响应编程
      • 对比总结
      • 混合使用
    • AOP 面向切面编程
    • IOC 控制反转、DI 依赖注入
    • NestJS核心概念
    • MVC
    • DTO、DAO
    • 总结

FP、OOP、FRP

Functional Programming:函数式编程。

核心思想:

  • 函数是“一等公民”:函数可以作为参数传递、返回值或变量存储。
  • 纯函数:相同的输入必定得到相同的输出,且无副作用(不修改外部状态)。
  • 不可变性:数据不可修改,通过创建新数据实现变化。
  • 声明式风格:关注“做什么”,而非“如何做”。

数组操作:

// 纯函数示例:无副作用,输出只依赖输入
const add = (a, b) => a + b;

// 不可变性:生成新数组,而非修改原数组
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2); // [2, 4, 6]

// 函数组合:将多个函数串联
const process = (arr) => 
  arr.filter(n => n % 2 === 0)  // 过滤偶数
    .map(n => n * 3)            // 乘以3
    .reduce((sum, n) => sum + n, 0); // 求和

console.log(process([1, 2, 3, 4])); // (2*3 + 4*3) = 18

特点

  • 优点:易测试、可维护性强,适合并发场景。
  • 缺点:学习曲线高,需适应不可变性和函数组合思维。
  • 典型库:Lodash(FP模式)、Ramda。

Object Oriented Programming:面向对象式编程

核心思想

  • 对象为中心:程序由对象组成,对象包含数据(属性)和行为(方法)。
  • 封装:隐藏内部细节,暴露接口。
  • 继承:子类继承父类的属性和方法。
  • 多态:同一方法在不同对象中有不同实现。

动物类

// 基类(抽象类)
abstract class Animal {
  constructor(public name: string) {}

  // 抽象方法:子类必须实现
  abstract makeSound(): void;

  // 公共方法
  move(distance: number = 0) {
    console.log(`${this.name} moved ${distance} meters.`);
  }
}

// 子类继承
class Dog extends Animal {
  makeSound() {
    console.log("Woof! Woof!");
  }
}

class Cat extends Animal {
  makeSound() {
    console.log("Meow~");
  }
}

// 使用多态
const animals: Animal[] = [new Dog("Buddy"), new Cat("Misty")];
animals.forEach(animal => animal.makeSound());
// 输出:
// Woof! Woof!
// Meow~

特点

  • 优点:结构清晰,适合业务模型抽象。
  • 缺点:过度继承可能导致“脆弱基类问题”。
  • 典型应用:GUI开发、游戏实体建模。

Functional Reative Programming: 函数式响应编程

核心思想

  • 响应式数据流:将事件、状态变化抽象为流(Stream)。
  • 函数式操作:使用纯函数对数据流进行变换、过滤、组合。
  • 声明式处理异步:简化复杂异步逻辑(如事件监听、AJAX请求)。

点击计数(使用 RxJS)

import { fromEvent } from 'rxjs';
import { map, scan } from 'rxjs/operators';

// 创建点击事件流
const button = document.querySelector('button');
const click$ = fromEvent(button, 'click');

// 操作流:统计点击次数
const count$ = click$.pipe(
  map(() => 1), // 每次点击映射为1
  scan((total, curr) => total + curr, 0) // 累加
);

// 订阅结果
count$.subscribe(count => {
  console.log(`Clicked ${count} times`);
});

// 点击按钮时输出:
// Clicked 1 times
// Clicked 2 times
// ...

特点

  • 优点:简化异步和事件驱动逻辑,可组合性强。
  • 缺点:概念抽象,调试复杂。
  • 典型库:RxJS、Bacon.js。

对比总结

范式核心概念典型场景
函数式编程 (FP)纯函数、不可变性、函数组合数据处理、并发任务
面向对象编程 (OOP)对象、封装、继承、多态业务模型抽象、GUI开发
函数式响应编程 (FRP)数据流、声明式异步处理实时应用、复杂事件处理

混合使用

// OOP + FP:类中使用纯函数
class Calculator {
  // 静态纯函数方法
  static add(a: number, b: number): number {
    return a + b;
  }
}

// FRP + FP:响应式流中使用函数式操作
const stream$ = click$.pipe(
  filter(event => event.target.matches('.btn')),
  debounceTime(300),
  map(event => ({ x: event.clientX, y: event.clientY }))
);

AOP 面向切面编程

Aspect Oriented Programming:面向切面编程。

核心思想:将通用逻辑(如日志、权限、缓存)从业务代码中剥离通过切面在运行时动态注入到目标位置,保持代码的纯净性。

NestJS 通过以下工具实现 AOP:

  • 拦截器(Interceptors):在方法执行前后添加逻辑。
  • 守卫(Guards):处理权限验证。
  • 管道(Pipes):数据校验和转换。
  • 异常过滤器(Exception Filters):统一异常处理。

IOC 控制反转、DI 依赖注入

Inversion Of Control:控制反转。

核心思想:将对象的创建管理交给框架(容器),开发者只需声明依赖关系,由框架自动完成实例化和注入。

Dependency Injection:依赖注入。

核心思想:对象的依赖由外部注入,而非在内部直接创建,实现解耦。

关系:IOC是一种设计思想&设计模式,DI 是 IOC 的具体实现

IPhone 依赖、Android 依赖与 DIStudent 解耦,示例如下:

di.ts

export interface Phone {
  playGame(name: string): void;
}

export class DIStudent {
  constructor(private name: string, private phone: Phone) {
    this.phone = phone;
    this.name = name;
  }

  getName() {
    return this.name;
  }

  setName(name: string) {
    this.name = name;
  }

  play() {
    this.phone.playGame(this.name);
  }
}

index.ts

import { DIStudent, Phone } from "./di";

class IPhone implements Phone {
  playGame(name: string) {
    console.log(`${name} use iphone play name`);
  }
}

class Android implements Phone {
  playGame(name: string): void {
    console.log(`${name} use android play name`);
  }
}

const student1 = new DIStudent("zahuopu1", new Android());
student1.play(); // output: zahuopu1 use android play name

const stdent2 = new DIStudent("zahuopu2", new IPhone());
stdent2.play(); // output: ahuopu2 use iphone play name

NestJS核心概念

Controller 层负责处理请求、返回响应。

Service 层负责提供方法和操作,只包含业务逻辑。

Data Access 层负责访问数据库中的数据。

在这里插入图片描述

NestJS 生命周期:

在这里插入图片描述


MVC

Model View Controller:模型、视图、控制器;MVC 是一种分层的架构模式。

  • Model(模型):管理数据逻辑(如数据库操作、业务规则)。
  • View(视图):负责数据展示(如 UI 界面、网页模板)。
  • Controller(控制器):处理用户输入,协调 Model 和 View 的交互。

通过职责分离,提升代码的可维护性和扩展性。


DTO、DAO

Data Transfer Object:数据传输对象。在不同层(如 Controller → Service → DAO)间封装并传递数据。

Data Access Object:数据访问对象。它是一层逻辑,包含实体类、数据库操作(CRUD)、数据校验、错误处理等。

在这里插入图片描述


总结

本篇文章,我们学习了一些良好的编程思想,后续将在我们的项目中运用这些思想,编写更加易读且健壮的代码。

好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!


参考资料:

  1. DeepSeek
  2. NestJS 从入门到实战

在这里插入图片描述


相关文章:

  • HarmonyOS中的多线程并发机制
  • Docker引擎、Docker守护进程和Docker客户端
  • RocketMQ 中的 MessageStore 组件:消息存储的核心枢纽
  • 不同数据库的注入报错信息
  • ubuntu 2204 安装 vcs 2018
  • L1-5 吉老师的回归
  • Python赋能量子计算:算法创新与应用拓展
  • 浏览器发起调用到服务器的全过程解析
  • Mybatis的简单介绍
  • 记一次Agora-RTSALite编译遇到的问题
  • SuperPoint论文及源码解读
  • 使用Lombok无法生成Getter()与Setter()和toString()方法的解决方案
  • RocketMQ 中 DefaultMessageStore 的 AllocateMappedFileService 属性详解
  • 【Linux】Linux 权限:数字背后的神秘 “门禁卡” 系统
  • 剖析Spring中的设计模式(一) | 工厂观察者
  • 【零基础玩转多模态AI:Gemma3 27B开源视觉模型本地部署与远程访问】
  • 全星APQP软件:为用户提供高效、合规、便捷的研发管理体验
  • HDLBIT知识点
  • 探索 Vue 3 响应式系统:原理与实践
  • 蓝桥杯电子赛_E2PROM(AT24C02)
  • 印称一名高级官员在巴基斯坦发动的袭击中死亡
  • 视频丨习近平同普京在主观礼台出席红场阅兵式
  • 本周看啥|喜欢二次元的观众,去电影院吧
  • 中日有关部门就日本水产品输华问题进行第三次谈判,外交部回应
  • 陕西永寿4岁女童被蜜蜂蜇伤致死,当地镇政府介入处理
  • 迪拜金融市场CEO:2024年市场表现出色,超八成新投资者来自海外