哪位物理大神能解释一下,这个滑块把自己抽离出来的问题?


##一、编程规约 ###(一) 命名规约
  1. 【强制】 代码中命名均不能以下划线或美元符号开始也不能以下划线或美元符号结束;

  2. 【强制】 代码中命名严禁使用拼音与英文混合的方式,哽不允许直接使用中文的方式; 说明:正确的英文拼写和语法可以让阅读者易于理解避免歧义。注意即使纯拼音命名方式 也要避免采用;

  3. 【强制】方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase风格,必须遵从驼峰形式第一个字母必须小写;

  4. 【强制】常量命名全部大寫,单词间用下划线隔开力求语义表达完整清楚,不要嫌名字长; 正例: MAX_STOCK_COUNT 反例: MAX_COUNT

  5. 【强制】中括号是数组类型的一部分数组定义如下:String[] args; 反例:请勿使用String args[]的方式来定义。

  6. 【强制】包名统一使用小写点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式但是类名洳果有复数含义,类名可以使用复数形式; 正例: 应用工具类包名为ponent {


    4.【推荐】在使用Touchable系列组件时进行setState或者大量调帧操作,请使用如下方式:
    
          



    1. 【强制】用户敏感数据禁止直接展示必须对展示数据脱敏; 说明:查看个人手机号码会显示成:158****9119,隐藏中间 4 位防止隐私泄露

    2. 【强制】请求傳入任何参数必须做有效性验证;避免过度请求服务,造成服务器压力或者双向校验; 如:验证手机号长度,是否是手机号等;

    1. 【推荐】開发工具使用WebStorm,安装ESLint插件进行代码检测代码中不要出现使用ESLint检查出的错误; 说明:变量命名规范,使用var或者const错误

    2. 【推荐】在WebStorm中导入附件的hoop-settings.jar文件进行代码格式化,提交的任何代码都需要进行格式化。快捷键是option+command+L


公元2016年末2017年初,某做旅行产品嘚互联网公司内产品经理疯狂的提 A/BTest 需求,以至于该司程序猿谈AB色变邪恶的产品经理令程序猿们闻风丧胆,苦不堪言...咳咳扯远了。
近期团队做了很多 AB Test 的业务需求在这种需求日益见多的情况下,我们不得不提升我们的代码组织方式以适应或更好的在此类需求上维护我們的代码。所以有了本文本文主要阐述了业务团队在做 AB Test 的一些想法和思路,才疏学浅不灵赐教。

既然产品经理在 A/B Test 胯下疯狂的输出那峩们就要弄清楚,什么是 A/BTest为何产品经理如此痴情于 A/B Test ?
A/B Test 就是为了同一个目标制定两个方案(比如两个websiteapp的页面),让一部分用户使用 A 方案另一部分用户使用 B 方案,记录下用户的使用情况哪个方案更接近测试想要的结果,并确信该结论在推广到全部流量可信
请注意上述那段话中的黑体字,这将是 AB Test 的核心价值所在
其实 A/B Test 就是我们中学上化学实验课时常做的对照试验,把这种对照试验搬到了互联网上通過改变单一变量的实验组和原来的对照组做对比,通过数据指标对比看哪种方案能够提高用户体验(转化率);

AB Test 的优点有哪些(对产品洏言)?


  

灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式A/B Test就是一种灰度发布方式,让一部分用户继续用A一部分用户开始鼡B,如果用户对B没有什么反对意见那么逐步扩大范围,把所有用户都迁移到B上面来灰度发布可以保证整体系统的稳定,在初始灰度的時候就可以发现、调整问题以保证其影响度。

可逆方案有点类似于之前的灰度发布,只不过不灰度的控制力更强当我们发布后发现實验组方案出现了严重的故障,或者对比数据量相差悬殊那么就完全可以全量切换回原来的对照组,保证了线上环境的稳定不影响用戶的正常使用。
这点对产品而言就是多了试错的可能,想想在之前App动态化匮乏的时代App的发布就是嫁出去的女儿泼出去的水,一去不复返发布了的产品用户更新完就不可能在回退到上一个版本。从这一点开始产品经理就大爱A/B Test !

数据驱动,这一点我想至关重要在目前这種以用户数据为商业土壤的大数据时代,一个产品是以数据驱动将能够更加铿锵有力的支持这个产品的全线发布,也是产品经理对新方案推进的重要王牌之前要发布一个新产品,要么美其名曰参考竞品(不反对抄袭抄袭是赶上竞争对手最快的手段,但是并不是超越的掱段)要么脑洞打开,认为某种新的方案或交互体验能带来更多的转化率这种方法都是没有数据说明的,只能通过项目上线后进行后評估才能确定是否如产品经理所愿真正到达了目标
通过A/B Test,能在不全量影响线上的正常运转的情况下通过对照度和试验组的数据对比,茬短时间能确定哪种方案的优越从而让产品的转化率在短时间能得可信性提升。这也正是产品经理说服老板并彰显其能力价值的精华の处!so,大爱!

在做 AB Test 之前有几个问题是要问产品经理的:

这其实就是我们上面那段话中加粗文字的重点,当然有些问题是服务端需要關心的,比如问题3和4
那么客户端开发需要关心哪些个问题呢?

第一个问题目标是什么?目的是什么这是我们需要问的,对客户端而訁A/B Test 就需要客户端维护两套同样业务的代码,这种工作量简单理解就是之前的double既然会导致工作量翻倍,那就要问清楚这次做 A/B Test 的目的是什么?评估一下真的值得这样做吗虽然有时候胳膊拧不过大腿,但或许在你的分析下某些需求是不需要做 A/B Test 的。例如:竞品已经做了很玖方案(你不要告诉我抄都没自信)或者很明显的UI改动是优于之前的方案的,等等

A/B Test 版本是什么?测试时间多长


第二个问题,A/B Test 版本是什么测试时间多长?其实这两个问题就是在确认这个 A/B Test 方案什么时候上线,什么时候下线上下线的时间我们要清楚,因为在这段时间內我们都需要去维护两套代码,而且在 App Size 这么紧张大家都在搞瘦身的大环境下,你的安装包的过大或需就是用户从一开始就不选择你们產品的理由!A/B Test 方案代码有写就有删,何时删代码取决于这个 A/B Test 方案何时下线删完代码后有多久的时间给 QA 测试工程师去测试,这都是要安排的

对于某些开发每天都要声嘶力竭的说5次以上:“这个(需求)是要算(研发)成本的呀。”这样用力扣研发成本尽量把价值低收益低的需求砍下去,把收益不明确的需求排到后面去相当于在输出几乎不变的基础上,节约了2-3个开发工程师这也是长期维持团队的诀竅,从源头上精简而不是苛求超人般的程序员。
如何衡量效果就是来判断这种需求是否是价值低收益低或不明确的项目,我们都想做囿价值的东西而不是随随便便随时准备砍掉的功能,希望产品经理敢想而且加以思考!
好了,扯完了产品篇咱们进入正题。
既然原夲一套代码有了两种逻辑或者两种UI样式,就需要从原本的逻辑中拆出来其必然结果是多了一个if判断语句,那如果判断的地方多了咱還这样if、if、if、if、i....就太失水准了,常言道:写业务代码搬得一手好砖是程序员的基本要求。接下来讲下小生的 A/B Test 方案探索历程

先来大概介紹本次探索的业务背景:

  
  • A 方案 线上方案,全量;
  • B 方案适用于 A 中的一种情况,是 A 方案的子集;
  • 非标准 A/B Test只是过渡,因为 A 方案为全量方案無法被下掉,B方案为部分A中的;

刚刚说了A 方案是一个全量方案,所以这里的switch会有一个默认方案但是这种写法实在是太low了,每一个调用函数中都去判断一次A/B影响效率暂且不提,维护起来也是坑坑坑看见第二张图的函数列表页觉得头大,而且也导致了Controller过于庞大如果再囿一个C方案岂不是要炸?所以这种方案不可取

方法选择子 + 字典,缓存式 A/B

由于Objective-C 的Runtime 动态特性我们可以把方法选择子缓存在一个字典中,在需要确定 A/B 方案的调用处判断一次得到对应方案的方法缓存字典,在调用的时候只需要去对应的缓存字典中调用就可以了,当然这里需偠扩展NSObject类中的- (id)performSelector:(SEL)aSelector

这种方案仅仅比上个方案提高了一点就是我们并没有在每个函数中判断 A/B ,只判断了一次但仍然解决不了Controller过于庞大,无法優雅的扩展的问题而且还引入了新的问题,就是在进行Runtime消息转发时的额外开销和performSelector返回值需要转一下类型的尴尬。

如图所示通过策略模式,把需要分 A/B 的方法抽象到一个协议中然后抽象出一个策略父类去遵循这个协议,其两个A/B子类也遵循这个协议这样在Controller只需要在判断A/B筞略的调用处初始化对应的策略类,通过父类指针去调用子类的协议方法达到A/B函数的执行。这样采用了面向对象的继承和多态的机制唍成了一次完美的 A/B 函数执行,AB策略可以自由切换避免了使用多重条件判断,同时满足了开闭原则对扩展开放(增加新的策略类),对修改关闭

协议分发可以简单理解为将协议代理交给多个对象实现,类似于多播委托

Protocol协议代理在开发中应用频繁,开发者经常会遇到一個问题——事件的连续传递比如,为了隔离封装开发者可能经常会把tableview的delegate或者datesource把自己抽离出来出独立的对象,而其它对象(比如VC)需要獲取某些delegate事件时只能通过事件的二次传递。有没有更简单的方法了协议分发器正好可以派上用场。

既然能实现多播委托消息分发那麼消息分发时,指定的分发的接收者不就是 A/B Test 的消息分为A/B分发吗?

先给各位看官呈上干货,是一个协议分发器通过该工具能够轻易实现将協议事件分发给多个实现者,并且能指定调用哪些实现者比如最常见的UITableViewDelegate和UITableViewDataSource协议,通过能够非常容易发分发给多个对象而且可以指定A/B方案执行,具体可参考

原理并不复杂, 协议分发器Dispatcher并不实现Protocol协议其只需将对应的Protocol事件分发给不同的实现者Implemertor。如何实现分发

NSObject对象主要通過以下函数响应未实现的Selector函数调用

     
     
     
     
     
     
     

因此,协议分发器Dispatcher可以在该函数中将Protocol中Selector的调用传递给实现者Implemertor由实现者Implemertor实现具体的Selector函数即可,而现实指萣的A/B调用需要传入所有实现者组织的下标,来指定调用


 
 
如何做到只对Protocol中Selector函数的调用做分发是设计的关键系统提供有函数

 



还有一点,协議分发器并不是一个单例而是一个局部变量,那如何来防止一个局部变量延迟释放呢这里使用了“自释放”的一种思想,看源码:

 
协議分发器使用需要了解如何处理带有返回值的函数 比如
我们知道,iOS中函数执行返回的结果存在于寄存器R0中,后执行的会覆盖先执行的結果因此,当遇到有返回结果的函数时返回结果以后执行的函数返回结果为最终值。
 
Protocol协议分发器本人并不是首创,也是看了这篇文嶂得到运用于 A/B Test 的灵感在这里感谢作者和开源社区。
 
随着A/B Test 的代码越来越多业务模块内的 A/B Test 组件化,无非是为了更方便的上下业务的 A/B Test 代码提高工作效率,让写代码和删代码变成一件快乐的事情
关于 iOS 组件化,网上也有很多文章这里就不炒冷饭了,大家可以搜索一下关于组件化的一些定义和经验
在整个客户端已经被组件化的今天,不是架构组的业务程序员可不可以尝试来解决一下业务模块内的 A/B Test 组件化呢iOS 組件化大部分都是围绕 Cocoapods 来展开的,所以在基于 Cocoapods iOS 高度组件化的的框架下 我们先来问几个技术问题。

相同架构的不同静态库是否可合并

 
 
这個问题主要是基于目前整个客户端架构,各个业务线向壳工程提供了自己的静态库
我们大部分时间(打包时)都会合并不同架构的相同靜态库,相同架构的不同静态库是否可合并

在合并不同架构的相同静态库时,用到以下命令:
  • 查看静态库支持的CPU架构
 
那么合并相同架构嘚不同静态库是怎么做的
静态库文件也称为“文档文件”,它是一些.o文件的集合在Linux(Unix)中使用工具“ar”对它进行维护管理。它所包含嘚成员(member)就是若干.o文件除了.o文件,还有一个一个特殊的成员它的名字是__.SYMDEF。它包含了静态库中所有成员所定义的有效符号(函数名、變量名)因此,当为库增加了一个成员时相应的就需要更新成员__.SYMDEF,否则所增加的成员中定义的所有的符号将无法被连接程序定位完荿更新的命令是:
  • 取出相同架构下的Lib.a。
    首先查看静态库Flight.a的架构:

    当然如果是 fat file ,我们就需要取出相同平台架构的库

  • 查看库中所包含的文件列表。
 
但是显然这样做太麻烦
 
Xcode 子工程,其实是帮助我们在一个工程内配合git submodule 来进行分模块开发
整理下思路。
  • 将子工程文件夹拖入父工程
 
这样其实回到了之前架构的一个状态,无法调用解耦相互依赖严重。
 
答案是subspec 不是独立的代码库,只是编译时候分开进行最后会囷pod形成一个产物。
为什么会问 Cocoapods subspecs因为在基于Cocoapods架构组件化后,业务对外部提供的是静态库类型的pod
源码类型是subspec,在引入pod时可以选择引入subspec目錄,也可以设置podspec的默认subsepcsubspect之间也可以有依赖关系。
 
业务线内部拆分可以做成多个 pod最后提供一个 pod 依赖所有业务内部的组件 pod,这样不影响外蔀架构打包业务线也可以灵活修改。
最后这个依赖所有业务内部组件的pod对外提供的也是一个静态库业务内部的组件pod不需要提供静态库,但是也会有独立的Git
当然这种业务内部的 A/B Test 组件化方案目前处于探索阶段,因为目前我们的 A/B Test 的代码量并没有达到需要我们进行拆分的地步所有这阶段尚处于技术拓展调(yi)研(yin)阶段。
关于 iOS A/B Test 的探索目前小生就这么多A/B Test 对于产品而言确实是一种比较好的方案,尤其是可逆性和数据驱動当然小生是站在开发的角度上来看待 A/B Test。既然是对产品有利的方案我们的代码就应该时代潮流,毕竟技术是为业务服务的
前段时间茬看 sunny 直播时,谈到了 iOS 开发的进阶速度

纯日常开发 < 纯看书、博客 < 自己试验、Demo < 写博客 < 系统性分享和讨论 < 提供完整的开源方案

 
之前自己的进阶速喥仅仅到写博客的分段最近这半年在团队中发起了技术分享了和团队博客的浪潮,希望能够向系统性分享、讨论和完整的开源方案这两個高分段冲分本次结合最近的业务和自身的一些想法和实践,完成了一次冲分尝试希望在冲分的路上越战越勇!

我要回帖

更多关于 把自己抽离出来 的文章

 

随机推荐