简洁易用的SDK开发之道

KerrieLVRG 8年前
   <h2>简洁易用SDK的特点</h2>    <h2>易用</h2>    <ol>     <li> <p>简单的api设计</p> <p>那么所谓的易用到底是什么呢?我们想创造一种最简单的方式,让人们在他们的应用中开始使用SDK. 如果它是易用的,它应该是不需要侵入太多你的代码或者你需要做很多繁琐的集成工作。只要在你的代码中新增一行我们的代码,就可以使用它了,类似这样:</p> <p>HyAwPay.init(this,"appid",""appkey");</p> </li>    </ol>    <p>2.轻松定制</p>    <p>开发者对SDK的拓展性要求,builder模式的使用,比如:</p>    <p><img src="https://simg.open-open.com/show/30db54f6ed7a226c653b50282e7d2247.png"></p>    <p>Paste_Image.png</p>    <p>3.防止误用</p>    <p>从Retrofit的构造函数我们可以得知,builder的参数在对象初始化的时候也进行了初始化,但是单纯的builder有时候会造成误用,比如这样:</p>    <p><img src="https://simg.open-open.com/show/a8bba311aa7ee700b7880a0c939073bf.png"></p>    <p>Paste_Image.png</p>    <h2>更好的方式呢?</h2>    <p>可消耗商品</p>    <p><img src="https://simg.open-open.com/show/b95bf4c819ed7c6c7d85a0f2110f6f05.png"></p>    <p>Paste_Image.png</p>    <p>不可消耗商品</p>    <p><img src="https://simg.open-open.com/show/8b36732cab9c6b615d7103cf1b4cbe4d.png"></p>    <p>Paste_Image.png</p>    <p>金额消费商品</p>    <p><img src="https://simg.open-open.com/show/c35000f2c7b60dcb96b4ec5c0a63ca93.png"></p>    <p>Paste_Image.png</p>    <p>由此我们对项目中的reporter库进行了改造,因为单纯的builder已经满足不了我们的需求:</p>    <p>初始化打点</p>    <p><img src="https://simg.open-open.com/show/7f91ddcf848a972819934123a05a667f.png"></p>    <p>Paste_Image.png</p>    <p>SDK上报打点</p>    <p><img src="https://simg.open-open.com/show/7f91ddcf848a972819934123a05a667f.png"></p>    <p>Paste_Image.png</p>    <h2>API的设计</h2>    <p><img src="https://simg.open-open.com/show/7164b97f7b1e4a1259fdcc727837f32c.png"></p>    <p>Paste_Image.png</p>    <p>一个 API 就像一个婴儿。他们很有趣,但他们需要18年的支持。任何 API 我们都必须要长期地支持,所以我们要让大家感觉到,我们正走在正确的路上,才能才久坚持支持下去。</p>    <p>1.回调的设计</p>    <p>我们平时开发当中都会见到什么样子的设计呢?首先我们看下微信的设计:</p>    <p><img src="https://simg.open-open.com/show/c963bd55f121e49713444fb31053df98.png"></p>    <p>Paste_Image.png</p>    <p>上图中为微信支付的调用代码,你要拿到结果从哪拿呢?首先你得在你<包名>/wxapi/下面创建微信指定的Activity对不对?在指定的activity中接受结果,可是这里收的结果,怎么跟你当前的业务关联起来呢?广播?监听器?好乱,反人类啊。</p>    <p><img src="https://simg.open-open.com/show/7c5ba1b4bcef67a8b644d9494b381623.png"></p>    <p>Paste_Image.png</p>    <p>那么支付宝的设计呢?</p>    <p><img src="https://simg.open-open.com/show/411b67401d74aa6dda0835cb45613e21.png"></p>    <p>Paste_Image.png</p>    <p><img src="https://simg.open-open.com/show/63a99151985be891053657ce248216c1.png"></p>    <p>Paste_Image.png</p>    <p>支付宝整个支付过程的调用还算是蛮简单的,但是涉及到一个问题,整个过程的调用在子线程中,要在主线程中拿结果,必须自己在handler中收发处理结果消息。为什么整个过程不能帮开发者完成,然让开发者自己单独完成呢?</p>    <p>说道这里,那么我们开发者更能接受的回调长什么样子呢?</p>    <p><img src="https://simg.open-open.com/show/c86f7c4bcb5852707b76e480ee534b87.png"></p>    <p>Paste_Image.png</p>    <p>上图是AsyncHttpClient的回调,整个过程清晰,回调结果更加清晰。有人说工具库和功能库是有本质区别的,区别在什么呢?对,区别在微信和支付宝有界面啊,activity中回调结果的接受本来就不容易。答案是什么样的呢?</p>    <p>答案是有界面的支付api,也是可以用这么简单的回调的,对吗?</p>    <p><img src="https://simg.open-open.com/show/74db9c0d461c8ebe4a5c31cc9cc68105.png"></p>    <p>Paste_Image.png</p>    <p>其实实现这样回调并不难,我们知道回调的定义一般都是interface,而interface是不能在activity之间通过intent传递的,那么用什么方法能让它传递呢?没错,可能有人已经想到了,容器啊,interface直接放全局的容器,在从第一个activity到第二个activity时传递容器过去,然后在第二个activity中接收,然后整个回调看起来就是这么简单的api。</p>    <h2>API稳定性</h2>    <p><img src="https://simg.open-open.com/show/6d18e25f3790de1dd5a867e7129c6d7f.png"></p>    <p>Paste_Image.png</p>    <p>1.如何确保稳定</p>    <p>作为开发人员我们可以做什么,以确保尽可能高的稳定性?有一些事情是我们开发过程中的关键。首先,代码审查是非常重要的,必须得认真对待它们。然后,通过不断地问自己“这个代码有什么问题吗?”我们可以这样试着去问自己,以达到尽可能的防守。</p>    <p>如果能够自动获得一些基本的正确性保证,也可以在早期帮助捕捉错误,所以单元测试是非常有用的。</p>    <h3>优美的降解</h3>    <p>开发者经常是容易不耐烦的,所以有一些错误越尽早抛出就越好。</p>    <p>比如开发者传的参数缺少,很明显的是不能继续进行业务上的处理的,是否可以直接抛出异常出来</p>    <p>保证你的 SDK 在生产环境中绝不会出错,让你的代码持续运行在他们的应用中</p>    <h3>轻量</h3>    <p>1.用户不太可能下载大的应用程序,这意味着安装包的大小是一个关键内容</p>    <p>2.伟大的第三方库,可以真正给予贡献于你的应用程序,但当涉及到 size 规模和影响时,他们会显得不自由</p>    <p>3.作为一个 SDK 你应该努力平衡你的尺寸与功能。因此,要注意引入第三方库,以确保它们只满足所需的内容。</p>    <p>4.积极地监控每个 build,使我们能够衡量的真实影响开发者的 APK 大小情况。没有硬性和快速的规则来解决大小增加,但一直关注它显然是有帮助的。</p>    <h3>模块化</h3>    <p>1.适配器模式</p>    <p><img src="https://simg.open-open.com/show/7d6c1d04f8b37a98f7e877f6fdf856a3.png"></p>    <p>Paste_Image.png</p>    <p>上面图中几行代码涉及到三个可更换模块</p>    <p>HTTP请求模块,相应内容格式化模块,相应内容处理模块</p>    <h3>更简单的异步</h3>    <ul>     <li>在应用中进行有限的同步工作</li>     <li>请帮开发者进行线程的切换</li>     <li>API代码运行线程的统一</li>    </ul>    <h3>可扩展的类和接口</h3>    <ul>     <li>除了运行时检测,我们不能满足每个开发者的需求。我们易于使用和流行的一些特性让用户去发现。</li>     <li>开发人员有很多工具,有很多的选择,他们需要在他们的代码中保持灵活性。</li>    </ul>    <h3>构建工具的支持</h3>    <p><img src="https://simg.open-open.com/show/ef2fd86d0de9494eaa722a8fe131a230.png"></p>    <p>Paste_Image.png</p>    <p><img src="https://simg.open-open.com/show/c150e14ffd41afb984077fde1cd89047.png"></p>    <p>Paste_Image.png</p>    <p><img src="https://simg.open-open.com/show/a81ccf06f2edfda951ca75c57fb3f416.png"></p>    <p>Paste_Image.png</p>    <ul>     <li>可以让开发者选择不同的依赖管理器或者构件工具来引入或集成你的库</li>     <li>可选择的依赖方式(jar,aar,library)</li>    </ul>    <p> </p>    <p>来自:http://www.jianshu.com/p/ae4bf7ac91e4</p>    <p> </p>