学习的过程是从未知到知道、理解、灵活应用。对原有案例的理解、抽象、扩展、应用,而不是生搬硬套式的拿来主义,有所取舍,更能有所精进。
一、项目目标与架构设计
随着业务的发展和前端设计的演进,app早期开发的搜索功能相对于淘宝、京东、考拉等竞品,显得不够美观,体验不够友好。对前端搜索功能进行整体改版,将搜索分类结果页的功能样式进行统一调整,目标提高功能体验、页面点击率、订单转化率。
iOS组目标:
1、原有搜索是基于原始的MVC架构开发,代码耦合性高,维护成本较高。需要重新设计搜索结果页架构,降低代码耦合性,降低维护成本。
2、梳理搜索业务逻辑,便于后续开发和维护,方便移交其他同事。
3、提高团队的协同开发能力。
搜索功能简述
因搜索业务的关联性和改版传统(第三次重构),关键词搜索页和分类结果页高度相似性,是写在一个页面中的,将页面类型传给后端,后端返回对应的数据,前端根据数据动态显示,这期改版接口也是统一的,维持了旧逻辑。
搜索业务的特殊性
1、搜索页的所有资源位都是与搜索词或分类词强相关的。接口比较集中,数量较少,但接口参数多达30多个,参数的格式多样化,尤其是搜索词可能含有特殊字符等。
2、搜索结果繁多时,需要对结果进行各种排序、筛选,涉及的交互联动较多,如图文分类楼层与分类浮层、筛选浮层、搜索框搜词四处相互联动等。
3、需要瀑布流布局并带有滚动顶部悬停效果的特殊设计。初始状态顶部全部展开,向下滚动只悬停快速筛选,向上滚动出现导航栏悬停排序楼层和快速筛选楼层。
4、分类搜索和结果搜索写在一个页面中,与外部页面的交互需要区分页面类型。
iOS端架构浅谈
首先要明确框架、架构、模式的区别和联系,网络资源丰富,这里就不展开说了。
曾作为主程参与过公司的单品页重构(VIPER)和结算页重构(VIPER),这两个项目我也在维护着,现主导搜索功能重构。模块架构主要有MVC、MVVM、MVCS、VIPER等,早期开发主要是MVC、MVCS,后续随着业务拓展,开始流行楼层Adapter装配机制和context机制,业务模块的开发也从MVVM逐渐过渡到VIPER。架构没有绝对的好坏之分,要平衡各要点,根据业务需要选择维护成本低、可测性好、拓展性好、易于上手的架构。
iOS端搜索结果页架构设计
对于业务复杂的模块,业务逻辑拆分的越明确越单一,相对来说,越有助于理解业务和降低维护成本。VIPER架构分工明确,多角色交互,是复杂模块的首选架构。但也存在一些问题,若使用时设计的不够具体,拆分不清晰,开发人员没有严格遵守开发规范,容易造成引用关系的混乱和事件响应链过长,胶水代码过多的问题,业务理解上更为复杂。
在VIPER的基础上,为了优化响应链过长和胶水代码过多的问题,平衡了耦合性,尝试了用分类思路进行逻辑隔离。各个功能类之间的关系图如图1所示。
图1搜索结果页架构设计
说明:分布式架构设计,黑色实线箭头代表类的strong持有关系,蓝色虚线箭头代表交互协议的代理关系,保障引用关系是单向的,提高各模块的独立性和可测性。
Context:上下文环境,是整个架构的核心,强持有各个模块的主类,各个模块通过协议方式向context传递事件。类似于消息路由,负责响应各个模块的事件,并通过主动调用的方法,发现其他模块的服务,不处理的具体的业务逻辑,只负责将事件的转发给各个模块。context承载了整个模块的事件转发,相对繁重,将context对接的各个模块分别封装到一个分类文件中,独立处理。
ServiceManager是网络请求管理类,管理搜索结果页的网络请求,请求参数拼接等。
DataManager是全局的数据中心,管理者该模块的基础数据(外部数据EntryModel和网络数据webDatas)、展示数据(viewModels)以及他们之间的转换逻辑。viewModels对应着具体的业务逻辑,通过从DataManager抽取数据,各viewModels懒加载数据,自主更新自己的数据源。
LogicHelper是逻辑处理工具类,将纯碎的业务逻辑和数据逻辑,抽象提取成一个通用的统一的方法实体,提供给其他模块调用。
OverManager是浮层调用的管理类,控制浮层的展示、关闭以及浮层与context的交互逻辑。
ContentView是自定义视图组件的管理类,管理NavBarView、HeaderView、ListView等视图创建、布局、联动交互等。
最底层一排的类,实现更具体的业务逻辑,瀑布流采用adapter楼层装配机制。
项目主要的资源配置
项目改版排期:
1、搜索结果页一期(75人天)做新旧AB版
2、搜索结果页二期(68人天)插入开学季需求10人天,临上线新增需求,在新旧AB版基础上,做新版一期和新版二期AB版
3、搜索中间页(18人天)(进行中)
iOS组开发人员:博主(主导)和5位同事,我和2位同事全程参与。
产品经理:产品1人。
UI设计师:UI设计师2人。
交互设计师:1人。
后端工程师:中台1人、后台3人。
测试工程师:3人。
二、评估结果
实际完成工时:
搜索结果页一期:88人天
搜索结果页二期:92人天
搜索中间页:进行中
总体上,一期开发问题较多,项目进度管理不明确和不够细致,二期有了比较大的提高。
开发阶段
Highlights
1、整体上iOS组各组员工作量相对均衡,相互配合比较默契,未出现阻塞性事件。
2、一期工期工作量超载,工时最为紧张,项目如期上线。
3、二期紧急插入教辅地址功能和一期和二期AB测功能,对项目造成较大冲击,但项目的进度都是可控的,并未出现混乱问题。
4、二期修复了一期遗留的全部问题,框架结构较一期更清晰,业务逻辑更清晰。
Lowlights
1、一期瀑布流顶部的效果没有达到预期效果,采用的折中方案,遗留二期处理。
2、一期开发过程,组员对代码的编写不够严谨,开发效率较二期明显偏低。
3、二期开发中修复一期遗留问题时,改动较多,对原有代码造成较大冲击。
测试验收阶段
一期bug量iOS和安卓两端合计406个,iOS端较多。二期业务比一期更复杂,但iOS和安卓两端的bug量合计314个,相对一期有所减少,两端端基本持平。
Highlights
1、bug处理的响应较快。
Lowlights
1、有不少bug非常基础,甚至不应该出现。
2、bug修复期间出现了bug解决和激活的多次反复。
3、bug量和所写业务复杂度不匹配的问题。
4、一期的埋点出现type=new的丢失问题,部分埋点错误的问题。
5、做出效果和实际需求有较大差别。
三、分析原因
一期开发较失败原因
主观原因:
1、自己有很多私事(经历着生活的黑暗时刻),精力和态度上都不够投入,对项目的管控没有明确的思路,项目开发细则不够明确,造成人员效率偏低。
2、自己对搜索业务了解不充分,就着手项目架构设计,造成瀑布流悬停功能达不到预期效果,后续发现问题时也没有及时调整。
3、没有认真阅读开发文档和UI设计图,有疑问时,沟通不及时,造成不少“简单”问题,甚至不必出现的bug。
4、改动公用/别人代码时,不够细致,与相关同事沟通也不够,很少有覆盖全部场景的自测验证。
客观原因:
1、搜索一期工作量大,人员配置和项目工期紧张,项目文档不够完善。
2、为了满足“要求”,在开发阶段未结束,也未用测试用例自测,iOS提前提测,造成iOS的部分未做需求当成bug统计。
二期开发较成功原因
主观原因:
1、对搜索一期开发进行了总结,对工作流程的细节更完善,强化队员对开发文档和UI设计图的重视程度,整体上各组员工作量相对均衡,相互配合更默契。
2、对一期的项目架构和代码进行了优化,业务逻辑更清晰,明确了具体的联调流程和细节。
3、在提测前,对照PRD、UI设计、测试用例进行了一轮冒烟测试。
客观原因:
搜二期人员配置相对充足,文档比较完善。
四、经验总结
专心专注,清醒地思考,做正确的事,把事做正确。
开发阶段
1、项目开展前都要细致阅读PRD 和设计图明确需求和UI交互,确保和产品/设计的理解一致,全方位梳理业务逻辑,并设计代码的组织结构。
2、严格参照产品文档和设计图要求编写代码,若对文档有疑问,请及时和产品沟通,并通知安卓组开发人员协同调整。
3、改动代码的功能单一性和自测验证,及时提交代码。
4、改动同事代码前要和相关同事沟通确认,逻辑是否闭合,在确认调整代码,并及时自测。
5、若有代码编写细则,请按照项目主导的要求编写代码,保障代码逻辑的闭合和交互的一致性。
测试验收阶段
1、在提测前,请参照产品文档、设计图、测试用例,自行检查是否有遗漏的需求或理解错误的需求,减少基础性错误。
2、修改bug代码时,要梳理问题发生的根源和场景,尽量逻辑闭合,减少问题的反复修改。
3、改动bug过程可能会联动修改同事代码,记得沟通,梳理逻辑,并提醒测试回归。
开发细节分享
1、keyword,publisher 等搜索词中可能含有 /r & %26 等特殊字符,需要做转码处理
2、同一个页面生成多个页面实例时,接收通知的区分。
3、渐变色背景可以使用DDGradientLayerView 生成一个渐变视图,作为需要渐变背景的视图,约束布局相同即可。
网友评论