什么是 SDK?

SDK 全称 Software Development Kit,广义上的 SDK 是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合(在 iOS 项目中,SDK 也被称为库)。

SDK 的全称是 Software Development Kit,翻译过来是软件开发工具包,这是一种被用来辅助开发某类软件而编写的特定软件包。

在 iOS 开发或 Android 开发中,不可避免会需要使用第三方工具提升产品的开发效率,比如用于消息推送的极光,用于第三方支付与登录的支付宝,微信等等。但大多数商用产品都不会直接给出源码(可能只有为爱发电的开源项目才会无私提供源码),而我们在开发 App 时就需要将这些第三方 SDK 集成在我们的项目之中。

在前端项目,各类地图应用都提供js-sdk给开发者使用。

SDK设计理念

如何设计SDK,其实更多取决于你的场景,或者SDK最终的用途。比如实现一个给网页调用的SDK与用于服务端的SDK就有明显的差异,但这之间确实存在着一些共通的原则,或者方法论:

从邓老爷子的话术来说:一个中心、两个基本点、四项基本原则。

SDK一个中心:小而精。具体来讲就是两个原则:

  • 最小可用性原则,即用最少的代码,如无必要勿增实体

  • 最少依赖原则,即最低限度的外部依赖,如无必要勿增依赖

SDK 设计的四项基本原则

一款好用且设计充分的 SDK 必须要遵循以下 4 条基本原则,即:

  • 安全,稳定:考虑到 SDK 是需要嵌入到 App 里面去的,所以 SDK 最重要的特性就是安全性,不会因为乱开放接口而导致 App 数据泄露;其次重要的是 SDK 的稳定性, SDK 的 Crash 如果没有被捕获进行处理,则会导致应用彻底崩溃(这样就会导致第三方接入的 App 体验性非常差),甚至会直接导致接入方的用户流失;

    • 绝不能导致宿主应用崩溃,这是最基础也是最严格的要求

    • 较好的性能,比如SDK体积应尽量小,运行速度尽量快

    • 可测试,保障每一次变更

    • 向后兼容,不轻易出现 Breakchange

    • 混淆,理论上除了四大组件以及开放API接口外,其它的都需要进行混淆。

  • 少依赖,易扩展:这个也很好理解,比如:不依赖第三方 SDK,如果SDK中又依赖其他第三方 SDK, 不仅会导致 SDK 的体积变大,也会影响接入方集成 SDK 的相关成本。

    • 最小程度的第三方依赖,尽可能自行实现,确实无法避免则最小化引入

    • 插件化,最大限度支持扩展

    • Hook机制,满足个性化诉求

  • 统一的开发规范:对于 SDK 开发规范来说,统一的命名规范很重要,最好的状态是“接入方看到接口命名就能知道是哪家厂商的 SDK”,换句话说就是 SDK 的命名规范统一,形成自己公司的品牌效应,此外也方便开发者进行接入使用。此外也需要具有自己的编码规范,你可以在网上找到大厂的规范模板,并通过借鉴整理出属于自己的规范,从而尽早统一代码风格;

  • Library 小而精:小是指要避免造成接入方的App增加很大,不然会引起接入方的不满,甚至下架。精是指功能要专注,比如极光推送,就是专注推送相关的功能;

从用户的角度来说,sdk的设计思想基本原则包括:

  • 简单易用

    • 提供完善的文档指引(介绍、接入指引、示例、API文档),使得SDK能够被轻松集成。

    • 遵循目标语言的一般设计准则和约定,符合业界习惯。

    • 循序渐进地介绍新概念。

    • 接入步骤保持精简。

  • 始终一致

    • 维护统一的术语与概念,在整套服务内保持一致,包括客户端、服务端,所有目标语言库。

    • 客户学习一次业务概念,能够用于所有SDK模块中。

  • 可诊断

    • 异常时,客户应该能够理解错误原因以及如何解决。

    • 日志记录、链路上报以及异常处理与功能本身一样重要,实现应经过深思熟虑。

    • 错误信息除说明原因外,还应引导客户如何解决。

  • 安全可靠

    • 考虑数据存储安全以及政策合规。

    • 100%向后兼容。

    • 保证优秀的性能质量、功能质量。

当然从不同的角度,还有更多的规则。

SDK 内容应包括:

  • 功能模块:交付给客户接入、安装的产物。(如:人脸APP、AAR、IoT服务套件等)

  • API:SDK门面,一切功能的入口。

  • 文档:标准统一、结构化展示形式,接入指引。

  • Demo:可直接运行体验的Demo,让客户直观体验SDK能力。

SDK架构设计

一般从0设计一款SDK,总体上可以分为5个步骤:

  1. 基础架构的设计

  2. 开放API接口设计

  3. 业务功能框架设计与开发

  4. 基础核心库设计与开发

  5. 打包与发布

基础架构设计

一个好的架构可主要从可读性、可扩展性、可维护性三个方面进行考虑,即功能模块间相互独立,降低耦合度,保证结构清晰易于维护。通常我们可以把SDK架构简单分为两个层次:业务层和通用功能层。

  • 业务层可以独立成业务模块,包括开放API接口和业务功能实现

  • 通用功能层可以分为两个模块,

    • 通用功能模块

    • 基础工具模块

放API接口设计

开放API接口设计,是直接开放给开发者调用的,所以经常要转化角色。针对如何调用这个接口,如何用起来更方便快捷,并且不用去考虑任何场景和问题,总结了以下几个要点。

  1. API接口命名需要规范,且通俗易懂;

  2. 接口职责单一:一个接口只做一件事情

  3. 接口输入参数尽量少,如有必要参数,需要做好参数校验;

  4. 接口尽量保证是非阻塞的,这样不影响开发者正常业务逻辑处理;

  5. 接口调用日志需要清晰明了,便于调试;

  6. 接口结果最好是直接返回,尽量少的使用回调,如有必要,可以在回调方法命名上明确回调所在线程,如在主线程回调,可以使用onResultInMainThread这种方式来命名回调方法。另外使用回调时需要考虑内存泄漏问题,由于开发者有可能是使用匿名内部类的方式进行回调传参,这时如果调用程序的生命周期结束时回调还没有回来,就需要主动移除回调,防止内存泄漏,所以使用回调时还需要提供移除回调的方法。

业务功能框架设计

业务功能框架设计,不要过度设计,根据具体的业务需求来设计即可,不要为了一些未来很小概率发生的需求变化提前设

基础核心库设计与开发

基础核心库设计与开发,在核心库提炼过程中需要保证功能间互相独立,降低耦合度。

打包与发布

引用形式

首先确定SDK的引用形式。SDK整体而言是一个大模块。

对于前端JS

模块有多种表现形式:ES Module、CommonJS、AMD/CMD/UMD,

引用方面则大体分 CDN和 NPM两种。即无论我们实现的是哪种形式的模块,最终都是通过CDN或者NPM的方式提供给用户引用。

对于java

对于java,从Java 9开始,JDK又引入了模块(Module)。

Java 平台模块系统,可以说是自 Java 诞生以来最重要的新软件工程技术了。模块化可以帮助各级开发人员在构建、维护和演进软件系统时提高工作效率。软件系统规模越大,我们越需要这样的工程技术。实现 Java 平台的模块化是具有挑战性的,Java 模块系统(Module System)的最初设想可以追溯到 2005 年的 Java 7,但是最后的发布,是在 2017 年的  JDK 9。它的设计和实现,花了十多年时间,我们可以想象它的复杂性。

Java平时引用 sdk 有两种方式:

  • pom 依赖引用,直接从仓库中下载使用别人的工具包,属于在线模式;

  • 手动添加引入 sdk 的 jar 包,并在打包配置中声明将该包加入的工程,属于离线模式;

确定SDK的版本管理机制

现有较成熟的版本管理机制当属 语义化版本号 ,表现形式为 {主版本}.{次版本}.{补丁版本},简单易记好管理。

JS-SDK实现实操过程

下面我们将通过剖析 岳鹰前端监控SDK 的设计过程,来看看上述的设计原则是如何应用到实际的开发过程中的。

明职责,定边界

前面章节提到, 岳鹰前端监控SDK 是前端稳定性和性能监控的SDK,主要面向前端H5领域。因此,稍加分析即可得出以下结论

  • 前端领域,稳定性方面主要的关注点

    • JS异常

    • 资源加载异常

    • API请求异常

    • 白屏异常

  • 性能方面,核心的关注点

    • 白屏时间

    • 可交互时间(TTI)

    • 首屏时间

    • FP / FMP / FCP 等

上述监控内容实际上都相对独立,因此我们可以把Ta们横向划分为如下几大部分:

明确了SDK的边界以及各部分的职责,结合前端监控的特性,我们可以开始设计SDK的整体框架了。

筑框架,夯基础

首先确定SDK的引用形式

SDK整体而言是一个大模块,前端模块有多种表现形式:ES Module、CommonJS、AMD/CMD/UMD,而在引用方面则大体分 CDN和 NPM两种。即无论我们实现的是哪种形式的模块,最终都是通过CDN或者NPM的方式提供给用户引用。

比如 webpack,通过简单的配置就可以构建出一个UMD的bundle。通过 webpack将 SDK构建为一个UMD bundle,这样可以自动适配所有形式的模块。同时我们也将同时提供 CDN和 NPM两种引用方式,给用户更多选择。

确定SDK的版本管理机制

现有较成熟的版本管理机制当属 语义化版本号 ,表现形式为 {主版本}.{次版本}.{补丁版本},简单易记好管理。

一般重大的变更才会触发主版本号的更替,而且很可能新旧版本不兼容。次版本主要对应新特性或者较大的调整,因此也有可能出现breakchange。其他小的优化或bugfix就基本都是在补丁版本号体现。

看到此处,是否有点似曾相识的感觉?没错,所有NPM模块都遵循语义化版本规范,因此结合第一点,我们可以将SDK初始化为一个NPM模块,结合webpack的能力就可以实现基础的版本管理及模块构建。

确定SDK的基础接口

接口是SDK和用户沟通的桥梁,每一个接口对应着一个独立的SDK功能,并且有明确的输入和输出。

总结接口的设计原则,如下

  • 职责单一:一个接口只做一件事情

  • 命名简单清晰,参数尽量少但可扩展:好的接口命名就是最好的注释,一看即明其用处。参数尽可能适用 Object封装

  • 做好参数校验和逻辑保护:输入校验,提前报错。

领域分析,模块划分

定边界的时候,我们已经清楚划分了SDK的几个关键的部分:全局异常、API异常、页面性能和白屏,实际上监控SDK通常也会内置对页面流量的监控,以方便用户对异常的影响面做出评估。这几个核心的关键组成部分,每一块都对应一个专业的领域,因此对应到SDK也是每一个独立的模块。

除了这些核心的偏领域的模块,SDK还需要有更基础的与领域无关的模块,包括SDK内核(构造方法、插件机制、与下游服务的交互、上报队列机制、不同环境的管理等等)和工具类库。

我们可以先看一下岳鹰前端监控SDK最后的整体模块划分:

  • SDK底层提供基础的能力,包括上面提到的内核、插件机制的实现、工具类库以及暴露给用户的基础API

  • 可以看到,我们前面提到的所有模块都以插件的形式存在,即各领域的功能都各自松散的做实现,这样使得底层能力更具通用性,同时扩展能力也更强,用户甚至也可以封装自己的插件。

  • Biz部分更多是对于不同宿主环境的多入口适配,当前支持浏览器、Weex以及NodeJS。

参考文章:

手把手第二篇:如何设计 SDK https://www.finclip.com/blog/first-app-ep02/

如何打造一款标准的JS-SDK https://developer.aliyun.com/article/776193

如何快速将你的应用封装成JS-SDK?https://www.163.com/dy/article/FSRO8E4G05313LFD.html

转载本站文章《SDK设计与封装:从基础概念入门到架构设计落地笔记》,
请注明出处:https://www.zhoulujun.cn/html/webfront/engineer/Architecture/8927.html

SDK设计与封装:从基础概念入门到架构设计落地笔记的更多相关文章

  1. Spark集群基础概念 与 spark架构原理

    一.Spark集群基础概念 将DAG划分为多个stage阶段,遵循以下原则: 1.将尽可能多的窄依赖关系的RDD划为同一个stage阶段. 2.当遇到shuffle操作,就意味着上一个stage阶段结 ...

  2. Exynos4412 IIC总线驱动开发(一)—— IIC 基础概念及驱动架构分析

    关于Exynos4412 IIC 裸机开发请看 :Exynos4412 裸机开发 —— IIC总线 ,下面回顾下 IIC 基础概念 一.IIC 基础概念 IIC(Inter-Integrated Ci ...

  3. Slickflow.NET 开源工作流引擎基础介绍(六)--模块化架构设计和实践

    前言:在集成Slickflow.NET 引擎组件过程中,引擎组件需要将用户,角色等资源数据读取进来,供引擎内部调用:而企业客户都是有自己的组织架构模型,在引入模块化架构设计后,引擎组件的集成性更加友好 ...

  4. 架构设计:前后端分离之Web前端架构设计

    在前面的文章里我谈到了前后端分离的一些看法,这个看法是从宏观的角度来思考的,没有具体的落地实现,今天我将延续上篇文章的主题,从纯前端的架构设计角度谈谈前后端分离的一种具体实现方案,该方案和我原来设想有 ...

  5. Flink基础概念入门

    Flink 概述 什么是 Flink Apache Apache Flink 是一个开源的流处理框架,应用于分布式.高性能.高可用的数据流应用程序.可以处理有限数据流和无限数据,即能够处理有边界和无边 ...

  6. 03-Django基础概念和MVT架构

    一.Django基础 掌握Django的 MVT 架构的使用 掌握Git管理源代码 主要内容 了解Django的 MVT 架构的使用流程 使用Django完成案例 : 书籍信息管理 MVC介绍 MVC ...

  7. DDD中Dto领域驱动设计概述,摘自《NET企业级应用架构设计》

  8. Serverless 基本概念入门

    从行业趋势看,Serverless 是云计算必经的一场革命 2019 年,Serverless 被 Gartner 称为最有潜力的云计算技术发展方向,并被赋予是必然性的发展趋势.Serverless ...

  9. GPS部标平台的架构设计(四)-百度地图设计

    部标GPS软件平台之百度地图设计 地图是客户端中不可缺少的一个模块,很多人在设计和画图时候,喜欢加上地图引擎这样高大上的字眼,显得自己的平台有内涵,说白了就是用第三方的SDK来开发,早期的GPS监 控 ...

  10. 简述移动端IM开发的那些坑:架构设计、通信协议和客户端

    1.前言 有过移动端开发经历的开发者都深有体会:移动端IM的开发,与传统PC端IM有很大的不同,尤其无线网络的不可靠性.移动端硬件设备资源的有限性等问题,导致一个完整的移动端IM架构设计和实现都充满着 ...

随机推荐

  1. Unity - UIWidgets 7. Redux接入(二) 把Redux划分为不同数据模块

    参考QF.UIWidgets 参考Unity官方示例 - ConnectAppCN 前面说过,当时没想明白一个问题,在reducer中每次返回一个new State(), 会造成极大浪费,没想到用什么 ...

  2. 苹果电脑开不了机,mac时间机器备份加速,以及识别不到u盘的方法

    平淡无奇的一天,上班后,我按照正常流程,揭开我亲爱的mac的盖子.屏幕没有如昨天一样照亮我的脸庞,擦,电用完了吗? 我充上电,半小时后,电池都热了,依然开不了机.打售后电话,售后姐姐亲切的指导各种我使 ...

  3. Ubuntu18虚拟机远程开发

    Ubuntu18 虚拟机远程开发 1. 安装 VMware 和 Ubuntu18 虚拟机 (1)VMware 官网上下载免费版本 一路 next 安装就行(中间也许需要改一下存放路径) (2)Ubun ...

  4. promise时效架构升级方案的实施及落地

    一.项目背景 为什么需要架构升级 promise时效包含两个子系统:内核时效计算系统(系统核心是时效计算)和组件化时效系统(系统核心是复杂业务处理以及多种时效业务聚合,承接结算下单黄金流程流量),后者 ...

  5. OPC 协议数据采集

    kepserver   OPC Connectivity Suite 让系统和应用程序工程师能够从单一应用程序中管理他们的 OPC 数据访问 (DA) 和 OPC 统一架构 (UA) 服务器.通过减少 ...

  6. 【源码系列#02】Vue3响应式原理(Effect)

    专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核推荐 欢迎各位ITer关注点赞收藏 Vue3中响应数据核心是 reactive , reactive 的实 ...

  7. Python——第五章:处理异常try、except、else、finally

    处理异常try 和 except 在 Python 中,try 和 except 语句用于处理异常(错误).通过使用这两个关键字,你可以编写代码来捕获和处理可能发生的异常,以保持程序的稳定性. try ...

  8. Python——第一章:数据类型介绍

    数据类型: 区分不同的数据.不同的数据类型应该有不同的操作 数字: 做加减乘除+-*/ 整数,int 小数,float a= 10 #整数 b = 20 print(a + b) #加法运算 c = ...

  9. 小姐姐用动画图解Git命令,一看就懂!

    无论是开发.运维,还是测试,大家都知道Git在日常工作中的地位.所以,也是大家的必学.必备技能之一.之前公众号也发过很多git相关的文章: Git这些高级用法,喜欢就拿去用!一文速查Git常用命令,搞 ...

  10. Pikachu漏洞靶场 Unsafe Filedownload(不安全的文件下载)

    不安全的文件下载 概述 文件下载功能在很多web系统上都会出现,一般我们当点击下载链接,便会向后台发送一个下载请求,一般这个请求会包含一个需要下载的文件名称,后台在收到请求后会开始执行下载代码,将该文 ...