2007年十一月月 发布的文章

读'代码修改艺术',可观其大略

早在几个月前就从网上下载到了"Working Effectively With Legacy Code"这本书的E版,之所以下这本书是因为看到了"Legacy Code"这两个单词了,说实话当时我并不知晓这本书的价值,只是想当然的认为:这本书可能会有助我改善我所从事的项目中的"Legacy Code"。早在上个月去逛书店时,就看到了书架上的这本"修改代码的艺术",遗憾的是没有给予足够关注。在最近看到这本书译者刘未鹏的博客以及Dreamhead关于这本书的评价后,才又从电脑中找到这本书开始翻看。从与这本书几次"擦身而过"的经历来看,自己识书的能力实在是差劲。

我需要这本书,首先是因为我目前的项目中就有大量大量的"Legacy Code",所以我已经开始迫不及待的想看完这本书了。但是翻看一些后,我觉得作为使用C的开发者独观其大略即可。为什么呢?书中代码多以面向对象的语言Java或C++作为例子代码,很多细节对使用结构化语言的开发者意义不大。毕竟结构化的思想与面向对象的思想有着较大的差别。

作者提出来的修改软件的四个起因基本上大家都是应该认同的:
(1) 添加新特性;
(2) 修正bug;
(3) 改善设计;
(4) 优化资源使用。

同时作者又给出了为了减少修改行为带来的风险而应该考虑的三个问题:
(1) 我们要进行哪些修改?
(2) 我们如何得知已经正确地完成了修改?
(3) 我们如何得知没有破坏任何(既有的)东西?

在第一部分第二章的最后作者给出了一个解决这些问题的算法:
以下算法可以用于对遗留代码基进行修改:
(1) 确定改动点;
(2) 找出测试点;
(3) 解依赖;
(4) 编写测试;
(5) 修改、重构。

看完这些我觉得就可以直接进入第二部分了,作者给出了细致的、具体的面对不同情形应该如何去做。建议:在读每一个章节之前先回顾一下自己是否遇到过类似情形,自己当时是如何做的,当时的做法是否有改善的地方,哪些是值得发扬广大的,哪些是应该摒弃的,如果是现在我还会如何去做?之后,再看看Michael Feathers是如何去做的,这样效果应该是很好的。有如下这些情形值得我们去考虑:
(1) I Don’t Have Much Time and I Have to Change It 时间紧迫,但必须修改
(2) It Takes Forever to Make a Change 漫长的修改
(3) How Do I Add a Feature? 添加特性
(4) I Can’t Get This Class into a Test Harness 无法将类放入测试用具中
(5) I Can’t Run This Method in a Test Harness 无法在测试用具中运行方法
(6) I Need to Make a Change. What Methods Should I Test? 修改时应当测试哪些方法
(7) I Need to Make Many Changes in One Area. Do I Have to Break Dependencies for All the Classes Involved? 在同一地进行多处修改,是否应该将相关的所有类都解依赖
(8) I Need to Make a Change, but I Don’t Know What Tests to Write 修改时应该怎样写测试  
(9) Dependencies on Libraries Are Killing Me 棘手的库依赖问题
(10) My Application Is All API Calls 到处都是API调用   
(11) I Don’t Understand the Code Well Enough to Change It 对代码的理解不足
(12) My Application Has No Structure 应用毫无结构可言
(13) My Test Code Is in the Way 测试代码碍手碍脚   
(14) My Project Is Not Object Oriented. How Do I Make Safe Changes? 对非面向对象的项目,如何安全地对它进行修改
(15) This Class Is Too Big and I Don’t Want It to Get Any Bigger 处理大类
(16) I’m Changing the Same Code All Over the Place 需要修改大量相同的代码
(17) I Need to Change a Monster Method and I Can’t Write Tests for It 要修改一个巨型方法,却没法为它编写测试
(18) How Do I Know That I’m Not Breaking Anything? 降低修改的风险
(19) We Feel Overwhelmed. It Isn’t Going to Get Any Better 当你感到绝望时

当你看到这些具体情形的列表,眼前是否浮现出是曾相识的经历呢?"代码修改艺术"应该说是一本实用主义的书,如果你是使用面向对象语言的程序员,那你很幸运,建议你将一本"修改代码的艺术"放在你的办工桌旁,随时翻看、思考和领悟;如果你和我一样是结构化语言的使用者,也没有关系,观其大略,品其思想,细读你兴致之所在。

以上的书中文字的中文翻译部分摘自于刘未鹏的中文译文。

在Solaris上编译Ethereal的注意事项

自从上次'编译Ethereal On Windows'之后,好久没有接触Ethereal了,前期策划的基于Ethereal开发的一个工具的任务就落到了这批来的一个新员工的头上了。第一阶段他在Windows上开发了一个基于Ethereal的插件用于分析CMPP协议之用;第二个阶段我们需要移植到Unix上,我们使用的是Solaris。

目标机器是一个x86的Solaris10的系统,首先是将Ethereal依赖的所有开源包都先装上。开源的唯一不好的一点就是互相依赖太多,像Ethereal这样规模的软件,依赖的包不下十几种。这里我们用的源码包是ethereal-0.99.0。按照常规编译软件包的方法:解包=>进入Ethereal目录=>执行./configure => make。

如果想一次make成功显然是不太可能的。

我的那个新同事第一次make得到如下结果:
libtool: link: only absolute run-paths are allowed,他查找了好久,终于"投降"了。由于是新同事对Unix上繁芜复杂的操作不了解也是情有可原的,亲自出马吧。

我对libtool同样是不熟悉,到网上找答案吧。网上关于这个错误的解释太少了。只能用"only absolute run-paths are allowed"在libtool这个脚本文件里搜索,果然找到了,有两个地方有这样的echo输出。大致检查了一下,基本定位问题所在:在libtool执行的语句中,有类似"-R../lib"这样的参数选项,显然这个"../lib"不是一个绝对路径,我们需要针对这个地方进行一下手工修改。

目标就是Makefile文件。打开Makefile搜寻"../lib",一共有4处,分别在SNMP_LIBS、ethereal_LDADD、tethereal_LDADD和dftest_LDADD的定义中,在其中删除"-R../lib"或者为-R指定一个绝对路径即可。

问题解决,继续Make。还是没有过去,提示:在"/usr/sfw/lib/.libs下找不到libnetsnmp.so",Makefile中明明配置的是/usr/sfw/lib,且该路径下存在libnetsnmp.so,为什么libtool非要到"/usr/sfw/lib/.libs"下找呢?libtool就是这样一个怪脾气,没办法,创建/usr/sfw/lib/.libs路径,并将libnetsnmp.so拷贝进去,在Make这块就过去了。

问题仍然层出不穷,程序在链接tethereal的时候,提示:ld: fatal: Symbol referencing errors. No output written to .libs/tethereal
Undefined                       first referenced
 symbol                             in file
gsm_a_pd_str                        tap-gsm_astat.o
RegistrationRejectReason_vals       tap-h225counter.o
register_all_protocol_handoffs      tethereal.o

继续在网上搜索,还好有类似的问题别人也遇到了,解决方法:将epan/dissectors/.libs/libdissectors.a加到Makefile中多个变量的定义中。下面是详细的修改:
(1)
tethereal_additional_libs = \
        wiretap/libwiretap.la           \
        epan/libethereal.la

=>

tethereal_additional_libs = \
        wiretap/libwiretap.la           \
        epan/libethereal.la \
        epan/dissectors/.libs/libdissectors.a \

(2)
dftest_additional_libs = \
        wiretap/libwiretap.la           \
        epan/libethereal.la \
=>
dftest_additional_libs = \
        wiretap/libwiretap.la           \
        epan/libethereal.la \
        epan/dissectors/.libs/libdissectors.a
(3)
dumpcap_LDADD = \
        $(dumpcap_additional_libs)      \
        -lgmodule-2.0 -lglib-2.0                        \
        -lpcap
=>
dumpcap_LDADD = \
        $(dumpcap_additional_libs)      \
        -lgmodule-2.0 -lglib-2.0                        \
        -lpcap -lsocket -lnsl
(4)
ethereal_additional_libs = \
        gtk/libui.a             \
        wiretap/libwiretap.la   \
        epan/libethereal.la \
=>
ethereal_additional_libs = \
        gtk/libui.a             \
        wiretap/libwiretap.la   \
        epan/libethereal.la \
        epan/dissectors/.libs/libdissectors.a \
这回你再make,哇,编译成功了。

然后敲入make install安装这个ethereal,在Windows上启动Xmanager(trial版),连接到目标服务器,用root登录(如果没有root权限,是看不到网卡的,也就不能进行协议分析了)。进入/usr/local/bin,在这里我只发现了tethereal这个程序,执行起来也没有问题,但是那个图形界面的ethereal哪里去了。翻看install的日志,发现根本没有安装ethereal。怎么回事?

继续网上找答案,很快答案找到了:是否编译安装ethereal是configure决定的。在configure的执行日志我看到:
The Ethereal package has been configured with the following options.
                    Build ethereal : no
                   Build tethereal : yes
                    Build capinfos : yes
                     Build editcap : yes
                     Build dumpcap : yes
                    Build mergecap : yes
                   Build text2pcap : yes
                     Build idl2eth : yes
                     Build randpkt : yes
                      Build dftest : yes

显然Build ethereal : no。网上的理由是:GTK+版本安装不当。从configure日志看到:
checking for GTK+ – version >= 2.0.0… no
*** Could not run GTK+ test program, checking why…
*** The test program failed to compile or link. See the file config.log for the
*** exact error that occured. This usually means GTK+ is incorrectly installed.

这时只能重新检查GTK+,甚至是重新安装GTK+。

搞定这个后,再重新configure,注意别忘了备份上述对Makefile的修改,否则configure会覆盖你的成果。之后的工作这里就不说了。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats