热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

react获取设备高_Flutter高内聚组件怎么做?阿里闲鱼打造开源高效方案!

作者:闲鱼技术-海潴fish_redux是闲鱼技术团队打造的flutter应用开发框架,旨在解决页面内组件间的高内聚、低耦合问题。从react_redu
ebd800ca17092e62f03f2a78648b9e74.png

作者:闲鱼技术-海潴

fish_redux是闲鱼技术团队打造的flutter应用开发框架,旨在解决页面内组件间的高内聚、低耦合问题。

从react_redux说起

redux对于前端的同学来说是一个比较熟悉的框架了,fish_redux借鉴了redux单项数据流思 想。在flutter上说到redux,大家可能第一反应会类比到react上的react_redux。在react_redux中有个重要的概念——connect,

connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

简单得说,connect允许使用者从Redux store中获取数据并绑定到组件的props上,可以dispatch一个action去修改数据。

那么fish_redux中的connector是做什么的呢?为什么说connector解决了组件内聚的问题?我们应该如何理解它的设计呢?

connector in fish_redux

尽管都起到了连接的作用,但fish_reduxreact_redux在抽象层面有很大的不同。

fish_redux本身是一个flutter上的应用框架,建立了自己的component体系,用来解决组件内的高内聚和组件间的低耦合。从connector角度来说,如何解决内聚问题,是设计中的重要考量。

fish_redux自己制造了Component树,Component聚合了statedispatch,每一个子Componentstate通过connector从父Componentstate中筛选。如图所示:

1447eb7cd3b9b79c86a2badabb672acd.png

可以看到,fish_reduxconnector的主要作用把父子Component关联起来,最重要的操作是filterstate从上之下是一个严谨的树形结构,它的结构复用了Component的树形结构。类似一个漏斗形的数据管道,管理数据的分拆与组装。它表达了如何组装一个Component

而对于react_redux来说,它主要的作用在于把react框架和redux绑定起来,重点在于如何让React component具有Redux的功能。

c158ae67dd127688c912f4b7cb8e0c38.png

从图中可以看到,react_reduxReact是平行的结构,经过mapStateToProps后的state也不存在严谨的树形结构,即对于一个React component来说,它的state来自于Redux store而不是父component的state。从框架设计的角度来说,react_redux最重要的一个操作就是attach

源码分析

说完概念,我们从源码的角度来看看fish_redux中的connector是如何运作的,以fish_redux提供的example为例。

class ToDoListPage extends Page> { ToDoListPage() : super( ... dependencies: Dependencies( adapter: ToDoListAdapter(), slots: >{ 'report': ReportConnector() + ReportComponent() }), ... ); }

在ToDoListPage 的构造函数中,向父类构造传递了一个Dependencies对象,在构造Dependencies时,参数slots中包含了名叫"report"的item,注意这个item的生成,是由一个 ReportConnector+ReportComponent产生的。

从这里我们得出一个简单却非常重要的结论:

在fish_redux中,一个Dependent = connector + Component 。

Dependent代表页面拼装中的一个单元,它可以是一个Component(通过buildComponent函数产 生),也可以是一个Adapter(由buildAdapter函数产生)。这样设计的好处是,对于View拼装操作 来说,Dependent对外统一了API而不需要透出更多的细节。

根据上面我们得出的结论,connector用来把一个更小的Component单元链接到一个更大的 ComponentAdapter上。这与我们之前的描述相符合。

connector到底是什么

知道了connector的基本作用,我们来看一下它到底链接了哪些东西以及如何链接。

先来看一下ReportConnector 类的定义:

class ReportConnector extends ConnOp

ReportConnector继承了ConnOp类,所有connector的操作包括+操作,都来自于ConnOp类。

69346b673e026ee8a65bfa522f0df460.png

set/get

既然是数据管道,就会有获取放置

set函数的入参很好得表达了TP的意思,即把一个P类型的subState合并到T类型的 state中。

再回头看get函数,就很好理解了,get函数表达的就是如何从T类型的state中获取P类型 的subStateDependent使用。

operator +

+操作符的重载是我们最初看到connector作用的地方,也是connector发挥作用的入口。

LogicComponentAdapter的父类,它表示页面组装元素的逻辑层,里面包含了reducer/effect/higherEffect等与逻辑相关的元素以及它的组装过程。

operator+调用了createDependent函数,接着会调用到_Dependent类的构造函数,这里将 logicconnector放入_Dependent内部,在后面fish_reduxComponent组装的过程中,connector会随着外部对_Dependent中函数的调用发挥作用。

connector正式登场

铺垫了这么多,是该connector正式发挥作用的时候了。

get

我们以Component为例,会调用到_DependentbuildComponent函数:

Widget buildComponent(MixedStore store, Get getter) { final AbstractComponent

component = logic; return component.buildComponent(store, () => connector.get(getter())); }

这里的logic实际就是一个Component对象,在调用ComponentbuildComponent函数的 时候,使用get函数从一个大的父state中获取到当前Component需要的数据集。接下去,这个变换后的子state将被用在例如ViewBuilderRedcuer函数中。

这是connector在数据获取上的作用。

set

还是在_Dependent类里面,看createSubReducer函数:

SubReducer createSubReducer() { final Reducer

reducer = logic.reducer; return reducer != null ? connector.subReducer(reducer) : null; }

首现从一个Logic(这里实际上是一个Component)对象中获取到外部设置进来的reducer,接着 调用subReducer返回一个SubReducer对象。SubReducer是一个被wrap后的Reducer

subReducer的实现在MutableConn中,ConnOp继承了MutableConn类,也获得了这个能 力。

SubReducer subReducer(Reducer

reducer) { return (T state, Action action, bool isStateCopied) { final P props = get(state); if (props == null) { return state; } final P newProps = reducer(props, action); final bool hasChanged = newProps != props; final T copy = (hasChanged && !isStateCopied) ? _clone(state) : state; if (hasChanged) { set(copy, newProps); } return copy; }; }

它首现通过get函数得到一个变换后的数据集props,接着调用原始的reducer函数进行逻辑处 理,这里有一个优化也是SubReducer的作用,如果数据集在经过reducer处理之后发生了变化, 并且state已经被copy过一次了(isStateCopied==true),就直接把newProps通过set函数 更新到state中去。(这个优化可以防止多个子state发生变化的时候父state被拷贝多次)

至此,connector在数据更新上的作用也体现出来了。

ReportConnector

最后,就好理解ReportConnector的实现了:

class ReportConnector extends ConnOp { @override ReportState get(PageState state) { final ReportState reportState = ReportState(); reportState.total = state.toDos.length; reportState.done = state.toDos.where((ToDoState tds) => tds.isDone).toList().length; return reportState; } @override void set(PageState state, ReportState subState) {} }

很明显的,在get函数中,ReportStatePageState中获得了total/done字段。

总结

闲鱼客户端的详情页完全使用了fish_redux进行了重构,通过高内聚的Component+connector形式,使得Component可以被大量复用,很好得支持了5中类型的详情页。未来我们会基于*fish_redux*强大的扩展能力制作更多组件来满足不同业务对于框架的需求。



推荐阅读
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • React项目中运用React技巧解决实际问题的总结
    本文总结了在React项目中如何运用React技巧解决一些实际问题,包括取消请求和页面卸载的关联,利用useEffect和AbortController等技术实现请求的取消。文章中的代码是简化后的例子,但思想是相通的。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • #define_CRT_SECURE_NO_WARNINGS#includelist.h#includevoidSListInit(PNode*pHead ... [详细]
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了在Python张量流中使用make_merged_spec()方法合并设备规格对象的方法和语法,以及参数和返回值的说明,并提供了一个示例代码。 ... [详细]
author-avatar
广东暖暖_小乖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有