前言

今日早读文章由铃盛@Michael Lin投稿分享。

@Michael Lin,RingCentral前端高级工程师,前端架构经验丰富,擅长通用化领域,热爱开源。
GitHub:https://github.com/unadlib
NPM: https://www.npmjs.com/~unadlib

正文从这开始~~

如果你对Redux/Mobx/Vuex等如何更好的OOP设计感兴趣,那么本文将给出一个前端状态库OOP完整的通用化方案。

动机

由于前端单页应用开发日趋复杂,当我们在使用React/Vue时,为了开发复杂的App让我们不得不用到一些状态管理或者状态容器(下文统称为状态库),同时我们也急需一个更容易模块化的模型设计。而前端状态库又百花齐放,无论是Redux/MobX/Vuex以及Angular自带的状态管理,状态库的模块化也一直是最近几年复杂系统中的前端开发领域的新需求。当然Angular来说这个需求早就被Angular框架本身实现了,但对于其他的库这是一个至关重要的问题,因此本文试着探索一套通用于主流状态库的OOP模块化设计。

通用化状态模块

通常情况下,前端中大型项目的架构设计中常见于采用面向对象编程(OOP),而采取哪种前端状态库等问题又经常变成可争论热点:

  • 到底是Redux还是MobX更适合用于React?

  • Redux适合应用于OOP吗?

  • MobX的observable在React带来利弊如何权衡?

  • 在Vue中Vuex如何OOP?

此外,大部分情况下的通用化JavaScript更多针对于JavaScript的运行环境,一旦某种架构设计选定了某个状态库,那么将意味着该架构难以脱离此状态库的使用,任何系统基于此架构都将基于这样的状态库。但更好的前端架构会包含更灵活的可选性与可扩展性,尤其有类似典型的集成业务之类通用化需求的前端部分,其中可体现于View Render库有可选余地,甚至状态库有可选余地,例如在主流方案中React+Redux/React+MobX/Vue+Vuex/Angular等有选择余地,那么它带来的问题便是通用化状态库。

我们需要因此解决这几个问题:

  • 基于Redux/MobX/Vuex 等状态库的OOP的设计,这也是最重要的,尤其对Vue和React而言。

  • 被封装的OOP设计是否足够简单易用,同时它们具有相当灵活性。

  • 从DDD角度说,在复杂的domain modules间的依赖关系需要IoC,它们之间的启动逻辑有依赖关系,那么必然有类似事件机制或者module生命周期的引入。

为解决以上几个问题,通用化OOP封装和模块标准化生命周期或者事件机制变得不可或缺。

提出解决方案

基于这样通用化的概念,我们提出新的通用化状态模块的lib —— usm。

首先,它应该能解决是基于Redux/MobX/Vuex等状态库的OOP设计。

这是典型的Redux Counte例子:

function counter(state = 0, action) {switch (action.type) {case 'INCREMENT':return state + 1;case 'DECREMENT':return state - 1;default:return state;}}const store = createStore(counter)store.subscribe(() => console.log(store.getState()))store.dispatch({ type: 'INCREMENT' })store.dispatch({ type: 'DECREMENT' })

而这是基于usm的Counter例子:

import Module, { state, action } from 'usm';class Counter extends Module {@state count = 0;@action  increase(state) {    state.count += 1;}@action  decrease(state) {    state.count -= 1;}}

首先我必须承认Redux在immutable类型的状态库中绝对是最好的库之一,在这里我无意要讨论一些Redux的缺点,我们想探讨的是如何利用Redux进行更好的OOP设计。我们希望基于Redux的模型可以更加直观和简洁,就像上面提到的基于ES6+的class的Counter的OO例子一样,如果这样的OO范式它同时还是通用化的状态模型,一个更好的统一状态库封装, 这无疑可以给开发者带来会有一种更灵活和更友好的编程体验(当然也包括易于阅读/维护等)。usm正好解决了这些问题,并且目前usm支持Redux/MobX/Vuex/Angular。

USM特性

  • 通用化状态模块

  • 标准化模块生命周期

  • 可选事件系统

  • 支持无状态最小化模型

  • 支持Redux/MobX/Vuex/Angular

USM装饰器

usm提供@state用于包装一个带状态的变量,@action用于包装一个改变状态的函数(函数传入的最后一个参数均为当前state对象),除此以外和一个普通的class封装的OO模块没有区别。

USM模块生命周期

如果有必要,usm提供五个支持异步的生命周期函数:

  • moduleWillInitialize

  • moduleWillInitializeSuccess

  • moduleDidInitialize

  • moduleWillReset

  • moduleDidReset

它们的运行顺序如下图所示:

需要特别说明的,usm之所以提供生命周期是因为在大部分复杂的领域模块场景下,模块间的启动依赖常常是必须的,但是在不必使用它们的时候,它们的设置当然都是可以省缺的。

理想中的架构设计

在复杂前端模块系统中, 这也许是一个比较典型的模块化架构设计,它包含以下几个部分:

  • 生命周期

  • Store订阅器

  • 事件系统

  • State

  • 依赖模块

  • 领域模型

当然在这里只是提出这样的设想,或许某些架构运用场景下可能是这样设计模型的扩充或删减。

Todo简单例子

// if necessary, you can use `usm-redux`/`usm-mobx`/`usm-vuex` with states.import Module, { state, action } from 'usm'; class Todos extends Module {@state list = [];@action  addTodo(text, state){    state.list.push({text});}@action  toggle(id, state){const todo = state.list.find(item => item.id === id);    todo.completed = !todo.completed;}}

结论

当你使用React+Redux/React+MobX/Vue+Vuex等库或者框架组合进行开发时,希望usm是在你的应用系统模块化不错的选择,它可能是你在使用React/Vue等UI构建库时缺少的那块重要的模块化拼图。

换句话说,如果你使用usm进行OOP架构设计,那么你的系统不仅可以减少不同状态库的boilerplate,尤其像Redux这样boilerplate较多的库而样应该有很大的帮助。最重要的是,usm可以让你需要的OOP架构的模块化变得简洁而直观,甚至usm可以让你的业务代码兼容各种状态库,无论是Redux/MobX/Vuex还是Angular,而且如果你用的UI组件库正好也兼容React/Vue/Angular,那么你的应用将快速无缝使用React/Vue/Angular。

最后,我们可以提出一个值得思考的问题:

从OOP角度来说,前端状态库的选择真的很重要吗?

最后,为你推荐

【第1581期】 2019 React Redux 完全指南

【第1579期】十个案例学会 React Hooks

redux异步action_【第1586期】基于Redux/Vuex/MobX等库的通用化状态OOP相关推荐

  1. 精益 React 学习指南 (Lean React)- 3.4 掌控 redux 异步

    书籍完整目录 3.4 redux 异步 在大多数的前端业务场景中,需要和后端产生异步交互,在本节中,将详细讲解 redux 中的异步方案以及一些异步第三方组件,内容有: redux 异步流 redux ...

  2. Redux异步中间件

    曾经前端的革新是以Ajax的出现为分水岭,现代应用中绝大部分页面渲染会以异步流的方式进行.在Redux中,如果要发起异步请求,最合适的位置是在action creator中实现.但我们之前了解到的ac ...

  3. 优雅的redux异步中间件 redux-effect

    不吹不黑,redux蛮好用.只是有时略显繁琐,叫我定义每一个action.action type.使用时还要在组件上绑定一遍,臣妾做不到呀!下面分享一种个人比较倾向的极简写法,仍有待完善,望讨论. g ...

  4. redux异步action_Redux数据状态管理

    Redux 中文文档(https://www.redux.org.cn/) Redux入门教程(快速上手)(https://segmentfault.com/a/1190000011474522?fr ...

  5. redux异步action_React躬行记(12)——Redux中间件

    Redux的中间件(Middleware)遵循了即插即用的设计思想,出现在Action到达Reducer之前(如图10所示)的位置.中间件是一个固定模式的独立函数,当把多个中间件像管道那样串联在一起时 ...

  6. Redux 异步数据流-- thunk中间件源码解析

    Thunk 引入背景 这是一个关于Redux异步数据流的故事.引入thunk中间件的完整故事在Redux官方中文文档异步数据流.一句话总结就是:原生Redux只支持同步数据流,所以需要引入中间件(mi ...

  7. 基于Redux的ReactNative项目开发总结(一)

    写在前面 上周把基于Redux的单页应用开发完 紧接着就开始了ReactNative的开发.真的快得不可思议,只花了一周时间,我们两个人就分工把APP也开发完了,并且同时兼容IOS操作系统和Andro ...

  8. Redux异步解决方案之Redux-Thunk原理及源码解析

    前段时间,我们写了一篇Redux源码分析的文章,也分析了跟React连接的库React-Redux的源码实现.但是在Redux的生态中还有一个很重要的部分没有涉及到,那就是Redux的异步解决方案.本 ...

  9. redux rxjs_可观察的RxJS和Redux入门指南

    redux rxjs Redux-Observable is an RxJS-based middleware for Redux that allows developers to work wit ...

最新文章

  1. 已知2个整形数据a,b.不使用if,?:以及其他任何条件判断的语法,找出a跟b中数据的大者。
  2. 源码分析 @angular/cdk 之 Portal
  3. numpy 深复制 切片创建视图
  4. java resources目录 编码_关于Java项目读取resources资源文件路径
  5. 自己身份信息泄漏了怎么办,别怕,带你了解身份管理与访问控制
  6. cuda-gpu计算随笔(1)
  7. Visual Studio 2015专业版创建Win32控制台应用程序,C,C++源文件
  8. 每秒上百万次的跨数据中心写操作,Uber是如何使用Cassandra处理的?
  9. 获取系统分辨率_100 GHz传送带高速成像系统
  10. cstring判断包含字符串_Power Query中判断字符串中是否包含有字母的三种解决办法...
  11. 超详细图文保姆级教程:App开发新手入门(一)
  12. Es,N0,EsN0,EbN0,SNR关系详解
  13. VB编程:UBound获取数组上限;LBound获取数组下限-25_彭世瑜_新浪博客
  14. 知名互联网公司都在使用哪些数据库
  15. Android屏幕图片资源大小
  16. Windows 11操作系统 ndis.sys 驱动无限蓝屏问题修复
  17. Logstash报错:[ERROR][logstash.agent ] Failed to execute action {...
  18. Excel一键创建班级成绩表模板的操作
  19. 【建站笔记】apache配置赛门铁克免费ssl证书搭建https
  20. Manjaro 安装后的设置

热门文章

  1. 后端怎么接收map_史上最全,C++后端开发面试题与知识点汇总
  2. android文本与布局
  3. Git GUI基本操作
  4. java对PPG的基线漂移的一种处理办法(中值滤波)
  5. mac设置python3环境变量_mac下python3的环境变量设置!
  6. java excel自动保存_比POI好用的EasyExcel简单使用记录
  7. 深入了解Blazor组件
  8. 使用Angular和ASP.net Core的Raw Websockets迷你游戏
  9. 微软公布 Visual Studio 2020 上半年路线图
  10. java跨库调用存储_java-调用spring数据其余存储库方法不会返回...