• 2012-07-26

    旧瓶装新酒

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-logs/220397545.html

    这个周末,西安OpenParty和QClub,西安葡萄城办公室,《我们身边的语言》。

    我喜欢任何与程序设计语言相关的话题,我喜欢折腾各种代码。所以,这次有机会去分享自己的一些想法,《Be a Polyglot》,简而言之,要学习多种程序设计语言。

    这两天在准备这个演讲所用的PPT,其中有一个观点,让我越想越觉得有点意思:学习新语言,可以把新想法用回到工作语言上。

    举个例子,我见过很多C程序员这样写代码,要实现一个函数,就在头文件里写下函数声明,然后,在.c文件里开始写函数实现。作为一个学习过Java的程序员,经过千辛万苦的锻炼,我知道,我们应该面向接口编程。这时回过头看C,我们完全应该把头文件视为接口,而把对应的.c文件视为实现。这时,我们原有的C世界观就颠覆了。

    如果将头文件视为接口,我们会发现,接口是给别人使用的,所以,出于信息隐藏的考虑,里面的东西越少越好。所以,如果不想给别人使用的东西(函数、变量、宏等等),我们完全不应该放在头文件里。所以,再实现一个新函数时,我们需要先想一下这个函数是给别人用,还是只在这个.c里内部使用。如果是要给别人使用,我们才在头文件里声明,否则,最多是把声明放在.c文件的头上。

    把头文件视为接口,这扇窗一旦打开,改变绝不止这一点。我们继续。

    回想一下Java里的接口,我们便不难发现,接口里放置的只有函数和静态常量,没有变量。为什么?还是从信息隐藏的角度出发,变量就是实现细节,细节就应该隐藏,这样,关于信息隐藏的套话是,你将来修改时不会影响到其它客户端代码。同样,回到头文件的话题上,我们要做信息隐藏,就不要在头文件里声明任何变量,它们同属实现细节,细节嘛,就应该隐藏。

    进一步想一下,在C里面有一个很讨厌的东西,叫做extern。通过extern声明一个函数,我们甚至可以跳过头文件声明,把别的.c文件里的东西拿过来用,事实上,很多懒惰的程序员就是通过这种办法破坏别人的封装。还好,我们还有利器,它叫static。在C里面,static可以让一个函数真正意义上成为局部的,编译成目标文件的过程中,就把函数名消灭了,这样,如果在链接时,那些extern就找不到它们要找的函数了。不过,从信息隐藏的角度来说,这是好的。所以,以个人经验来说,两个方面,不要用extern声明函数,局部函数请用static声明。

    为了进一步引入封装的概念,我一般会建议增加两个宏

    #define PUBLIC
    #define PRIVATE static

    对所有函数都用这两个宏声明,这样,在写代码的时候,你必须考虑一下自己函数的使用范围。

    再回到接口上,其实,在Java里,我们一个类是可以实现多个接口的,这样,一个类可以当做不同接口的对象。反过来,我们也可以做同样的事情,传统习惯上,我们一个.c对应一个头文件,事实上,我们的一个.c文件完全可以对应于多个头文件,比如,有多个不同的模块要调用我们的实现,而它们真正调用的接口又不尽相同,我们完全可以为不同的使用定义不同的头文件,这样,这样不同的项目组之间协作起来也相对容易,客户端程序员理解接口也相对容易一些。

    这就是把新语言的想法用回工作语言的一个想法。实际上,Java也算不上新语言了,我已经开始逐渐探索把其它语言的想法用回到Java里了,有机会再聊。

    如果你对程序设计语言的话题感兴趣,那就一起来吧!

    分享到:

    历史上的今天:

    一较短长 2008-07-26
    引用地址: