上海品茶

您的当前位置:上海品茶 > 报告分类 > PDF报告下载

2018年美团客户端基于响应式的架构实践.pdf

编号:95467 PDF 107页 13.11MB 下载积分:VIP专享
下载报告请您先登录!

2018年美团客户端基于响应式的架构实践.pdf

1、美团客户端基于响应式的架构实践CONTENTS 大纲TABLE OFEasyReact 和 EasyMVVM 的项目背景EasyReact 技术重点EasyMVVM 架构重点美团客户端面临的挑战美团客户端架构变迁EasyReact 与 EasyMVVM 的初衷EasyReact 和 EasyMVVM 的项目背景EasyReact 和 EasyMVVM 的项目背景美团客户端面临的挑战代码体量达到数百万代码行数十个团队协同开发迭代周期越来越快产品质量要求越来越高EasyReact 和 EasyMVVM 的项目背景美团客户端面临的挑战代码质量代码复用迭代流程架构美团客户端面临的挑战美团客户端架构变迁

2、EasyReact 与 EasyMVVM 的初衷EasyReact 和 EasyMVVM 的项目背景EasyReact 和 EasyMVVM 的项目背景美团客户端架构变迁0104050302简易形态 MVC结构美团AppEasyReact 和 EasyMVVM 的项目背景美团客户端架构变迁0104050302业务拆分架构Base LibraryCustomUIKitNetworkFoundationCryptoBase Business SDKAccount SDKPayment SDKPush SDKShare SDKTuangouWaimaiMovieHotelEasyReact 和 Ea

3、syMVVM 的项目背景美团客户端架构变迁0104050302响应式引入 基于 ReactiveCocoaEasyReact 和 EasyMVVM 的项目背景美团客户端架构变迁0104050302MVVM 架构(基于ReactiveCocoa)ModelViewModelViewEasyReact 和 EasyMVVM 的项目背景美团客户端架构变迁0104050302MVVM+模块化架构复用模块复用模块复用模块美团客户端面临的挑战美团客户端架构变迁EasyReact 与 EasyMVVM 的初衷EasyReact 和 EasyMVVM 的项目背景EasyReact 和 EasyMVVM 的项目

4、背景EasyReact 与 EasyMVVM 的初衷让人又爱又恨的 ReactiveCocoa概念烦杂调试困难易出错风格不统一EasyReact 和 EasyMVVM 的项目背景EasyReact 与 EasyMVVM 的初衷让人又爱又恨的 ReactiveCocoaFRP函数式编程的天然门槛基于 OOP 设计的响应式编程框架EasyReact 和 EasyMVVM 的项目背景EasyReact 与 EasyMVVM 的初衷RP基于 OOP 设计的响应式编程框架简单、易用EasyReact 和 EasyMVVM 的项目背景EasyReact 与 EasyMVVM 的初衷RPForMVVMMod

5、elViewModelView理解不一致层次划分不明风格不统一缺乏框架支持EasyReact 和 EasyMVVM 的项目背景EasyReact 与 EasyMVVM 的初衷FrameworkMVVM统一的 MVVM 框架简单、易用丰富的工具支持CONTENTS 大纲TABLE OFEasyReact 和 EasyMVVM 的项目背景EasyReact 技术重点EasyMVVM 架构重点声明式编程中的响应式编程基于图和面向对象的 EasyReact主流框架对比EasyReact 技术重点EasyReact 技术重点声明式编程中的响应式编程命令式编程过程式编程面向对象编程面向接口编程声明式编程约

6、束式编程DSL函数式编程逻辑式编程EasyReact 技术重点声明式编程中的响应式编程命令式编程过程式编程面向对象编程面向接口编程准备环境监测是否成功?协调解决执行环节开始结束EasyReact 技术重点声明式编程中的响应式编程命令式编程过程式编程面向对象编程面向接口编程父亲家庭母亲孩子们+登记家庭(父亲、母亲)-搬家(新地址)住址省地址市街道+登记地址-地址更名楼牌号职级编程语言-编码-加班程序员年龄人性别-结婚(配偶)-成长EasyReact 技术重点声明式编程中的响应式编程命令式编程过程式编程面向对象编程面向接口编程父亲家庭母亲孩子们+登记家庭(父亲、母亲)-搬家(新地址)住址年龄人性别

7、-结婚(配偶)-成长省地址市街道+登记地址-地址更名楼牌号职级编程语言-编码-加班程序员可表示地址的-地址更名-获取地址信息生产日期机器人型号-固件升级-充电可表示人的-获取信息-吃饭EasyReact 技术重点声明式编程中的响应式编程命令式编程过程式编程面向对象编程面向接口编程y=f(x)a=b.method(c)状态1状态2命令EasyReact 技术重点声明式编程中的响应式编程命令式编程过程式编程面向对象编程面向接口编程声明式编程约束式编程DSL函数式编程逻辑式编程EasyReact 技术重点声明式编程中的响应式编程声明式编程约束式编程DSL函数式编程逻辑式编程给定约束、范围得到结果约束

8、计算框架UIEdgeInsets padding=UIEdgeInsetsMake(10,10,10,10);view1 mas_makeConstraints:(MASConstraintMaker*make)make.top.equalTo(superview.mas_top).with.offset(padding.top);/with is an optional semantic fillermake.left.equalTo(superview.mas_left).with.offset(padding.left);make.bottom.equalTo(superview.mas

9、_bottom).with.offset(-padding.bottom);make.right.equalTo(superview.mas_right).with.offset(-padding.right);约束编程(Constraint programming)是一种编程典范,在这种编程范式中,变量之间的关系是以约束的形式陈述(组织)的。这些关系(约束)和命令式编程语言元素不同的是:它们并非明确说明了要去执行的步骤中的某一步,而是规范其解的一些属性。这样看来,约束编程是一种声明式的编程范式。维基百科“EasyReact 技术重点声明式编程中的响应式编程声明式编程约束式编程DSL函数式编程

10、逻辑式编程GPLDSLvsSQL领域特定语言指的是专注于某个应用程序领域的计算机语言。又译作领域专用语言。不同于普通的跨领域通用计算机语言(GPL),领域特定语言只用在某些特定的领域。比如用来显示网页的 HTML 语言,以及 Emacs 所使用的 Emac LISP 语言。维基百科“EasyReact 技术重点声明式编程中的响应式编程声明式编程约束式编程DSL函数式编程逻辑式编程DSL内嵌 DSL外部 DSLplatform:ios,9.0inhibit_all_warnings!target MyApp do pod ObjectiveSugar,0.5 target MyAppTests

11、do inherit!:search_paths pod OCMock,2.0.1 endendpost_install do|installer|installer.pods_project.targets.each do|target|puts#target.name endendDROP TABLE IF EXISTS table_test_one;CREATE TABLE table_test_one(id int(11)NOT NULL AUTO_INCREMENT,student_no varchar(10)NOT NULL,student_name varchar(10)NOT

12、NULL,subject_no varchar(10)NOT NULL,subject_name varchar(10)NOT NULL,score int(11)NOT NULL,PRIMARY KEY(id)ENGINE=InnoDB DEFAULT CHARSET=utf8;EasyReact 技术重点声明式编程中的响应式编程声明式编程约束式编程DSL函数式编程逻辑式编程函数式编程,特别是纯函数式编程,尝试最小化状态带来的副作用,因此被认为是声明式的。大多数函数式编程语言,例如 Scheme、Clojure、Haskell、OCaml、Standard ML和Unlambda,允许副作用

13、的存在。维基百科“EasyReact 技术重点声明式编程中的响应式编程声明式编程约束式编程DSL函数式编程逻辑式编程逻辑编程(逻辑程序设计)是种编程典范,它设置答案须匹配的规则来解决问题,而非设置步骤来解决问题。过程是 事实+规则=结果。不同的方法,可以看 Inductive logic programming。维基百科“规则事实friend(X,Y):-likes(X,Y),likes(Y,X).human(kate).human(bill).likes(kate,bill).举例(sort)q:-L=33,18,2,77,18,66,9,25,(sortcsj(L,P),write(P),

14、nl).sortcsj(L,S):-permutation(L,S),ordered(S).ordered().ordered(_|).ordered(A|B|T):-A=Observable in if query.isEmpty return.just()return searchGitHub(query).catchErrorJustReturn().observeOn(MainScheduler.instance)A1BC2673=B2+C2声明式编程中的响应式编程基于图和面向对象的 EasyReact主流框架对比EasyReact 技术重点EasyReact 技术重点基于图和面向对象

15、的 EasyReact基于图的数据结构面向对象的设计使用示例EasyReact 技术重点基于图和面向对象的 EasyReact基于图的数据结构nodenodenodenodenodenodenodenodenodenodenodenodeedgeedgeedgeedgeedgeedgeedgeedgeedgeedgeedgeedgeEasyReact 技术重点基于图和面向对象的 EasyReact基于图的数据结构node anode bnode cnode enode gnode hnode ilistener clistener dnode dlistener blistener amapl

16、inklinklistened byflatten mapfiltertakelistened bycombinelistened bylistened bycombineEasyReact 技术重点基于图和面向对象的 EasyReact基于图的数据结构面向对象的设计使用示例EasyReact 技术重点基于图和面向对象的 EasyReact面向对象的设计Nodevalue:TupstreamTransformsdownstreamTransforms(weak)value()-TlistenEdges(weak)Edgefrom()-NodesetFrom(Node)setTo(ToType)

17、to()-ToTypenext(FromItemType)MutableNode:Nodevalue:TupstreamTransformsdownstreamTransforms(weak)listenEdges(weak)Transform :EdgeFromItemType,Nodevalue()-TsetValue(T)from()-NodesetFrom(Node)setTo(Node)to()-NodeListenEdge :Edgenext(FromItemType)from()-NodesetFrom(Node)setTo(ToType)to()-ToTypenext(From

18、ItemType)setTo(ToType)to()-ToType类型定义EasyReact 技术重点基于图和面向对象的 EasyReact面向对象的设计Nodevalue:TupstreamTransformsdownstreamTransforms(weak)value()-TlistenEdges(weak)EdgeMutableNode:Nodevalue:TupstreamTransformsdownstreamTransforms(weak)listenEdges(weak)Transform :EdgeFromItemType,Nodevalue()-TsetValue(T)Li

19、stenEdge :EdgeSomeTransform :TransformNode,Nodefrom:Nodeto:Node(weak)next(FromItemType)构建连接EasyReact 技术重点基于图和面向对象的 EasyReact面向对象的设计Nodevalue:TupstreamTransformsdownstreamTransforms(weak)value()-TlistenEdges(weak)EdgeMutableNode:Nodevalue:TupstreamTransformsdownstreamTransforms(weak)listenEdges(weak)

20、Transform :EdgeFromItemType,Nodevalue()-TsetValue(T)ListenEdge :EdgeSomeTransform :TransformNode,Nodefrom:Nodeto:Node(weak)next(FromItemType)SomeListenEdge :ListenEdgeNode,Anyfrom:Nodenext(FromItemType)AnyObject+ListenExtensionto:Any(weak)listenEdges构建监听EasyReact 技术重点基于图和面向对象的 EasyReact面向对象的设计Nodeva

21、lue:TupstreamTransformsdownstreamTransforms(weak)value()-TlistenEdges(weak)MutableNode:Nodevalue:TupstreamTransformsdownstreamTransforms(weak)listenEdges(weak)value()-TsetValue(T)SomeTransform :TransformNode,Nodefrom:Nodeto:Node(weak)next(FromItemType)SomeListenEdge :ListenEdgeNode,Anyfrom:Nodenext(

22、FromItemType)to:Any(weak)Weak 链条作为传播链条数据流动EasyReact 技术重点基于图和面向对象的 EasyReact面向对象的设计Nodevalue:TupstreamTransformsdownstreamTransforms(weak)value()-TlistenEdges(weak)MutableNode:Nodevalue:TupstreamTransformsdownstreamTransforms(weak)listenEdges(weak)value()-TsetValue(T)SomeTransform :TransformNode,Node

23、from:Nodeto:Node(weak)next(FromItemType)SomeListenEdge :ListenEdgeNode,Anyfrom:Nodenext(FromItemType)AnyObject+ListenExtensionto:Any(weak)listenEdgesStrong 链条作为内存管理内存管理EasyReact 技术重点基于图和面向对象的 EasyReact面向对象的设计类型定义构建连接构建监听数据流动内存管理EasyReact 技术重点基于图和面向对象的 EasyReact基于图的数据结构面向对象的设计使用示例EasyReact 技术重点基于图和面向

24、对象的 EasyReact使用示例创建节点let nodeA=MutableNode(1)let nodeB=Node()创建变换连接节点创建监听连接监听者let transform=MapTransform$0*2 transform.set(from:nodeA)transform.set(to:nodeB)let listenEdge=BlockListenEdge print($0)nodeB.listened(by:self).with(listenEdge)改变节点值nodeA.set(5)EasyReact 技术重点基于图和面向对象的 EasyReact使用示例创建节点let n

25、odeA=MutableNode(1)创建变换连接节点创建监听连接监听者改变节点值变换衍生便捷监听let nextNode=nodeA.map$0*3 nextNode.listened(by:self).with print($0)声明式编程中的响应式编程基于图和面向对象的 EasyReact主流框架对比EasyReact 技术重点EasyReact 技术重点主流框架对比易用性性能排错能力EasyReact 技术重点主流框架对比易用性性能排错能力EasyReact 技术重点主流框架对比易用性对比RAC&RxSwiftImmutableCold signal&Hot signalSignal,

26、Producer and SubjectFunctor,Applicative,MonadEasyReactMutableLink,syncNode,Edge,ListenerOOP designedEasyReact 技术重点主流框架对比易用性性能排错能力EasyReact 技术重点主流框架对比性能对比0125,000,000250,000,000375,000,000500,000,000listenermapfilterfattenMap combinezipmergesyncToEasyReact(Objc)ReactiveCocoaEasyReact 技术重点主流框架对比易用性性能排

27、错能力EasyReact 技术重点主流框架对比排错能力ReactiveCocoa 调试堆栈EasyReact 技术重点主流框架对比排错能力ReactiveCocoa 调试堆栈5次变换 50层堆栈 堆栈内容无法参考EasyReact 技术重点主流框架对比排错能力EasyReact 调试堆栈EasyReact 技术重点主流框架对比排错能力EasyReact 调试堆栈5次变换 10层堆栈 堆栈内容与变换相符EasyReact 技术重点主流框架对比排错能力追溯CONTENTS 大纲TABLE OFEasyReact 和 EasyMVVM 的项目背景EasyReact 技术重点EasyMVVM 架构重点

28、EasyMVVM 框架简介EasyMVVM 解决的问题Rubik 模块化方案EasyMVVM 架构重点EasyMVVM架构重点EasyMVVM 框架简介整体架构EasyFoundationSequenceThread-safe CollectionTupleEnumerateUseful BlocksEasyReactNodeEdgeTransformListenEdgeMutable NodeNode OperationCancelableEasyActionActionOperationOperations operationOperationQueueEasyNetworkService

29、ManagerServicePluginsEasyMVVMBinderContainerEventHandlerModelModelCenterUIKit CategoryRubik FrameworkCellPresentationContainerViewContentViewGridViewListViewRubikView ControllerPresentation ProviderContentView ControllerListView ControllerGridView ControllerEasyDebug ToolboxSqlite3WebSocketKituraVis

30、.jsEasyMVVM 架构重点EasyMVVM 框架简介EasyMVVM 解决的问题Rubik 模块化方案EasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定聚合类视图的绑定页面间的依赖EasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定ViewViewModelModelBindingInvokeEasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定ViewViewModelModelBindingInvoke(VC)NodeEventHandlerNodeEventHandlerOperationResultErrorEasyMVVM 架构重点Ea

31、syMVVM 解决的问题声明式的绑定ViewViewModelModel(VC)NodeEventHandlerNodeEventHandlerOperationResultErrorNodeNodeNodeEasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定优惠买单PaymentVCrootView consumeTextField textNode QRCodeButton clickEvent excludeCheckbox checkedNode discountLabel textNode couponButton clickEvent paymentLabel tex

32、tNode conformButton clickEvent didAppearEvent errorMessagePaymentVMconsume:Node showQR:Handler isExclude:Node discount:Node coupone:Handler payment:Node conform:Handler fetchDiscount:Handler errorMsg:NodePaymentModelmerchantID:Node gotoQR:Operation result error conform:Operation result error discoun

33、t:Operation result errorEasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定 override func bindView(using binder:Binder)super.bindView(using:binder)binder.bind(mainVM.consume,with:consumeTextField.ezm.textNode)binder.bind(QRCodeButton.ezm.clickEvent,with:mainVM.showQR)binder.bind(mainVM.isExclude,with:excludeCheckbox.

34、checkedNode)binder.bind(discountLabel.ezm.textNode,with:mainVM.discount)binder.bind(couponButton.ezm.clickEvent,with:mainVM.coupone)binder.bind(paymentLabel.ezm.textNode,with:mainVM.payment)binder.bind(conformButton.ezm.clickEvent,with:mainVM.comform)binder.bind(ezm.didAppearEvent,with:mainVM.fetchD

35、iscount)binder.bind(ezm.errorMessage,with:mainVM.errorMsg)EasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定聚合类视图的绑定页面间的依赖EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 演示与实际的差异vsEasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 固定页面与聚合页面的差异vs优惠买单EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 UITableView 与 MVVMclass TableViewController:UIViewControlle

36、r,UITableViewDelegate,UITableViewDataSource IBOutlet var tableView:UITableView!let dataSource=(title:a,height:17),(title:b,height:20),(title:c,height:17),(title:d,height:22)override func viewDidLoad()super.viewDidLoad()tableView.register(UITableViewCell.self,forCellReuseIdentifier:reusableCell)func

37、tableView(_ tableView:UITableView,numberOfRowsInSection section:Int)-Int return dataSource.count func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-UITableViewCell let cell=tableView.dequeueReusableCell(withIdentifier:reusableCell,for:indexPath)cell.textLabel?.text=dataSourcein

38、dexPath.row.title return cell func tableView(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-CGFloat return CGFloat(dataSourceindexPath.row.height)func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)/do something EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 UITableView 与 MVV

39、Mclass TableViewController:UIViewController,UITableViewDelegate,UITableViewDataSource IBOutlet var tableView:UITableView!let dataSource=(title:a,height:17),(title:b,height:20),(title:c,height:17),(title:d,height:22)override func viewDidLoad()super.viewDidLoad()tableView.register(UITableViewCell.self

40、,forCellReuseIdentifier:reusableCell)func tableView(_ tableView:UITableView,numberOfRowsInSection section:Int)-Int return dataSource.count func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-UITableViewCell let cell=tableView.dequeueReusableCell(withIdentifier:reusableCell,for:i

41、ndexPath)cell.textLabel?.text=dataSourceindexPath.row.title return cell func tableView(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-CGFloat return CGFloat(dataSourceindexPath.row.height)func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)/do something 数据变化无法传递回调方

42、式无法声明回调分散代码混乱EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 多类型异构场景class DiscoverViewController:UIViewController,UITableViewDelegate,UITableViewDataSource IBOutlet var tableView:UITableView!let dataSource:News=.Video(title:video,url:xxx),.Picture1(title:h2,image:yyy,description:desc),.Picture1(title:h3,image:z

43、zz,description:Desc),.Picture3(title:ps,images:aaa,bbb,ccc),.BigPicture(title:bigger,image:fff),.Video(title:new video,url:ggg)override func viewDidLoad()super.viewDidLoad()tableView.register(VideoCell.self,forCellReuseIdentifier:Video)tableView.register(Picture1Cell.self,forCellReuseIdentifier:Pict

44、ure1)tableView.register(Picture3Cell.self,forCellReuseIdentifier:Picture3)tableView.register(BigPictureCell.self,forCellReuseIdentifier:BigPicture)func tableView(_ tableView:UITableView,numberOfRowsInSection section:Int)-Int return dataSource.count func tableView(_ tableView:UITableView,cellForRowAt

45、 indexPath:IndexPath)-UITableViewCell switch dataSourceindexPath.row case.Video(let title,let url):let cell=tableView.dequeueReusableCell(withIdentifier:Video,for:indexPath)as!VideoCell cell.textLabel?.text=title cell.url=url return cell case.Picture1(let title,let image,let description):let cell=ta

46、bleView.dequeueReusableCell(withIdentifier:Picture1,for:indexPath)as!Picture1Cell cell.textLabel?.text=title cell.imageURL=image cell.desc=description return cell case.Picture3(let title,let images):let cell=tableView.dequeueReusableCell(withIdentifier:Picture3,for:indexPath)as!Picture3CellEasyMVVM

47、架构重点EasyMVVM 解决的问题聚合类视图的绑定 多类型异构场景 let dataSource:News=.Video(title:video,url:xxx),.Picture1(title:h2,image:yyy,description:desc),.Picture1(title:h3,image:zzz,description:Desc),.Picture3(title:ps,images:aaa,bbb,ccc),.BigPicture(title:bigger,image:fff),.Video(title:new video,url:ggg)override func vie

48、wDidLoad()super.viewDidLoad()tableView.register(VideoCell.self,forCellReuseIdentifier:Video)tableView.register(Picture1Cell.self,forCellReuseIdentifier:Picture1)tableView.register(Picture3Cell.self,forCellReuseIdentifier:Picture3)tableView.register(BigPictureCell.self,forCellReuseIdentifier:BigPictu

49、re)func tableView(_ tableView:UITableView,numberOfRowsInSection section:Int)-Int return dataSource.count func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-UITableViewCell switch dataSourceindexPath.row case.Video(let title,let url):let cell=tableView.dequeueReusableCell(withId

50、entifier:Video,for:indexPath)as!VideoCell cell.textLabel?.text=title cell.url=url return cell case.Picture1(let title,let image,let description):let cell=tableView.dequeueReusableCell(withIdentifier:Picture1,for:indexPath)as!Picture1Cell cell.textLabel?.text=title cell.imageURL=image cell.desc=descr

51、iption return cell case.Picture3(let title,let images):let cell=tableView.dequeueReusableCell(withIdentifier:Picture3,for:indexPath)as!Picture3Cell cell.textLabel?.text=title cell.imageURLs=images return cell case.BigPicture(let title,let image):let cell=tableView.dequeueReusableCell(withIdentifier:

52、BigPicture,for:indexPath)as!BigPictureCell cell.textLabel?.text=title cell.imageURL=image return cell func tableView(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-CGFloat switch dataSourceindexPath.row case.Video(_,_):return VideoCell.height case.Picture1(_,_,_):return Picture1Cell.hei

53、ght case.Picture3(_,_):return Picture3Cell.height case.BigPicture(_,_):return BigPictureCell.heightEasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 多类型异构场景 let cell=tableView.dequeueReusableCell(withIdentifier:Video,for:indexPath)as!VideoCell cell.textLabel?.text=title cell.url=url return cell case.Picture1(let

54、title,let image,let description):let cell=tableView.dequeueReusableCell(withIdentifier:Picture1,for:indexPath)as!Picture1Cell cell.textLabel?.text=title cell.imageURL=image cell.desc=description return cell case.Picture3(let title,let images):let cell=tableView.dequeueReusableCell(withIdentifier:Pic

55、ture3,for:indexPath)as!Picture3Cell cell.textLabel?.text=title cell.imageURLs=images return cell case.BigPicture(let title,let image):let cell=tableView.dequeueReusableCell(withIdentifier:BigPicture,for:indexPath)as!BigPictureCell cell.textLabel?.text=title cell.imageURL=image return cell func table

56、View(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-CGFloat switch dataSourceindexPath.row case.Video(_,_):return VideoCell.height case.Picture1(_,_,_):return Picture1Cell.height case.Picture3(_,_):return Picture3Cell.height case.BigPicture(_,_):return BigPictureCell.height func tableVi

57、ew(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)switch dataSourceindexPath.row case.Video(_,_):/do something case.Picture1(_,_,_):/do something case.Picture3(_,_):/do something case.BigPicture(_,_):/do something EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 EasyMVVM 解决的问题跟踪变化的容器声明化的聚合类视图异构去除swit

58、ch-caseEasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 跟踪变化的容器EasyContainer线程安全变化跟踪变化具体类型索引变化元素数量变化变化类型与UITableView兼容支持事务EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 声明化的聚合类视图ListViewGridViewEasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 声明化的聚合类视图class ListView:UIView let dataSource:NodeContainer func pattern(forCellClass cellClas

59、s:CellClass.Type,viewModelIs vmClass:VM.Type,pattern:(VM)-Bool,binding:escaping(Binder,CellClass,VM)-Void)EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 声明化的聚合类视图class GridView:UIView let dataSource:NodeContainer let column:Node let itemHeight:Node func pattern(forCellClass cellClass:CellClass.Type,viewModelIs

60、 vmClass:VM.Type,pattern:(VM)-Bool,binding:escaping(Binder,CellClass,VM)-Void)EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 class GridViewController:EasyViewController IBOutlet var gridView:GridView!IBOutlet var resetButton:UIButton!IBOutlet var addButton:UIButton!/.let mainVM=GridMainVM()override func bindVi

61、ew(using binder:Binder)super.bindView(using:binder)gridView.pattern(forCellClass:GridItemCell.self,viewModelIs:GridItemVM.self,patternBlock:matchAllViewModels()(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.text)binder.bind(gridView.dataSource,with:mainVM.items)binder.bind(resetB

62、utton.ezm.clickEvent,with:mainVM.resetItmes)binder.bind(addButton.ezm.clickEvent,with:mainVM.addItems)/.声明化的聚合类视图EasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 class DiscoverViewController:EasyViewController IBOutlet var listView:ListView!let mainVM=DiscoverListViewModel()override func bindView(using binder:Bi

63、nder)super.bindView(using:binder)listView.pattern(forCellClass:VideoCell.self,viewModelIs:VideoVM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.urlNode,with:vm.videoURL)listView.pattern(forCellClass:Picture1Cell.self,viewModelIs:Picture1VM.self )(bin

64、der,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.imageURL,with:vm.imageURL)binder.bind(cell.desc,with:vm.desc)listView.pattern(forCellClass:Picture3Cell.self,viewModelIs:Picture3VM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)bin

65、der.bind(cell.imageURLs,with:vm.imageURLs)listView.pattern(forCellClass:BigPictureCell.self,viewModelIs:BigPictureVM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.imageURL,with:vm.imageURL)binder.bind(ezm.willAppearEvent,with:mainVM.reloadDiscoverLis

66、t)异构去除 switch-caseEasyMVVM 架构重点EasyMVVM 解决的问题聚合类视图的绑定 class DiscoverViewController:EasyViewController IBOutlet var listView:ListView!let mainVM=DiscoverListViewModel()override func bindView(using binder:Binder)super.bindView(using:binder)listView.pattern(forCellClass:VideoCell.self,viewModelIs:Video

67、VM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.urlNode,with:vm.videoURL)listView.pattern(forCellClass:Picture1Cell.self,viewModelIs:Picture1VM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.imageURL,

68、with:vm.imageURL)binder.bind(cell.desc,with:vm.desc)listView.pattern(forCellClass:Picture3Cell.self,viewModelIs:Picture3VM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.imageURLs,with:vm.imageURLs)listView.pattern(forCellClass:BigPictureCell.self,vie

69、wModelIs:BigPictureVM.self )(binder,cell,vm)in binder.bind(cell.textLabel.ezm.textNode,with:vm.title)binder.bind(cell.imageURL,with:vm.imageURL)binder.bind(ezm.willAppearEvent,with:mainVM.reloadDiscoverList)异构去除switch-caseclass DiscoverViewController:UIViewController,UITableViewDelegate,UITableViewD

70、ataSource IBOutlet var tableView:UITableView!let dataSource:News=.Video(title:video,url:xxx),.Picture1(title:h2,image:yyy,description:desc),.Picture1(title:h3,image:zzz,description:Desc),.Picture3(title:ps,images:aaa,bbb,ccc),.BigPicture(title:bigger,image:fff),.Video(title:new video,url:ggg)overrid

71、e func viewDidLoad()super.viewDidLoad()tableView.register(VideoCell.self,forCellReuseIdentifier:Video)tableView.register(Picture1Cell.self,forCellReuseIdentifier:Picture1)tableView.register(Picture3Cell.self,forCellReuseIdentifier:Picture3)tableView.register(BigPictureCell.self,forCellReuseIdentifie

72、r:BigPicture)func tableView(_ tableView:UITableView,numberOfRowsInSection section:Int)-Int return dataSource.count func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-UITableViewCell switch dataSourceindexPath.row case.Video(let title,let url):let cell=tableView.dequeueReusableC

73、ell(withIdentifier:Video,for:indexPath)as!VideoCell cell.textLabel?.text=title cell.url=url return cell case.Picture1(let title,let image,let description):let cell=tableView.dequeueReusableCell(withIdentifier:Picture1,for:indexPath)as!Picture1Cell cell.textLabel?.text=title cell.imageURL=image cell.

74、desc=description return cell case.Picture3(let title,let images):let cell=tableView.dequeueReusableCell(withIdentifier:Picture3,for:indexPath)as!Picture3Cell cell.textLabel?.text=title cell.imageURLs=images return cell case.BigPicture(let title,let image):let cell=tableView.dequeueReusableCell(withI

75、dentifier:BigPicture,for:indexPath)as!BigPictureCell cell.textLabel?.text=title cell.imageURL=image return cell func tableView(_ tableView:UITableView,heightForRowAt indexPath:IndexPath)-CGFloat switch dataSourceindexPath.row case.Video(_,_):return VideoCell.height case.Picture1(_,_,_):return Pictur

76、e1Cell.height case.Picture3(_,_):return Picture3Cell.height case.BigPicture(_,_):return BigPictureCell.height func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)switch dataSourceindexPath.row case.Video(_,_):/do something case.Picture1(_,_,_):/do something case.Picture3(_,_):/

77、do something case.BigPicture(_,_):/do something 代码对比EasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定聚合类视图的绑定页面间的依赖EasyMVVM 架构重点EasyMVVM 解决的问题页面间的依赖ViewViewModelModelBindingInvokeEasyMVVM 架构重点EasyMVVM 解决的问题页面间的依赖ViewViewModelModelViewViewModelModelViewViewModelModelEasyMVVM 架构重点EasyMVVM 解决的问题页面间的依赖ViewVM1Model1View

78、Model3ViewVM4Model2VM2VM2VM3EasyMVVM 架构重点EasyMVVM 解决的问题页面间的依赖MerchantList PageMerchantList ViewModelMerchantList ModelMerchantDetail PageMerchantDetail ModelMerchantDetail ViewModelEasyMVVM 架构重点EasyMVVM 解决的问题声明式的绑定聚合类视图的绑定页面间的依赖EasyMVVM 架构重点EasyMVVM 框架简介EasyMVVM 解决的问题Rubik 模块化方案EasyMVVM 架构重点Rubik 模块

79、化方案为什么需要模块化方案Rubik 模块化系统EasyMVVM 架构重点Rubik 模块化方案为什么需要模块化方案代码复用复用模块复用模块复用模块EasyMVVM 架构重点Rubik 模块化方案为什么需要模块化方案代码复用分段场景EasyMVVM 架构重点Rubik 模块化方案为什么需要模块化方案代码复用分段场景不同类型聚合视图整合轮播图1x5大分类2x5小分类2x2推荐区单页广告区EasyMVVM 架构重点Rubik 模块化方案为什么需要模块化方案Rubik 模块化系统RubikEasyMVVM 架构重点Rubik 模块化方案为什么需要模块化方案Rubik 模块化系统RubikCubeEa

80、syMVVM 架构重点Rubik 模块化方案为什么需要模块化方案Rubik 模块化系统RubikViewCubePresentationListViewGridViewContentView?CustomViewEasyMVVM 架构重点Rubik 模块化方案为什么需要模块化方案Rubik 模块化系统 rubikView.cubs.value.add(listView)rubikView.cubs.value.add(gridView)rubikView.cubs.value.add(ContentView(uiView)CONTENTS 大纲TABLE OFEasyReact 和 EasyMVVM 的项目背景EasyReact 技术重点EasyMVVM 架构重点写在最后的话“EasyReact OC 版本即将开源!美团平台技术团队“EasyReact Swift 开发中 EasyReact JS 计划中 其他 Easy 系列陆续开源 美团平台技术团队Thanks Q&A

友情提示

1、下载报告失败解决办法
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站报告下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。

本文(2018年美团客户端基于响应式的架构实践.pdf)为本站 (云闲) 主动上传,三个皮匠报告文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三个皮匠报告文库(点击联系客服),我们立即给予删除!

温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。
会员购买
客服

专属顾问

商务合作

机构入驻、侵权投诉、商务合作

服务号

三个皮匠报告官方公众号

回到顶部