干货 | Trip.com 机票React Native整洁架构2.0实践

携程飞机票部分 vue/cli+element-plus 逻辑部分 @click="handleAddPassenger"添加乘客 在setup里定义handleAddPassenger方法,向vuex里commit数据 在mutations里定义addPassengerconst addPassenger = state => { state.passengers.push(乘客的属性,可以设默认初始值)} 删除乘客 delPassenger(state, p) { const index = state.passengers.indexOf(p) 阅读详情

作者简介

 

本文作者为携程国际部门机票App团队的佳璐、熠暘、文焕。

一、前言

2019年上半年携程机票前台团队基于clean architecture思想,结合具体业务特点和复杂度,对App机票查询列表页进行了一次技术重构。重构后的机票列表页视图与逻辑分离,多个业务模块分治业务场景,降低整体业务复杂度,提升了页面的可维护性,可测试性。

在近一年的业务迭代过程中开发团队发现了新的问题,并在原有1.0版本架构上做进一步优化。


二、架构优化

软件架构是软件的基本结构,针对业务场景实现合适的软件架构是软件可维护、可拓展的重要因素之一。

随着业务发展,大量业务逻辑迁移至前端实现以减少请求服务的次数,带给用户更平滑、顺畅的使用体验,前端的业务复杂度大大提高。现阶段前端的主要业务场景可抽象为:

1)请求服务。

2)根据业务逻辑将服务数据转化为业务状态。

3)根据展示逻辑将业务状态转化为展示状态,并渲染至界面。

4)响应用户交互,根据展示逻辑更新展示状态,根据业务逻辑更新业务状态。

前端页面的复杂度在于业务逻辑、展示逻辑繁多复杂,且业务逻辑间、展示逻辑间存在大量联动关系。如下图,大量复杂的业务逻辑、展示逻辑互相关联,导致整个页面的复杂度指数级上升。

 

2.1 原有问题

原架构借鉴clean architecture思想,将页面拆分为多个同构的业务模块,业务模块间可以嵌套组合。单个业务模块使用MVP模式进行管理:

  • View  -  React代码,只负责界面展示、样式和响应用户交互。

  • Presenter  -  连接View和Model,连接外部模块,不存在业务逻辑。

  • Model  -  业务实体,封装了业务逻辑和展示逻辑供Presenter调用。

其架构如图:

对比原架构设计与实际业务场景,可以发现其设计存在不合理之处:

  • 业务逻辑实现在业务模块内,与展示逻辑强耦合。当界面不展示业务模块时,对应的业务逻辑也无法执行,容易出现程序bug。

  • 业务逻辑与展示逻辑难以复用。

    • 页面内多个业务模块实现同一业务逻辑时,只能通过拷贝相关代码解决。

    • 跨页面复用模块时,由于不同页面间的业务逻辑存在差异,导致无法直接复用。

  • 模块间数据通信方式复杂,由于业务逻辑实现在不同业务模块内且业务模块在页面中呈树状结构,页面逻辑复杂时数据通信容易出现下图中的状态。


 

2.2 解决方案

新架构针对上述问题进行优化,核心改动点为:

  • 优化数据通信方式,模块只与Service通信,实现单向数据流。

  • 新增业务Service概念,承载页面业务逻辑,业务模块调整为只承载展示逻辑。

最新架构如图:

单向数据流

新架构下业务模块间无法通信,只可与业务Service通信,并且业务模块只是业务Service方法的调用方,业务逻辑的计算在业务Service实现,最终实现了单向数据流。

对于业务模块触发业务数据更新(例如用户交互),其流程如下:

对于业务数据更新触发业务模块刷新(例如请求返回), 其流程如下:

对于业务模块触发业务数据更新,同时联动引起其他业务模块刷新,其流程如下:

整体数据流如下:

业务Service

新架构中,页面拆分为多个同构业务模块和多个业务Service,业务模块根据界面展示内容进行划分,仍使用MVP模式进行管理,业务Service根据业务领域进行划分,使用面向对象方式进行管理。

业务模块中View职责不变,Presenter不再与其他模块直接连接、新增与业务Service的连接,Model不再负责业务逻辑,专注于展示逻辑。

业务Service则专注于特定业务领域的业务逻辑,为上层业务模块和其他业务Service提供支持。

拆分后的业务模块与业务Service,更符合单一职责原则(SRP原则),两者的可复用性也大大提升。跨页面复用业务模块时,只要其展示逻辑、交互逻辑相同即可直接复用。页面内涉及相同业务逻辑的业务模块,调用业务Service方法即可完成功能。

业务Service还能提取成为公用类库,不同平台(例如h5、online、app)存在相似业务场景时,即使上层的界面展示、交互方式不同,采用的UI框架不同也能进行复用,降低跨平台开发的成本。

三、插件功能优化

前端页面中除了业务功能外,还需实现大量非业务性功能,例如用户行为埋点、线上监控等。

 

3.1 原有问题

原架构中这类非业务性功能通常散落在代码各处,自身缺乏收口方式,对正常业务代码侵入性强,严重影响代码的可读性、可维护性。

以最常见的埋点功能为例,假设现在需对页面内具有联动关系的展示数据进行监控,当数据间展示不同步时上送报错埋点。在原架构下我们的实现方式为:

// ModuleA/Presenter/index.ts
export class ModuleAPresenter {
    private monitor: Monitor;
    constructor(monitor: Monitor) {
        this.monitor = monitor;
    }


    public updateView() {
        // 收集模块A的最新状态。
        this.monitor.updateState(this.model.getViewModel(), 'ModuleA');
        this.view.updateView(this.model.getViewModel());
    }
}
// Monitor/index.ts
export class Monitor {
    private stateMap = new Map();
    public updateState(state, moduleName) {
        this.stateMap.set(moduleName, state);
        // 检查模块A、模块B的状态是否同步。
        this.checkState();
    }
}

上述代码有几个明显的问题:

1)埋点代码直接侵入业务代码,两者互相强耦合,后续对埋点逻辑的改动很可能破坏业务代码,反之亦然。

2)业务模块需持有埋点类的实例,增加了对Monitor类的依赖,降低了自身的可复用性、可测试性。

3)对埋点逻辑的修改需要改动多个位置的代码,产生了”散弹枪式修改“的坏味道。


 

3.2 解决方案

基于面向切面编程的思想,在架构设计时预留”切面“并提供插件功能。用户可将非业务性功能封装在插件内维护与业务代码完全隔离,插件可通过切面获取如程序生命周期、特定用户行为等必要信息,无需入侵业务模块代码。同时业务模块也可访问插件实例,利用插件收集的数据完成特定功能。

面向切面编程(Aspectoriented programming)旨在将业务主体与非业务性功能分离,以提高程序的模块化程度。它将代码逻辑切分为不同的业务功能集,每个功能集包含了多个功能点,部分功能点会在多个功能集中都有出现,它们被称为”切面“。非业务性功能利用切面进行封装、维护,使原本分散在整个页面中的逻辑变得可管理、可维护。

上述例子使用插件改写后如下:

// ModuleA/Presenter/index.ts
export class ModuleAPresenter {
    public updateView() {
        // 业务模块中不再有无关逻辑
        this.view.updateView(this.model.getViewModel());
    }
}
// Monitor/index.ts
export class MonitorPlugin implements IGrtPlugin {
    private stateMap = new Map();


    // ”切面“方法
    public onUpdateState(state, moduleName) {
        this.stateMap.set(moduleName, state);
        // 检查模块A、模块B的状态是否同步。
        this.checkState();
    }
}

改动后的代码业务功能与非业务性功能完全解耦,且埋点功能的相关逻辑完全收口在Monitor类内,代码的可读性、可维护性有效提升。


四、小结

新架构针对业务功能,优化了现有代码结构,使其能够更好地应对愈发复杂的业务场景,实现业务功能,同时保证实现代码的可维护性。

针对非业务性功能,提出插件功能,利用面向切面编程思想,使非业务性功能收口在插件类内,不入侵业务模块代码。

【推荐阅读】

“携程技术”公众号后台回复“新书”,

可免费获得两本书的试读样章~

《携程架构实践》

京东

当当

《携程人工智能实践》

京东

当当

 “携程技术”公众号

  分享,交流,成长

干货 | 携程机票 React Native 整洁架构实践 作者简介任跃华, 携程机票前台软件工程师,从事机票android、react和react native技术栈相关研发工作。前言携程机票前台团队在使用 React Nati... 阅读详情

相关推荐

瞎谈干净架构(clean architecture)

关于干净架构(Clean Architecture)的一次尝试和总结

yangTal09的博客 1万+

React Native Clean Architecture:构建清晰架构的React Native脚手架

React Native Clean Architecture:构建清晰架构的React Native脚手架 项目核心功能/场景 React Native Clean Architecture 是一个易于理解的React Native脚手架,采用了清晰架构模式。 项目介绍 在移动应用开发领域,React Native凭借其跨平台的优势,成为了许多开发者的首选技术。然而,随着项目规模的扩大,如何保持...

gitblog_00089的博客 1068

react-CRN是CtripReactNative简称由携程无线平台研发团队基于ReactNative框架优化

CRN是Ctrip React Native简称,由携程无线平台研发团队基于React Native框架优化,定制成稳定性和性能更佳、也更适合业务场景的跨平台开发框架。

探索React Clean Architecture:构建可维护与扩展的前端应用

探索React Clean Architecture:构建可维护与扩展的前端应用 在软件开发中,架构设计扮演着至关重要的角色。良好的架构可以帮助我们打造出易于理解、测试和维护的代码库。这就是为什么我们向您推荐React Clean Architecture(RC.A),一个基于React的实用型开源项目,它将Clean Architecture原则引入到React世界。 项目介绍 React Cl...

gitblog_00025的博客 436

携程是如何去做React-Native优化的

携程是如何去做React-Native优化的,如何理解以及应用

SAP采购订单中项目类别B(限制)的控制逻辑

在笔者所在企业中,框架类采购订单中项目类别需要选择B(限制)。今天笔者从比较全面的角度分析了一下这个项目类别B到底可以决定些什么?控制到什么?先从后台SPRO中打开相应的配置菜单。 打开项目类别B之后,可以看到一些配置信息,这里有一点与其它配置不同的地方,即无法新增项目,也无法修改现有项目。这个疑惑今后再去解决吧。当前只研究项目类别B的控制逻辑。 下面就参考上图中的配置分段来分析和测试其控制逻辑, 1、如项目类别配置图,所需材料值为不允许;经测试,如下图在采购订单创建时,不能输入物料编号条目。

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 6032

React Native Bottom Sheet状态管理终极指南:MVVM与Clean Architecture实战解析

React Native Bottom Sheet是一个高性能、可交互的底部弹窗组件,提供了丰富的配置选项和灵活的状态管理能力。本文将通过MVVM架构与Clean Architecture设计模式,结合实际代码示例,帮助开发者掌握Bottom Sheet的状态管理最佳实践,打造响应式且易于维护的移动应用界面。 ## 为什么状态管理对Bottom Sheet至关重要? 底部弹窗(Bottom S

gitblog_00960的博客 754

Cisco三层交换机的详细配置

** 本文适用于新手小白以及微微基础的同学来用于参考,实验是在Cisco Packet Tracer Student 进行,实验最终效果如图所示,所有命令配置与图中的一致。 使用到的机器型号为:五台电脑,一台服务器,三个普通交换机(2960型号),一个三层交换机(3560-24PS),两台普通服务器(2811) 文章目录一、什么是三层交换机二、配置交换机步骤1.配置二层交换机2.配置三层交换机3.配置两台路由器以及最后一台电脑 一、什么是三层交换机 1.三层交换机 = 三层路由+二层交换机 2.工作在

真正的大师,永远都怀着一颗学徒的心。 4万+

携程 React Native 实践与性能优化

本文为携程技术中心投稿,版权归原作者所有,非经允许,请勿转载。 作者简介: 赵辛贵,携程无线开发高级技术经理,目前主要负责 React Native 框架在携程内部的使用推广和性能优化。 欢迎技术投稿、约稿、给文章纠错,请发送邮件至:mobile@csdn.net。 React Native(下文简称 RN)开源已经一年多时间,国内各大互联网公司都在使用,携程也在今年 5 月份投...

历史上的今天 3126

视频预处理--经典方法卷积3D

在三维卷积操作中,卷积核不仅在空间维度上滑动,还在时间维度上滑动,从而同时捕捉时间和空间上的特征。通过合理设置步长和填充,可以灵活控制输出特征图的大小和特征提取的效果。你的理解非常准确:三维卷积核就像是一个长度为 3 的滑动窗口,每次选取 3 个连续的帧进行卷积操作,而步长和填充则进一步优化了这一过程。

m0_73359068的博客 1649

手把手教你用键盘在Ubuntu上给Lerobot机械臂采集HIL-SERL训练数据(附完整配置文件)

本文详细介绍了在Ubuntu系统中使用键盘控制Lerobot机械臂进行HIL-SERL训练数据采集的完整流程。从环境准备、机械臂校准到键盘遥操系统配置和数据采集优化,提供了实战指南和常见问题解决方案,帮助读者高效获取高质量训练数据,推动具身智能和强化学习应用的发展。

weixin_30733003的博客 479

携程是如何做React Native优化的

React Native(下文简称RN)开源已经一年多时间,国内各大互联网公司都在使用,携程也在今年5月份投入资源开始引入,并推广给多个业务团队使用,本文将会分享我们遇到的一些问题以及我们的优化方案。 一、背景和使用情况介绍为什么会引入React Native? 1. AppSize占用 携程旅行App从11年开始开发,至今已有5年多时间,随着各项业务功能的全面移动化,以及公司mobile ...

Cool的博客 545

从数据校准到论文呈现:fsQCA与NCA方法融合的完整实证研究指南

本文详细介绍了fsQCA(模糊集定性比较分析)与NCA(必要条件分析)方法融合的完整实证研究流程,从数据校准到论文呈现。通过软件操作技巧、R语言NCA包高效使用及论文写作规范,帮助研究者避免常见误区,提升研究质量与可靠性。特别适合需要进行组态分析的研究生和学者参考。

weixin_29215391的博客 414

React JS Clean Architecture:实现整洁架构的开源项目

React JS Clean Architecture:实现整洁架构的开源项目 React JS Clean Architecture 是一个开源项目,旨在帮助开发者以整洁架构(Clean Architecture)的模式轻松实现 React JS 应用程序。该项目使用 TypeScript 作为主要的编程语言,确保了代码的健壮性和可维护性。 项目基础介绍 本项目基于 Uncle Bob 的整洁架...

gitblog_00993的博客 530

ThingsBoard PE专业版解决方案技术文档——温度&湿度

温湿度解决方案

weixin_67440240的博客 818

AI故障预测系统架构设计:5个核心模块+3种主流架构,收藏这篇就够了

深夜11点,某汽车工厂的生产线突然停机——核心机器人的轴承磨损过度导致卡壳。维修人员连夜抢修,直接损失超过50万元,还延误了客户的交货期。传统的“事后维修”或“定期维护”要么代价高昂,要么防不胜防。AI故障预测系统的出现,让“精准维护”成为可能——它能通过传感器数据提前7-30天预警故障,将停机损失降低80%以上。知道要做故障预测,却不知道怎么搭系统——数据怎么采集?特征怎么提取?模型怎么部署?架构怎么选?本文将解决这些问题:我们会拆解AI故障预测系统的5个核心模块,分析3种主流架构。

AIGC应用创新大全的博客 1019

从 Clean-Architecture 谈架构原理及其应

前些日子和团队的小伙伴们分享了自己对架构的理解,当时准备的比较仓促,讲的也比较粗糙,很多点并没有表达清楚;欣慰的是大家的反馈都比较积极,证明分享的内容是有参考价值的。这篇...

Docker的专栏 775

华为OD机试真题 新系统 - WIFI设备网络规划 (Java/Py/C/C++/Js/Go)

本文整理华为 OD 机试新系统机考真题库,涵盖高频考点精析与完整题目内容,提供 C 语言、Java、C++、Python、Go、JavaScript 多语言源码实现,搭配详细解题思路讲解,并支持在线 OJ 刷题练习,助力高效备考华为 OD 机试新系统。

算法大师! 2017

携程技术中心React Native Meetup活动经验分享

感谢携程的本次活动分享,携程用RN的30版本自己封装了一套CRN,重新了很多基础组件、API、打包方法、并做了很多的性能提升,目前应用RN的页面是50个;菠萝蜜也用RN的27和34版本做了两次整合,现在越来越多的页面正在将RN引入。 就本次活动我个人做了以下的记录,本次分享主要分四个阶段进行: 第一阶段:携程讲师--赵辛贵; 第二阶段:携程前端-姚瑞琼; 第三阶段:菠萝蜜--好大(徐本洋)

liu__520的博客 4174

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

探索高效跨平台开发:携程CRN框架开源解析

CRN,全称Ctrip React Native,是由携程无线平台研发团队匠心打造的一个优化版的React Native框架。这个框架不仅提升了稳定性和性能,还更加贴近业务需求,为开发者带来了高效的跨平台开发体验。CRN开源了其性能优化部分,特别是针对大规模业务开发所必需的关键改进。 ## 项目技术分析 CRN的核心亮点在于其独特的功能列表: 1. **框架和业务代码拆分**:允许更灵活的打...

gitblog_00091的博客 782

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

React架构整理

React 设计理念 React 是用 JavaScript 构建 快速响应 的大型 Web 应用程序的首选方式。 如何实现快速响应,需要解决两个方面的问题: 硬件限制CPU 由于JS是单线程的,脚本执行与页面渲染无法同时进行。当项目庞大,组件繁多时,JS执行就会超过16.6ms(浏览器单帧时长),用户就会感受到卡顿。 为了解决JS执行事件过长的问题,React 采取了时间切片的方式。将长任务拆分成多个片段到每一帧中执行。 网络延迟 网络延迟是前端开发者无法解决的。如何在网络延迟客观存在的情况下,减少用

e1172090224的博客 3461

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

干货 | 携程租车React Native单元测试实践

作者简介琨玮,携程高级前端开发工程师,从事React Native/Web前端的开发及维护工作,喜欢研究新技术。在较大规模的前端项目中,测试对于保证代码质量十分重要,而React的组件...

携程技术 1705

干货 | 减少50%空间,携程机票React Native Bundle 分析与优化

作者简介Sheila,携程资深前端开发工程师,关注前端性能优化;xqin,携程前端开发专家,CRN bundle分析平台开发者。一、前言在业务迭代上线的过程中,往往会出现一些代码冗余,导...

携程技术 834

React Native 实践之携程 Moles 框架

编者:本文来自携程框架研发部高级经理魏晓军在第二期【携程技术微分享】上的分享,以下为整理后的文字实录。视频回放可点击这里。关注携程技术中心微信公号ctriptech,可获知更多微分享课程信息。 因为支持用javascript开发原生应用,React Native一推出就受到不少公司热捧,各家都跃跃欲试。但有一个痛点是,在移动端,我们是否有...

weixin_34095889的博客 322
上一篇: 干货 | 日均TB级数据,携程支付统一日志框架
下一篇: 干货 | 高耦合场景下,Trip.com如何做支付设计与落地
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值