SDK开发技巧&注意事项
SDK结构
两种SDK形式
1. header-only
+- /include
| +- a.h
| +- b.h
| +- c.h
| +- ...
2.header-files+lib
+- /include
| +- a.h
| +- b.h
| +- c.h
+- /lib
| +- libxxx.so
+- /dependencies
| +- libaaa.so
| +- libbbb.so
| +- libccc.so
1. 接口信息暴露
一般,必须暴露出去的接口类,包含以下这些东西
- 插件(管理)(驱动)类
- 输入参数
- 输出参数
class manager {
public:
bool init();
void run(const int &input, int &output);
void destroy();
private:
//...
};
这样的类必不可少,开发时做好抽象,尽可能减少这种类的数量
2. 多个头文件整合
如果上面栗子的manager类,和输入input、输出output分别属于多个头文件,那么开发者需要include三次,可以进行一个头文件整合。使用的时候只需要包换sum.h即可。
//sum.h
#include "manager.h"
#include "input.h"
#include "output.h"
- but,简化调用,缺因为多引入头文件增加编译时间,so需要权衡
3. 简化接口类,隐藏具体的实现类
有时候会遇到这种情况,对外暴露的public方法不是很多,但是private却有一大堆。
//managerImpl.h
class managerImpl {
public:
bool init();
void run(const int &input, int &output);
void destroy();
private:
//... 1000line
};
//managerImpl.h
class Manager {
public:
Manager() {
m_managerImpl;= new managerImpl();
}
~Manager() {
delete m_managerImpl;
}
bool init() {
return m_managerImpl->init();
}
private:
mnagerImpl *m_managerImpl;
}
将具体实现类隐藏起来,外面套一层类,在外面调用具体里面接口,目的达到。
4. 前置声明
如果我们使用了其他头文件中的内容,不可避免的要引用对应的头文件,前置声明则可以帮你摆脱这种窘境。并且可以有效缩短编译时间
//manager.h
class GenInfo; //前置声明
class manager {
public:
void run(GenInfo &info);
};
声明数量较多的时候,可以使用一个头文件统一进行前置声明,用的时候只包含头文件就可以,无需一个一个前置声明。
注意:前置声明只是一个声明,如果只是用了指针,引用这种方式那么可以使用前置声明,如果用到了值类型、继承、对象的方法这些,只能老老实实引用头文件。
5. Readme
注意事项
接口设计
1.接口名称,参数要足够清晰
- 一个好的接口命名可以替代大量注释
2. 一个接口只负责一件事情
- 一个接口只完成一个功能,如果有比较接近的功能,但是用一个接口实现有点麻烦,那就用两个!不要为了特意减少接口而生硬的把两个接口合为一个。
3. 接口参数要尽可能少
- 接口参数要尽量少,能自身去获取就不要让开发者传递参数。
4. 参数校验
- 所有接口的参数都要做合法性校验,不要让别的接口或者开发者去保证调用你接口的参数一定合法
- 所有对外暴露的接口做的第一件事就应该是参数的合法性校验。
- 对于需要转义(换行符等)、或者类型转换等参数,一定要处理!而且是尽早去处理,安全方面的虽然没说要到那种要求,但是不代表就可以不用考虑。
5.名称统一
- 通用名字或者模块叫法,名称要统一起来。
其他
1. SDK应该有一个专门的线程去处理SDK相关操作
- 日志、config等相关模块应该专门有个地方初始化,方便扩展