编程思想——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)、数据校验、错误处理等。
总结
本篇文章,我们学习了一些良好的编程思想,后续将在我们的项目中运用这些思想,编写更加易读且健壮的代码。
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- DeepSeek
- NestJS 从入门到实战