当前位置: 首页 > news >正文

用什么软件做网站最好网站建设公司专业网站费用报价

用什么软件做网站最好,网站建设公司专业网站费用报价,百度网站统计添加网址,徐州手机建站模板背景 提单页的位置 提单页是美团外卖交易链路中非常关键的一个页面。外卖下单的所有入口#xff0c;包括首页商家列表、订单列表页再来一单、二级频道页的今日推荐等#xff0c;最终都会进入提单页#xff0c;在确认各项信息之后#xff0c;点击提交订单按钮#xff0c;完… 背景 提单页的位置 提单页是美团外卖交易链路中非常关键的一个页面。外卖下单的所有入口包括首页商家列表、订单列表页再来一单、二级频道页的今日推荐等最终都会进入提单页在确认各项信息之后点击提交订单按钮完成最终下单操作。 所支撑的业务 虽然提单页的代码统一放在外卖代码仓库中但根据业务发展的需要提单页上的模块分别由不同的业务部门去负责维护。主要包括以下业务方 外卖侧业务 提单页绝大部分模块的需求开发和日常维护都是由外卖侧的研发同学在负责包括地址模块、商家商品信息模块、折扣信息模块、准时宝、隐私号、发票备注等。闪购侧业务 当从商超等频道进入提单页时提单页生成的是闪购侧订单闪购侧的订单在配送方式、红包、下单路径上都与外卖订单有所区别但又依赖于外卖的基础功能模块因此与外卖侧功能存在严重的耦合问题。其他业务 提单页上的部分模块对动态化配置能力有着很高的要求这些模块使用Mach等动态化模版来实现相关的业务逻辑由专门的业务组负责开发和维护。 随着业务的不断迭代提单页的模块也越来越多逻辑的耦合也越来越重。现在提单页的UI展示模块已经超过30个这些模块的展示与否基本上通过服务端的下发数据来决定。在不同的订单类型下提单页所展示元素的差异越来越大很多模块的代码已经不适合统一放在一起维护代码拆分的需求十分强烈。此外客户端包体积是衡量客户端性能的重要指标为了解决业务发展带来的提单页代码量急剧增长的问题同时实现页面元素的动态配置我们希望能够实现提单页的动态化而动态化需要基于容器来实现所以我们提出了提单页的容器方案。 问题和挑战 提单页的容器化与外卖首页的动态化有以下几点不同 提单页整体动态化的需求不是很强烈并且API改造的成本比较高因此API接口字段保持不变需要在客户端层面去做转换。首页模块基本仅作为展示用途提单页模块的交互逻辑要复杂一些比如发票模块进入二级页面操作完成后还要更新提单页的数据。首页模块的UI展示各模块之间是完全独立的而提单页的模块是根据功能聚合在一个组这些模块条件出现的位置不同展示的样式也不一致如下图备注发票模块所示最上层和最底层的模块上都带有圆角所以提单页需要外层再添加一个模块组。 容器化后的提单页需要实现模块之间的互相无感知根据服务端的下发数据客户端可以将闪购代码仓库内的模块和外卖代码仓库内的模块拼接起来组成完整的提单页展示给用户。当用户在提单页完成一系列操作时各模块可以提供必要的参数给服务端。要想实现这一点我们需要考虑以下几个问题 模块注册问题如何在无直接依赖的情况下让提单页获取页面可用模块。API数据分发问题如何将服务端字段转换为模块可用数据同时不侵入到模块这一层。通信问题模块之间如何实现联动效果。页面更新和复用问题在提单页刷新时如何提交数据给服务端以及如何完成模块的更新。设计方案 1.容器化整体的架构图设计 容器化是我们在外卖平台化之后对多方业务能力的支持和扩展在不改变API数据源等前提下我们保证其具有动态可配置化的能力。为了更好地支撑业务我们在业务层面抽离出来容器化框架层其所提供三个部分的核心功能: 1.功能节点扩展及通信功能2.可配置化功能3.数据分发功能。在最上层业务容器中目前所支持外卖提单页面模块、闪购提单页模块、提单页Mach外卖动态化模板模块、提单页MRNRN页面模块四种不同的业务。 1.1 概念解释 在容器化框架设计过程中我们引入了一些新的定义比如在Android端引入了Block的概念这里的Block是一个功能模块的简称。在提单页页面中我们可以理解为一个Block对应一个功能条目。在iOS端有与之对应的概念Element由于两者没有差异下文陈述中用Block代指两者。 Block有两种类型其一是普通的Block其包含BlockView视图层和BlockViewModel数据层。BlockView视图层用来展示具体的视图以及内部的业务逻辑BlockViewModel数据层用来数据解析。其二是LogicBlock是没有视图的Block单纯地用来做数据业务处理。 1.2 整体概述 在容器化之前我们的业务大多是模块化的结构模块化宿主类是承载所有模块化的管理类各个模块之间通过宿主类或者控制器进行数据交互。但在容器化改造中我们将之前宿主类中管理的模块进行拆解并重新定义了宿主类的职责。在容器化宿主类中我们将不再持有各个功能模块的引用而只要持有Root Block这一个实例就可以完成对所有功能模块的管理。而Root Block Context则用来处理父Block与子Block之间的通信以及子Block之间的通信。 1.3 核心功能 第一部分功能节点扩展及通信功能。主要是目前页面的集成和通信关系其中Root Block是Block Tree的根节点下面会挂载一些SubBlock子节点Root Block会控制整体的数据流的分发以及整体样式Root Block Context可以理解为上下文环境或通信的总线。每个模块都有自己的Context来维护自己向外部提供数据以及业务逻辑的能力这些子Context会统一注册到Root Context中进行管理维护。 第二部分可配置化功能。在发起数据请求成功之后客户端根据注册的Key以及接收到的数据动态创建Block的容器化能力。遍历解析数据以及配置文件先动态创建viewModel将创建好的viewModel绑定到生成的Block模块上动态添加到Root Block中。多业务方在完全不用相互感知的情况下完成对新增模块的开发。 第三部分数据分发。既将解析之后的数据由Root Block节点进行数据分发到各个子Block各子Block的BlockViewModel在更新数据之后并回传到Block中Block用更新后的数据更新View的展示。其中数据可以自动完成分发也可以手动的接管数据流进行相应的处理。 2. Block注册问题 2.1 Android 注册的设计方案 Android 是在编译时期通过APT注解处理器的方式将在指定模块上的注解信息和Block类关联起来生成Block类对应的工厂类然后将这些工厂类存在全局的Map集合中并在运行时进行初始化操作。 DynamicBinder(nativeId block_key_d, viewModel blockDViewModel.class, modelType blockDInfo.class)NativeID是用来标识Block块的唯一KeyviewModel是用来绑定View视图的数据层 modelType对应着API的数据Model。 2.2 iOS 注册的设计方案 iOS使用Kylin注册Kylin是美团平台开发的基建库利用Clang提供的section()函数在编译时Kylin将{kylin_Key,kylin_Data}格式的数据写入到可执行文件的特定数据段中运行期就可以通过读取指定的Key值获取相应的数据。 使用这种方式注册代码分散在每个组件内部。注册内容组件native_id、Element名称、viewModel其含义同上。 注册宏 #define PGA_ELEMENT_REGISTER(NATIVE_ID, PGA_ELEMENT, PGA_VIEW_MODEL) \KLN_STRING_EXPORT(AppKey_#NATIVE_ID, { \#PGA_VIEW_MODEL\ : \#PGA_ELEMENT\});3. API数据结构化 由于API下发数据的不规范性需要将数据按照data_key这种数据模式的方式进行整理然后在获取数据之后按照规则进行数据解析并创建相应的功能Block。 目前API数据返回的格式 {data:{xxx_pay_by_friend: true,xxx_by_friend_tip: 发给微信好友让TA买单,xxx_by_friend_bubble_desc: 找微信好友买单,xxx_friend_order: false}code:0,msg: }由于这种格式是平铺分散的没有将特定功能点的字段聚合在一起表示不利于我们动态地将数据Model与Block绑定在一起。 需要我们将一个模块的数据统一在一个JSON对象中整理之后API数据返回的格式如下 {data:{pay_by_friend:{//keyxxx_pay_by_friend: true,xxx_by_friend_tip: 发给微信朋友让TA买单,xxx_by_friend_bubble_desc: 找微信好友买单,xxx_friend_order: false}}code:0,msg: }将平铺的API数据整理成定制的结构化数据将Key作为唯一的标识那么就可以方便地用来对应指定模块化Block中所需的数据Model。 布局及位置信息会对应相应的模块视图层这由另外的layoutInfo字段给出。数组中的每条元素对应每一个Block模块 其中 native_id的值是唯一的且与上面Block在注册时候的Key保持一致data_key的值映射上面整理之后的API数据的Key这样在编译时期生成Block的时候就可以动态地关联相应的ViewModel以及数据模型。 {layout_info:[{native_id:order_pay_by_friend,data_key:pay_by_friend},{native_id:block_container_default,//容器组children:[{native_id:order_flower_cake,data_key:flower_cake}]}] }当然这里可以以组为维度将一些功能相似的模块聚合在一起native_id的含义同上Children是子Block结点的数组。 4. 模块间通信问题 由于之前模块化的时候我们通过中间类的方式承载各个业务模块的通信逻辑。以Android为例我们将多个子模块之间需要通信的逻辑用接口的方式抛到Activity层由Activity层进行业务逻辑的实现但是由于子模块众多最终导致该类的膨胀和模块的高耦合性难以进行扩展和维护。 在容器化设计的时候为了更好地使各个业务之间进行通信降低耦合性我们引入了BlockContext同上所述理解为通信总线。 每个Block都有自己的BlockContext各个BlockContext汇总到Root Block Context中去实现最终各个Block就可以通过BlockContext进行数据传递。 整体的通信分发图如下 图中展示的两种数据方式 4.1 Command数据交互方式 将所需要的数据包装成事件在指定的位置驱动事件的执行进而拿到需要的数据。 //声明事件容器 private SupplierCommandObject mSupplierCommand new SupplierCommand(); Override public SupplierCommandObject getSupplierCommand() {return mSupplierCommand; } //注册实现 context().getSupplierCommand().registerCommand(new Supplier() {Overridepublic Object run() { } }); //获取相应的Object对象 context().getSupplierCommand().execute();4.2 Event数据交互方式 利用观察者的方式订阅相应的事件通过主动触发从而完成数据分发等不同操作。 //声明事件容器 private SupplierEvent mSupplierEvent new SupplierEvent(); Override public SupplierEvent supplierResponseEvent() {return mSupplierEvent; } //实现订阅 context().supplierResponseEvent().subscribe(new Action() {Overridepublic void action() {} }); //触发相应的操作 context().supplierResponseEvent().trigger();5. Block页面数据分发问题 5.1 数据分发问题 Root Block在接收数据的之后会按照Block结点进行数据的分发。父Block将数据逐次的分发给子Block。 Block Tree数据分发逻辑简介图 Block页面的刷新流程时序图 5.2 Block创建的顺序 Block创建的顺序由API结构化数据中的layoutInfo数组来决定layoutInfo数组的具体格式如第三节API数据结构化中内容所示。容器化后的提单页会根据layoutInfo数组的顺序依次创建对应native_id的Block模块。因此对于一些基础公共模块比如wm_confirm_order_logical对应的Block我们可以将其放在layoutInfo数组的最前面让其提前加载保证负责UI展示的Block创建时数据可用。 5.3 数据拉取问题 由于提单页的模块比较多在页面曝光、页面刷新或提交请求时需要从指定的模块获取相应的数据作为请求的入参那么如何做成在不感知其他业务方模块的情况下完成数据的组装呢 如上面的通信设计思路我们利用Event数据交互方式从各个模块中将需要的数据取出来完成数据的拼装。其中不同业务场景提取数据需要的校验工作也分散在各个模块中进行处理。最终即使在物理层面上隔离了对Block的感知但是依然可以完成对请求所需数据的获取。 6. Block页面的复用问题 在实际的开发中有些Block的页面View大致上相似但是逻辑上有些细微的差异为了快速开发我们在设计上复用了其视图。Block、BlockView以及ViewModel的关系一个Block对应一个ViewModel和一个BlockView一个ViewModel和一个BlockView可以对应多个Block。 计算机界有一句名言“计算机科学领域的任何问题都可以通过增加一个中间层来解决。”原始版本出自计算机科学家David Wheeler相似的为了视图层的复用屏蔽数据层的差异我们在数据层的逻辑中转部分引入一个中间层ViewDataViewData是为了更好地适配数据模型以及区别视图展示上的差异这样就大大提高了代码的复用率。 收益 在开发过程中我们将iOS和Android系统的模块进行了对齐和统一容器化完成之后两端同一NativeID对应的模块展示着相同的UI数据也具有完全一样的业务逻辑。经过容器化后的提单页相关代码被划分到了33个模块当中这些模块分别承担着不同的职责。这里按照模块的业务功能、所采用的技术栈和所属业务线将这些容器化后的模块进行划分得到如下的柱状直方图 容器化之后的提单页完全由各模块组成这些模块可以负责UI展示也可以不展示任何UI模块单纯地处理业务逻辑。模块内部的开发方案也可以根据业务形态自由选择相互之间做到了完全无感知。这些优点为后续提单页的业务迭代和技术优化都提供了很大的空间。 解耦的收益 开发效率提升 容器化之前的提单页页面各部分共享同一个数据模型服务端接口数据返回后在提单页控制器内进行数据的更新、过滤和二次加工之后再分发给页面上的各模块。当不同的RD同时开发提单页的需求时这些放置在一起的业务逻辑会提高RD的开发成本另外很容易出现代码层面的冲突在需要RD手动解决的同时也很容易因为开发流程的不规范出现Bug。 容器化之后的提单页开发模式也相应发生了改变RD在开发过程中不会感知到别的模块内业务需求的改动各业务可以在各自的容器内进行有效的推进迭代而不用担心会影响到其他业务从而让多人协作开发效率得到一定的提升。 控制器瘦身 在客户端业务开发的层面MVC架构得到了广泛应用。容器化重构之前的提单页虽然也以模块化思想为基础做过多次重构但是依然深受MVC思想的影响在提单页控制器内保留了大量业务逻辑的代码。这些业务逻辑的代码最终会在业务迭代过程中逐渐变得臃肿和不可控最终成为下一次代码重构计划中的业务背景。 本次提单页的容器化改造彻底解决了这一问题。基于PGA框架包括接口异常处理、数据模型传递和二级页面跳转等业务逻辑代码都被收入到对应的Element和Block中改造后的提单页中已经不存在业务逻辑相关的代码彻底杜绝再次出现臃肿页面VC的可能。经统计iOS侧提单页控制器的代码行数从2894行减少到289行控制器类中仅包含Block组装的业务逻辑。 包体积减少 提单页承载着美团的外卖业务和闪购业务在未进行容器化之前两个业务方需要同时向订单库提交代码在订单库整体“瘦身”的过程中我们发现这种开发模式让包大小优化的工作多次出现反复并且统计指标也难以统一和对齐。对提单页进行容器化改造之后外卖和闪购分别维护各自模块内的代码相互之间无依赖闪购侧可以直接在自己的代码仓库内完成提单页模块的新增和修改不需要再给外卖代码仓库提PR也就不会对外卖侧的包大小统计产生影响。 动态化的收益 动态化是整个外卖业务的发展方向。提单页的动态化建立在容器化的基础之上在完成容器化之后就具备了动态化的基础。当前提单页的动态化所指的主要是模块层级的动态化提单页的各模块展示顺序、展示与否都可以完全由根据服务端下发的数据决定各模块可以自由地进行组合、拼装实现提单页的动态配置。 两端对齐的收益 之前因为历史原因提单页很多的功能模块Android和iOS在实现上大相径庭完全不一样的实现让两端在新业务需求到来时在与服务端接口对接、开发工时和开发方案上都存在很大的差异这些差异点对产品需求的排期、开发和测试上线上都产生了很多负面的影响。 提单页在容器化后的另外一项收益就是Android和iOS在模块层级的代码实现完成了统一。借助于PGA框架和Element注册机制Android和iOS具有大致相同的模块结构相同native_id的模块获取的API接口返回字段完全一致在页面请求接口数据时相同ID的模块也提供同样的数据字段。在后续的开发过程中两端对API接口字段的请求趋于一致可以最大程度地减少因为两端不一致带来的合作方开发成本也可以在一定程度上减轻下游的测试压力。 总结与展望 外卖客户端一直在推动核心页面的标准化同时一直在探索尝试让核心页面也具备动态化能力。提单页作为下单路径上的核心页面在PGA框架的基础上完成了容器化重构。至此外卖首页、点菜页和提单页在页面这一层级都统一使用PGA框架实现。统一化和标准化之后可以让编程风格趋于一致代码结构在不同平台保持统一在后续的需求开发中可以有效减少因为两端实现不一致出现的隐性开发成本。 提单页在容器化之后让区域动态化的技术演进更容易推进。模块之间的解耦让不同模块可以自由选择模块内使用的技术栈而不会对其他模块产生影响。对于提单页的部分模块完全可以通过Mach或者RN等动态化方案来实现通过区域动态化来进一步减少开发成本提高业务需求的开发效率。 在提单页之后客户端会继续推进订单状态页使用PGA框架实现容器化让标准化框架对用户下单路径上的核心页面实现100%覆盖。同时积极在提单页的商家商品信息展示、放心吃、准时保等模块探索页面的部分区域动态化进一步缩减包大小提高开发效率。 附录 1.Mach (马赫) 是外卖终端组自研的多终端跨平台级的局部动态化技术。 2.MRN 是美团基于React-native 0.54.3进行的二次封装抹平了两端上的差异并且提供了一些基础库和组件库供业务开发同学使用。 3.Metrics 是美团平台团队和外卖团队开发的新一代App性能采集、监控、统计平台。 4.Hertz赫兹是一个自动化的性能采集与监控SDK可以在开发、测试、灰度、运维各阶段采集性能指标、检测卡顿、测量页面加载时间帮助开发者监控和定位性能问题。 作者简介 李肖、廷瑞、彦平、同同均为美团外卖团队工程师。 招聘信息 美团外卖长期招聘 Android、iOS、FE 高级/资深工程师和技术专家Base 北京、上海、成都欢迎有兴趣的同学投递简历到techmeituan.com。
http://www.sadfv.cn/news/278205/

相关文章:

  • php网站后台开发wordpress网易云插件怎么用
  • 国外网站建设现状宜春代做网站
  • 手机网站html网站后台ftp账户
  • 神华集团两学一做网站我的世界做神器指令网站
  • 网站建设公司专业网站制作开发莱阳 网站建设
  • 大理网站制作建德广元建设有限公司网站
  • 网站制作价格怎么算网络公司做的网站
  • 开普网站建设公司wordpress打包小程序
  • 企业门户网站制作价格怎么算微信软文广告经典案例
  • 丰泽区住房和城乡建设局投诉网站网站设计案例公司
  • 荆州网站开发昆明 网站推广
  • 网站空间是什么意思东莞p2p网站开发费用
  • 网站建设多少钱专业可以免费做推广的网站
  • 建设学习网站自助建站平台设计器
  • 惠城区城乡规划建设局网站全国最大的关键词挖掘
  • 一个公司主体可以在多个网站做备案最好的韩国服务器
  • 潍坊市坊子区建设局网站免费店铺logo设计
  • 深圳做网站费用网络广告投放流程的第一步要做
  • wordpress 网站图标做网站大量视频怎么存储
  • 自己开网站需要什么加盟招商网站建设方案书
  • 人才网站养老保险怎么买最划算
  • 常用网站有哪些邯郸做网站推广
  • 智慧团建网站登录入口官网公司网页图片
  • 哈尔滨松北区建设局网站哪有网站给光头强做面
  • 义乌做网站公司哪家好网站建设 长春
  • 成都有哪些比较做网站比较好的wordpress首页添加文章列表
  • 能在线做初中题的网站怎样设计网站或网页
  • 李沧做网站手机开发公司
  • 网站开发用什么写网站建设明薇通网络不错
  • wordpress网站整站搬迁免费推广网站58