Skip to main content

从 Angular 和 React 看编程范式演进:OOP 与 FP 的深度对比

一、直观体验:两种框架的组件交互方式

Angular(OOP 风格)

<!-- 父组件模板 -->
<app-layout [selected]="'Expedientes'" #appLayout>
<div class="form-field" *ngIf="appLayout.isEntity()">
<!-- 条件渲染内容 -->
</div>
</app-layout>

特点分析:

  • 使用 [selected] 属性向下传递数据
  • 通过 #appLayout 模板变量直接获取子组件实例
  • 直接调用子组件的公共方法 isEntity()

React(FP 风格)

// 子组件 - Layout.js
const Layout = forwardRef(({ selected }, ref) => {
const [user, setUser] = useState(null);

// 显式暴露方法给父组件
useImperativeHandle(ref, () => ({
isEntity: () => user && 'cif' in user
}));

return <div>{/* 组件内容 */}</div>;
});

// 父组件
const Parent = () => {
const layoutRef = useRef();

return (
<Layout selected="Expedientes" ref={layoutRef}>
{layoutRef.current?.isEntity() && (
<div className="form-field">{/* 条件内容 */}</div>
)}
</Layout>
);
};

特点分析:

  • 通过 selected prop 向下传递数据
  • 使用 useRef + forwardRef 获取子组件引用
  • 必须显式声明暴露的方法(useImperativeHandle

二、核心差异对比

特性Angular (OOP)React (FP)
组件本质类实例函数闭包
API 暴露自动公开公共成员需显式声明暴露内容
状态管理类属性 + 变更检测useState + 不可变更新
代码复用继承 + 服务自定义 Hook + 组合

三、设计哲学深度解析

1. Angular 的面向对象思维

// 典型的 Angular 组件类
@Component({
selector: 'app-user',
template: `...`
})
export class UserComponent {
@Input() user: User; // 输入属性
@Output() selected = new EventEmitter(); // 输出事件

public isEntity(): boolean { // 公共方法
return this.user && 'cif' in this.user;
}
}

OOP 特点:

  • 组件即类实例,天然拥有公共 API
  • 通过装饰器声明元数据(@Component、@Input 等)
  • 依赖注入系统管理组件依赖

2. React 的函数式思维

// 典型的 React 函数组件
const UserComponent = ({ user, onSelect }) => {
// 状态管理通过 Hook
const [isActive, setIsActive] = useState(false);

// 副作用通过 Hook 处理
useEffect(() => {
// 副作用逻辑
}, [user]);

// 渲染函数返回 UI
return (
<div onClick={() => onSelect(user)}>
{user.name}
</div>
);
};

FP 特点:

  • UI = f(state):UI 是状态的函数
  • 不可变数据流:状态更新创建新对象而非修改原对象
  • 组件组合优于继承

四、历史背景与演进趋势

为什么先有 Angular(OOP 风格)?

  • 2000-2010 年代 Java/C# 背景开发者占主流
  • OOP 是当时最熟悉的范式
  • 类组件 + 依赖注入降低了后端开发者的学习门槛

React 为何后来居上?

// React 的简洁性示例
const App = () => {
const [count, setCount] = useState(0);

return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
};

React 成功因素:

  • 更简单的心理模型:UI 是状态的函数
  • 更好的性能:虚拟 DOM 和精细的更新控制
  • 更灵活的架构:函数组合优于类继承

现代框架的融合趋势

// Vue 3 组合式 API(受 React Hook 启发)
import { ref, computed } from 'vue';

export default {
setup() {
const count = ref(0);
const double = computed(() => count.value * 2);

return { count, double };
}
}

演进趋势:

  • Angular 增加函数式特性
  • Vue 3 引入组合式 API
  • 所有框架都向更简单的函数式模型靠拢

五、实战场景对比

复杂状态管理

Angular(服务 + 类)

@Injectable({ providedIn: 'root' })
export class UserService {
private users = new BehaviorSubject<User[]>([]);

getUsers() { /* API 调用 */ }

addUser(user: User) {
// 可变更新(Angular 变更检测可处理)
const current = this.users.value;
current.push(user);
this.users.next(current);
}
}

React(Hook + 不可变更新)

const useUsers = () => {
const [users, setUsers] = useState([]);

const addUser = (newUser) => {
// 不可变更新
setUsers(prevUsers => [...prevUsers, newUser]);
};

return { users, addUser };
};

六、总结:选择哪种范式?

OOP(Angular)优势:

  • 结构清晰,适合大型团队
  • 强大的类型系统和工具支持
  • 完整的解决方案(路由、状态管理等)

FP(React)优势:

  • 更简单的心理模型
  • 更灵活的代码组织方式
  • 更好的性能优化可能性

最终建议:

  • 大型企业级应用:Angular 的 OOP 结构提供更好的可维护性
  • 快速迭代的产品:React 的 FP 模式提供更好的开发体验
  • 个人学习:理解两种范式,根据场景选择合适工具

框架只是工具,真正的价值在于理解背后的编程思想和设计原则。无论 OOP 还是 FP,最终目标都是构建可维护、可扩展的应用程序。