库设计随笔
一直以来写代码都是拷贝为主,编写为辅。一般都是套用现成框架,自己写一下功能模块。有时候自我感觉良好,写代码也不是多么难的事,不过是把处理流程转换成计算机语言罢了。最近开始自己重头写项目,才发现有那么多烦心事。基本上每个功能都不是什么难事,但是要组装起来还真的费劲。
兼容
我以前还以为c++是跨平台的。直到我打算把我自己在windows下写的代码移植到arduino上。首先我要解释一下我这么做的原因:
- 易于调试
- 可以编写测试用例
- 更好的开发工具
- 我所使用的库是跨平台的,也确实能在我的电脑上使用。所以开始我认为移植起来会很轻松。
总之就是,既然能在电脑上开发运行,为什么要在板子上弄呢?
于是没过多久我就留下了悔恨的泪水。
当我开心地把写好的代码拿去编译的时候,编译器就给了我一个大嘴巴子。满屏都是error,这个说缺成员函数,那个说类型不符。仔细地看了看错误,然后就发现c++所谓的标准库并不标准,每个平台下都有点小差异,缺点东西也正常毕竟单片机平台有限。然后我就想,少什么就加什么呗。
第一次重构 扩展类成员
问题比较大的是string类型。一般我们用的是std::string,但是arduino自己有个String。那么我自定义一个类NString 继承std::string,然后实现一些String的方法;
遗憾的是,编译器再次当头棒喝。ArduinoJson 这种库里面已经针对现有的String或是std::string做处理。具体原因不是很清楚,C++的模板又把问题的难度上升一个台阶。基本情况就是,在原有的第三方库中是使用String的。当我把NString作为模板类型传入时,需要一个String到NString的转换。唯一的方法是在String类里添加一个重载函数。艹!!
第二次重构
我突然发现ArduinoJson自己实现了一套String。看来跨平台的关键是不要用别人的东西。但是当我翻看像string这种常见的类的实现时,我胆怯了。花了不少时间又去看了下模板。坑点太多。最后选择了一个偷懒折中的方案。当使用字符串时,统统取.c_str(),转成const cahr*。当遇到不兼容的成员函数。如find_first_of时,转用函数写法。
即用find_first_of(String&)来解决。
哪里出了问题
如果一开始就用C,或者只用函数而不是类去解决问题,那么代码的兼容问题将大大降低。当然这也不是C++的优势,C++比C更加易用。
易用不易写
如果是调用的话,C++确实比C好用太多了。但是反过来,在使用上占的便宜,加倍地在开发上补回来。为了修改我之前犯的错误,我要来回在好几个有继承关系的类切换做修改。看了一下人家的实现:
class JsonArray : public Internals::JsonPrintable<JsonArray>, public Internals::ReferenceType, public Internals::NonCopyable, public Internals::List<JsonVariant>, public Internals::JsonBufferAllocated
我突然意识到,我就继承一个类,上下连起来就是一条线,这么麻烦搞抽象继承还不如写几个函数指针。真的是任重道远。