如何设计一个优秀的(C/C++)类库?

引子

2015年3月24日上午10点,我给公司全体工程师发布了该周的技术研讨论主题——如何优雅的导出动态链接库的函数,并在主题的下方展示了我在这个问题上做出的成果——DynamicLib。(有兴趣的同学可以移步《DynamicLib使用手册》详细了解。)我满怀欣喜的向众人宣布,但却被突如其来的不速之客打扰。

首先介绍一下背景,我在公司一直以来都有一个宿敌,大家懂得,谁都看谁不顺眼。宿敌产生的原因多种多样,其实时间过了这么久了,至于为什么当初会成为敌人,可能谁也记不清楚了吧。我是典型的天蝎座性格,睚眦必报,人不犯我我不犯人。所以应该是他在什么地方让我不满意了,所以我懒就懒得理他了。哦,对了,刚来公司的时候他是老板的红人,我以强势崛起的姿态迅速在公司占有一席之地,所以我猜他应该是对我不满的。另外此人感觉比较阴险,说话很喜欢拐弯抹角,不善于分享,这对于我等天蝎来说又是大忌。我们互相看不顺眼也是正常。

我10点发的邮件,他11点左右过来问了我一个问题,为什么DynamicLib会有13个参数的限制?能不能用pair<>解决?其实他提的哪种方法我还真没有试过,但是我非常肯定的告诉他,那样做是不行的。为什么我会这么肯定?首先,我当时在忙,没有时间跟他深聊,所以我有敷衍的成分;其次,我认为他还没有深入了解过DynamicLib,难知其中精髓,那么这个时候他提出的问题有时候会是幼稚的,或者是故意刁难人的,或者是展示他的能力比你强的,我当然不干了;再者说了,我自认为对模板的了解要甚于公司的任何人,各种模板推导、演绎了然于胸,你给我提了一个pair<>这就是你的极限了,殊不知一般化的pair<>其实是tuple<>,tuple<>比pair<>适用性更广(夜郎自大?)。基于以上三个理由(我的脑子转的也挺快的嘛),我认为这哥们是来刁难我的,这从他临走时候的一句话更让我深信不疑,他说,我一直都是用pair<>的,我都用了好久了。呵呵。什么鬼逻辑!我已无力吐槽,各位自己揣摩吧。

好了,如果事情到此结束了,我也就没有必要写篇文章纪念一下了。但是他尽管心思不正吧,但是却给我提了一个好问题,我由此感悟到本文章的主题——如何设计一个优秀的类库?或者说什么样的类库才称得上优秀?下面,我就详细的阐述一下我在这个主题上的观点。

如何设计一个优秀的类库?

说实话,在我见过的形形色色的类库之中,作者半吊子水平的不在少数。(原谅我,我不是在进行人身攻击,毕竟谁还没有个年纪轻轻经验尚浅的时候,只是有些库不再更新了。)我认为一个优秀的类库至少符合简单和灵活这两个要求,如果能再实现一把艺术范儿,那就称得上优雅了。

简单

类库的作者一定要弄清楚产品的受众,是刚入门的小白还是经验丰富的老手。但是一般而言,受众的范围越广泛说明类库越有价值。曲高和寡的产品鲜有人问津,最终只能是孤芳自赏了。所以类库最基本的要求是使用简单,接口简单。

其次类库在技术选型、技术实现上也要尽量简单。纯粹的充满了现代C++风格的类库非功力深厚者不能读也,使用宏命令反复嵌套满足少写代码的目的也是不可取的(这一点有兴趣的读者可以探究一下VS2010关于function的实现原理,或者参考《std::tr1::function源码剖析》系列文章)。 所以DynamicLib在类库的实现上没有考虑pair<>也有这方面的原因。

接口简单降低了类库的使用门槛;实现简单降低了对类库探究的门槛。另外,(外部)接口简单应该优于(内部)实现简单。

灵活

对于C/C++类库而言,C/C++语言本身的跨平台、高性能、和其他语言易融合等特点使得它相对于Java、C#等编程语言在类库的实现上更加灵活。所以C/C++类库更应该做到下面几点。

第一,类库支持的平台尽可能的丰富。这一点其实是对C/C++类库可移植性的要求,毕竟通用性更强的代码更容易使广大的C/C++程序员获益。(可见,我是多么的爱C++呀!)比如DynamicLib就支持Windows和Linux至少两种系统(其他系统还没有测试过,支持Mac系统也仅仅只需增加几行代码)。

第二,类库支持的编译器版本要尽可能的低。对编译器要求低也就意味着更多的人能够使用,在实际生产环境中诸如VS和GCC等开发工具并不会频繁的升级。另一方面,编译器的版本低也意味着对于技术的选择相对简单,因为很多新的语法特性是不能被支持的,但是这恰恰也满足了对于实现的简单性要求。比如DynamicLib就支持VS2010以上及GCC3.4以上的编译器,而且在实现的细节上并未追求依赖新编译器特性的不定参数模板、模板函数支持默认参数等在VS2013甚至VS2015上才能实现的语法特性。

第三,类库应尽可能的和其他的类库或者框架进行配合。这并不是说它们之间是强耦合关系,恰恰相反。有些类库产生的原因可能就是某些框架使用起来非常不容易,所以在该框架之上封装了一下,提供一种简单的使用接口。然后在类库的演进过程中,又逐渐摆脱了原有框架的束缚。这样的类库使用起来当然更加灵活。

优雅

能够满足上面两个要求——简单和灵活——的类库足以称得上优秀,但是我个人认为这还不够。代码风格、命名习惯等在我们刚进入编程行业就经常被人反复提起、反复要求,为什么?多少类库中自动生成工具生成的垃圾代码仍然存在,多少类库中大段大段的注释代码还没有被删去,多少类库中拷贝粘贴的痕迹是那么的明显……

所以我个人认为,如果优秀的类库在细节处理上表现同样精彩,那么它就是优雅的。以DynamicLib为例,函数调用的时候需要显式的指明一个模板参数且这个模板参数看起来和函数参数又一点关系也没有(如a.A<_Null>(3,4)),为什么?诸位肯定会非常奇怪。实际上对于函数参数大于等于1的情况这个模板参数是可以通过模板参数演绎的方式获得的,但是当函数参数为0时,因为没有参数所以不能进行模板推导。为了和参数为0的使用形式一致,我决定还是使用统一的调用方式好了。虽然可能觉得很怪异,但是在对于技术的妥协之中是不是又包含着另外一种美的感觉呢!

总结

优雅更多的是个人感觉。不优雅的类库也未必不能称得上伟大!


转载于:https://my.oschina.net/lvan100/blog/392471

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值