All Stories

IDE需要什么功能

  在网上看到一个英文博客,有一篇文章作者谈到他希望一个代码编辑器,或者一个IDE应该有什么样的功能。看了之后感觉还算比较客观,基本没有特别个性化的要求,对于要做这方面工作的人很有参考价值。

扩展性和通用性

  这两天在想一些问题,怎样构建一个有足够扩展性和通用性的框架呢?  对Scintilla的使用有了一点经验后,就想好好利用它来做几个有点实用价值的东东,关键就在于想做的不止一个,但在文本编辑方面由于都是使用Scintilla,所以肯定会想到如果能让代码写得足够通用,所有工程都共享一个代码实现就好了,以后即便有了修改,只要修改一次,其他的最大程度上只要重新编译链接一下就可以了,不用再修改源代码。但这样的通用性要如何实现呢,组件化是一种常见的解决方案,这里Scintilla已经是一个现成成熟的组件,但它只是提供了最基本的能力,如果要把这些能力展现出来,还是自己写代码实现。  有鉴于Impeller项目越来越冗长庞杂的实现,我心里很是不舒服。它确实有那么多事要做,也许有些事不是它的责任,但那也只是极小一部分,但把所有事的实现都放在工程中用C++完成,我就觉得有待商榷了。比如有很经典的一段代码,用于在用户动作触发时,在当前光标所在位置插入日期和时间,这样微不足道的功能,花了好几十行C++代码。其实在大半年前,我还在维护编辑器模块时,我就想通过脚本来支持这些简单功能了,但后来因为这样那样的原因最终没有实现。这只是一个简单的例子,照我的想法,最理想的方案是程序从配置文件中读出相关扩展信息,根据配置在主菜单、工具栏、弹出菜单等用户最习惯的界面上添加可触发控制,当用户触发了这些控制时,程序从配置中读出需要执行的动作,可能是一段脚本,或一个脚本文件,或一个DLL导出函数,甚至是一个COM组件中的一个接口中的方法,总之在被触发前这些东西可是是实际不存在的,也即Eclipse提倡的懒加载规则。这里有几个实现上的难点,如何通过配置文件就动态地实现配置的用户界面;如何通过用户动作立即找到正确的执行动作;如何让主程序和扩展进行交互。一般说来主程序需要提供一些方法供扩展进行调用控制主程序的行为,于是有相应的问题是主程序通过什么方式暴露这些方法,又需要暴露哪些方法。如果这些问题都能解决了,还有另外一个问题,不同的扩展之间是否可以交互,它们的协议应该怎么设计。  总之在动手做那几个东东前,这扩展性和通用性的问题必须要有一个可靠可行的方案,不解以后自己得累死。

从文本编辑转向图形编辑

  看了一点SciTE的代码,因为从SciTE可以看到Scintilla控件的各种使用方法,说起来Impeller也使用的Scintilla,但是总感觉很弱,比如SciTE可以同时直接支持UTF-8和ANSI编码的文件,而Impeller就不行,一个时刻只能支持一种,另一种编码的文件打开时,如果有中文之类的多字节编码符号,就会显示成乱码。  似乎我是不会被调回去做编辑器模块的工作了,可能要我去做图形编辑方面的事了,版本计划中下个大版本需要加入像Rose那样的UML类图编辑功能,不禁要感叹,他们的野心还真大,唉,Visio这样的工具全世界也没有几个呀!  我现在是陷入项目泥潭了,正是有这样大野心的领导,才会让我等小兵异常痛苦,尽提些高难度高技巧的需求,还总以为很简单很容易实现,却并不考虑用户可接受程度。又听到一个新的需求,说是要求所有工具都能自动安装到部门每个员工的电脑上去。那要是人家不愿意呢,又该怎么办!技术上是没有多少难度的,关键是使用者的抵制情绪如何抚平。  想想我转去做图形编辑方面的工作对我自己来讲是件大好事,本来对文本编辑部分已经有了一定的基础,以后就是自己钻研扩展了,现在趁工作的机会再学习图形编辑,对我以后极有好处啊。刚开始听到这个消息时,心里还略有点失落的,现在想起来,觉得这简直是上天对我的恩赐啊,哈哈!

让自己的数据结构支持std::for_each了

  经过几个小时的努力敲打键盘,终于让自己的数据结构支持std::for_each了。昨天我是过高地估计了其实现难度,其实看看for_each的实现代码,非常简单的算法,只要能让iterator支持前置++和提领(这是jjhou的叫法,就是对指针取值)操作符即可。这些内容昨天就知道了,但是自己没有动手做完前,总是心虚的。  实现过程基本上还算顺利,虽然老是编译不过,但VC的提示信息很详细,准确性也很好。在这个任务中,我觉得最好iterator不知道指向的类型,STL就是这样做的,也不是为了什么软件工程或者代码美感方面考虑,而是这样做对于实现者来说似乎更容易理解。  我在中间也犯了个比较严重的错误。因为NodeList已经被封装成一个类了,而我的设计里,iterator需要保存对NodeList的引用,所以我就很习惯成自然地用这个封装类了,另一方面,因为需要,NodeList封装类中也需要这个iterator类型,于是就成交叉引用了,编译都过不了。后来才想到,在iterator中使用封装类并没有得到多少好处,反而似乎增加了实现复杂度,直接用MSXML中的原始类型就行了。  嗯,略有收获,呵呵!

让自己的数据结构支持std::for_each

  今天看到代码中有很多处遍历XML DOM的NodeList中所有元素的操作,同事用MFC的CString在MSXML上面又加了一层封装,使得MSXML用起来更加方便,但在这个NodeList的封装上,遍历操作只有通过next方法,或者以索引号遍历,我开始用他这个封装时抄的他的代码,都用while循环next方法来遍历,现在看多了,就觉得不爽了。刚好这个项目中因为用了Boost中的bind和lambda库,所以大量用了std::for_each算法,于是就想这里的遍历操作是否可以转换成用std::for_each来实现呢?  以前没做过类似的扩展STL的事,所以没有经验,不知从何开始。看了一下几本经典的STL相关的书,大概了解到要自己写个iterator类,这个类需要能支持++、--等操作符,然后NodeList的封装类也要加一些STL风格的方法,比如begin、end、size、empty等。虽然已经有所了解,但动手的时候还是没什么思路,搞了一个下午,也只弄了一点点,还没涉及到核心部分。  我对STL、GP的了解还是太少了,真应该好好学习一下,毕竟仔细想想我还没能非常熟练地掌握并使用一种语言及它主要的程序库,现在看来我只有对C/C++稍微有点基础了,但对标准库的了解却很肤浅,虽然之前也一直要用C/C++写代码,但是没怎么使用标准库,现在在重构等思想的熏陶下,不自觉地希望写出优雅清晰的代码来,好好使用标准库正是其中一种方法。

iPhone真炫

  今天跟公鸡去华强北看手机,主要看了iPhone,让老板拿出真机来体验了一把,还真是爽。爽的有几个原因,一是屏幕特大,这就让看惯了小屏幕手机的我觉得特别大气,虽然在很多机器里N73也不算小了,不过到了iPhone面前还是小巫见大巫了。二是里面的应用程序比较丰富,多媒体娱乐上网等功能都有现成的程序。三是界面比较漂亮,这是苹果一贯的作风,不过也确实漂亮,弄得我曾经把N73上的主题都换成iPhone的了,呵呵。四是它支持WIFI,这样就可以通过我的无线路由器直接上网啦,不用什么GPRS了,不但省了钱,也许速度也更快呢!  除了这些吸引我的特点以外,还有其他特性也是很安逸的,比如据说苹果将在3月份发布官方的SDK,这样就可以自己写程序来玩啦,这点也许是本质上最吸引我的吧,虽然我可能实际上永远都不会动手去写它的程序,但这样官方的支持,对于第三方应用软件的发展,是极有利的,不难想像将来iPhone上的应用程序将遍地开花,呵呵。  因为iPhone并不在中国大陆上市,所以在华强北看到的都是水货,今天问的价格最便宜的,8G存储容量的3750,真是太有诱惑力了,实在有点忍不住想买的冲动啊。不过最近手头太紧了,已经快要去喝西北风了,呵呵。

发现自己兴趣转移了

  这几天回顾了一下,发现自己兴趣转移了,对那些重构、敏捷开发、设计模式这类主题感兴趣了,反而对以前似乎很有兴趣的纯语言技巧之类的东西没什么兴致了。本来我也不会注意到自己有这样的变化,只是最近在找书看的时候,不知不觉地不想看那些语言的高阶技术书籍了,也许是自己写代码的数量到一定量的时候,就会有这样的转变吧,就会潜移默化地开始关注设计问题了。  今天先在图书馆网站上看到有《重构》中文版了,马上跑去,终于借到了,哈哈,真开心啊!简单快速地浏览了《重构》的目录,发现这书很值得从头到尾细细看看,里面讲述了各种类型的bad smell,还有几十种相关的refactoring方法,我自己觉得对于我现在的水平应该有很大帮助。今天又发现,VAX1559版里已经集成了比较实用的重构功能了,真是太好用啦,原来只是用一下它的rename,今天才明白,其余的这些功能都很有用,大大简化了重构操作。配合Source Monitor的度量功能,重构简直是一种享受!  看了几页《重构与模式》,很遗憾地发现,要先懂重构,懂设计模式,再来看这本书才能有所收获,不然就是一头雾水啊。所以,先好好看《重构》,还有《设计模式》和《设计模式精解》,这就作为最近一段时间的学习计划吧!

该死的ADO,该死的SQLServer,该死的XML

  当时还为自己的设计沾沾自喜、得意洋洋,觉得这样的想法、这样的灵感、这样的架构简直就是神来之笔,谁知结果带来的是无休止的崩溃,找不到原因的异常!  因为需要对流程支持历史版本,也即如果新的流程里删掉了旧的里的活动,但活动里又有关联内容时,流程图在显示的时候,需要把表示活动的图形也显示出来,而boss又认死了excel这个东东,所有流程图的内容都要在Excel中编辑完成,可Excel里又没有记录修改动作历史,于是乎,我的设计隆重登场了。我先把Excel中的内容转换成XML保存下来,然后当Excel有了变化,再分析一遍转化成XML,跟原来的XML比较合成一把,这样似乎就能在那么丑陋的设计中以自以为比较优雅的方式实现这个需求了。结果问题也来了,原来的数据表结构要修改,需要为每个流程记录增加一个存放这转化后的XML内容的字段,而恰好MS SQL Server 2005中有那么一个叫XML的字段类型,于是欢天喜地、兴高采烈地用上了,于是又花了一天才勉强做得像以前已经完成的那种程度。因为XML里可能有各种字符,而且可能非常非常长,所以用合成SQL语句来insert、update、select是很难受的做法,又出于我对ADO的不熟悉,好不容易找到设置Field的Value属性的方法,结果在存放、获取XML数据里花了我今天近一天以及之前的那些时间!  在写入XML时就陷阱重重,第一条xml处理指令的存在就很可能引起崩溃,简单说来,我保持了GB2312的编码方式,里面有中文,它就不让我写进去,一update就崩溃,现在想来,也许用UTF-8不会有这样的问题,嗯!但我还是作了个很恶心的决定,要写入之前,跳过前面的这条指令!接着在取出时,总是会在后面加入一堆乱七八糟的东西,又花了好多时间,最后决定,自己在字符串中查找结束标志,之后的全部丢弃,才好不容易让MSXML的DOMDocument接收了,而且是不能让它直接load文件,得自己把文件里的内容读出来,加上那个xml处理指令,再loadXML,晕死!  不容易啊,不过也算是经验教训了,下次再遇到这样的事就应该能省很多时间,不过我猜下次的机会不多了,不已经烦透了,我要去做其它的东西去。可能还是会让我去做Impeller的部分工作吧,我要让它支持灵活的外部扩展,我要让Source Insight消失!

ADO操作数据库还真麻烦

  有点像标题党,呵呵,如果这样的东西放在csdn之类的地方,说不定会引来一大堆人的口诛笔伐,不过这真是我今天的感受啊!  早就烦透了用C++通过COM接口使用ADO来操作数据库了,不得不为那些先人们的艰苦生活感到可怜了。如果没有ADO,我的生活肯定不知比现在悲惨多少倍呢!  但是现在我也是感到苦恼气愤,为什么SQL Server会有这么多不同的字段类型,却使用了同一套表达能力极为有限的API和SQL语法。今天也就只花了一点时间来写代码,结果全都花在这个引起的问题上去了,而且到现在都没解决,郁闷!  恶心死啦!