随笔 - 53, 文章 - 0, 评论 - 3, 引用 - 0
数据加载中……

Unix下读源代码的一点体会.

最近开始在Unix下读一些源代码.下面是一点体会.
1. 工欲善其事,必先利其器
我开始的时候是用find xargs 和 egrep 配合来搜索关键字, 看代码的效率很低.后来装了ctags,方便多了.最初没有装ctags, 是因为觉得可能装起来费劲, 其实还是很容易装的,也就是那么几步, google一下就搞定了.

2. 要及时实践.
虽然开始是读代码的方式比较笨,不过这种干劲非常有用,只有动手实践了,才有可能取得进步.否则的话,我可能还是停留在阅读书本上代码的阶段.

3. Unix下的工具看起来不如Windows的工具异用.其实不然,可能是门槛搞一些.多数人象我一样因此不敢去碰它.入门以后,会发现其实Unix下的工具真是短小精悍. 就拿VIM + Ctags 阅读源代码来说,觉得性价比高.符合80/20原则.

posted @ 2008-03-28 17:39 InPractice 阅读(193) | 评论 (0)编辑 收藏

今天发现Spring居然不跨文件检查重复的Bean配置

如题。
同名的Bean配置两次。根据配置文件的载入顺序,后定义的Bean生效。
看来还得自己小心,不能过于依赖Spring自己的检查机制(只能在单文件中检查重复的bean配置)。

posted @ 2007-10-20 07:56 InPractice 阅读(351) | 评论 (0)编辑 收藏

包结构命名的新方法

J2EE项目中基本都是遵循分层架构的,自然包结构也是基于分层的。DAO层有DAO package。service 层有service package。在这些包下面再根据模块划分子包。

我觉得另一种可行的方案是根据模块划分包,如果包比较复杂,比如有超过十个的类,再根据层来划分子包。一般的模块比较简单,无需划分子包。

从高内聚,低偶合的原则来说,这样划分具有更高的内聚性。如果按层划分。其实同层的类并入多大的关系。考虑一下DAO层。这些DAO之间有多少联系?

新划分方法的好处是如果需要修改某个模块,修改的地方相对集中。因为都位于一个包内。

现在分层架构已经非常普遍,没有必要在包的划分上体现分层架构。在类名上体现分层架构即可。就是说分层架构无需通过包结构来体现。

新的划分方案可能有一个问题。各个模块之间可能有实现上的冗余。如果采用这个方案,需要在这点上采取预防措施。

当然这还是想法,没有在项目中实践。希望大家能指出这个方法可能带来的问题。

posted @ 2006-04-01 09:26 InPractice 阅读(587) | 评论 (0)编辑 收藏

最近看了一些项目代码. 一点感想

最近看了一些项目代码,了解了它得架构和设计。基本上很佩服。因为这些代码是几年以前写的。但是很多书中提到的模式,原则都得到了运用。但是也有一些地方有不同看法,我觉得很多地方用得并不恰当。
1. 滥用继承。比如在类结构中已经用了模板模式,照理说子类按照需要覆盖模板中的实现即可。可是不知出于何种目的。有的子类却是抽象的,需要从该抽象子类再次扩展,导致继承树不必要的深。
2. 滥用接口。经常看到接口中定义了一堆的方法,而且该接口只有一种实现。这种接口纯粹是摆设,这样的接口根本不能指望它有稳定性。实际情况是接口将随着实现的改变而改变。你说要这样的接口干吗?
3. 喜欢抽象出框架,但是这些框架对于当前的应用来说真实不必要的复杂。事实上没有增加重用,反而降低了代码的可读性。
4. 滥用工厂模式。大家不是觉得模式很难实际运用吗。真想用模式吗?那还不简单。给每个对象都定义一个工厂类不就的了吗?说心里话,我真看不出那些工厂模式到底实现什么设计上的好处。
5. 抽象的能力不够。在一个分页的实现中。把查寻字符串抽象到了一个类中。正确的方法应该是把查询结果抽象出来。
项目在进化的过程中很容易变得越来越难维护,毕竟很多不同的思想和不同人的代码揉和到了一起。出现各种问题也是正常的。
希望在别的项目中能引以为戒。


posted @ 2006-03-31 21:36 InPractice 阅读(199) | 评论 (0)编辑 收藏

今天成功的完成了一个游戏--孔明锁

今天成功的完成了一个游戏--孔明锁

简单的说,道具就是六根长方形木条, 其中五根都是有榫头的, 另一根则是直木.
这六根木条最终搭成三个方向互相穿透的立体形状.

这个玩具我上个周末在黄山买的.试过四次, 一直没有成功.
今天吃过晚饭, 无意之中和老婆合作完成了.

基本上,我的分析能力还是可以的. 能够抓住要点.
但是动手能力不如我老婆, 眼看就要成功的时候,还是老婆眼疾手快, 完成最好一块.

其实刚玩的时候, 我就总结出一些基本要领.尽管不是成功的法则.但是能避免不必要的失败

1. 要以唯一的一根直木为思考的出发点.

2. 有两个方向各有两个木条和该直木相交. 其中一个方向需要居中的榫头(刚开始只是总结出这点).
另一个方向需要偏左或者偏右的榫头(今天才总结出这个要点).

3. 分析已经有的木条榫头的形状, 合理的组合不到20种.

4. 通过手工试验. 再摸索出一些规律, 养成空间的感觉. 半个小时应该可以完成.


我很少写Blog.为什么今天例外了.
因为我需要一些东西来证明自己的智商还在. 我说的智商是与具体知识不太相关的一种能力.
都说成功离不开自信. 自信不仅仅是一种信念. 应该通过对自己能力的检验来建立自信.

posted @ 2006-03-31 21:01 InPractice 阅读(819) | 评论 (1)编辑 收藏

如何减少软件的BUG?

每次项目结束,都会发现有一堆的Bug。如何分析这些Bug,避免重蹈覆辙。

有两种分析方法, 根据Developer在修复Bug时选择的CommonCause,选择比重最大的CommonCause,

然后从各个方面分析RootcCause。总结出可以改进的地方。

我很难理解这种方法,主要是觉得每次都是泛泛而谈,对减少BUG没有真正的帮助。


(我确信这种分析方法没有太大的意义,因为缺乏对底层原因的了解. 而且Developer在选择common Cause的时候完全可能没有合适的而任选一个.经常看到的一个例子是缺乏UT. 这个就不一定是真正的原因,事实往往是做了UT却没有发现出Bug.这种分析方法是典型的不深入实际的浮夸作风, 依赖统计的数据而没有看到统计数据事实上可能存在问题. 这样的工作肯定效率不高. )


下面是我的一些思考。
分析的基础应该是Bug,而不是commonCause。直接从CommonCause开始分析,至少可能遗漏一下重要有价值的发现。
有些Bug是有可能避免的。而有些bug可以说没有什么好的对策。我们应该集中分析有可能避免的Bug。
至于如何分析具体Bug是否能避免,首先应该是造成该Bug的Developer自己分析,让大家知道Bug是如何形成的,然后由大家集体决定。(这样做的风险是大家能否接受。)
其次根据Bug引入的时间,和最终测试出的时间,总结有没有可以改进的大方。
能够由developer改进而消除的Bug。是最有希望避免再次发生的。
比如,有些bug是打字错误造成界面上显示的内容有瑕疵,一个可行的改进是每次都从需求文档拷贝。
注意必须要有措施能保证该经验能被所有Developer知道。
另一个例子是,我有一次,是的,我有一次再修正bug是没有清除彻底。在总结的时候我掌握了全局查找、替换的技巧。有效地避免了类似的错误再次发生。

并非所有错误都能由devloper来消除,有一些只能由Tester来消除。比如,一般来说,Tester总是比Developer对界面敏感,更能发现界面bug。
我觉得随着单元测试的进步,现在对Developer的测试水平的要求也提高了。这也许不尽合理。developer对实现花了很多精力,他不可能在测试上达到同样的水准。

posted @ 2006-02-19 18:01 InPractice 阅读(623) | 评论 (0)编辑 收藏

Throw away unnecessary interface!

Why we need Interface? The most important benefit come from the fact: The code depend on the interface no need to care about the implementaion class. and if the implementation class is changed later, the client code no need to update.
This is the feature of Ploymophism of OOP, such as Java. 

In some projects, the struts framework was adopted, so all the field need to be persisted is in ActionForm. In order to avoid that the Service layer /DAO layer will depends on the struts. One way is to define a interface which have getter and
setter to access all the fields need to be persisted. The design is like this:

XXXActionForm --------> XXXInterface <--------------ServiceLayer/DAO Layer
                                          most of them are 
                                          getter and setter
 
I can understand this concern, it seems follow the paterns in Enterprise Application Architecture Pattern. but I can not agree this kinds of design. I believe this is misuse of interface.

First, in this kinds of design, if we add some fields, we need update the actionForm, them also need to update interface.
It is boring, and in this case, the interface can not provide any abstraction so the interface need to evolve as the implementation changed.

Second, there is only one  kind of implementaion in the system, so the interface can not provide the benifit from making use of polymorphism.

In a word, we can get nothing design benefit from Interface in this case, And Have burden to keep the implementaion and interface synchronized.

posted @ 2006-02-19 17:30 InPractice 阅读(264) | 评论 (0)编辑 收藏

Solaris 的 sort 有问题

今天我用Solaris的sort命令排序如下内容。
 <ref bean="NoteDDO100"/>^M
 <ref bean="NoteDDO101"/>^M
 <ref bean="NoteDDO102"/>^M
 <ref bean="NoteDDO103"/>^M
 <ref bean="NoteDDO104"/>^M
 <ref bean="NoteDDO105"/>^M
 <ref bean="NoteDDO106"/>^M
 <ref bean="NoteDDO107"/>^M
 <ref bean="NoteDDO108"/>^M
 <ref bean="NoteDDO109"/>^M
 <ref bean="NoteDDO110"/>^M
 <ref bean="NoteDDO111"/>^M
 <ref bean="NoteDDO112"/>^M
 <ref bean="NoteDDO113"/>^M
 <ref bean="NoteDDO114"/>^M
 <ref bean="NoteDDO115"/>^M
 <ref bean="NoteDDO116"/>^M
 <ref bean="NoteDDO117"/>^M
 <ref bean="NoteDDO118"/>^M
 <ref bean="NoteDDO119"/>^M
 <ref bean="NoteDDO120"/>^M
 <ref bean="NoteDDO121"/>^M
得到的结果如下:
 <ref bean="NoteDDO121"/>
 <ref bean="NoteDDO119"/>
 <ref bean="NoteDDO118"/>
 <ref bean="NoteDDO117"/>
 <ref bean="NoteDDO116"/>
 <ref bean="NoteDDO115"/>
 <ref bean="NoteDDO114"/>
 <ref bean="NoteDDO113"/>
 <ref bean="NoteDDO112"/>
 <ref bean="NoteDDO111"/>
 <ref bean="NoteDDO109"/>
 <ref bean="NoteDDO108"/>
 <ref bean="NoteDDO107"/>
 <ref bean="NoteDDO106"/>
 <ref bean="NoteDDO105"/>
 <ref bean="NoteDDO104"/>
 <ref bean="NoteDDO103"/>
 <ref bean="NoteDDO102"/>
 <ref bean="NoteDDO101"/>
 <ref bean="NoteDDO120"/>
 <ref bean="NoteDDO110"/>
 <ref bean="NoteDDO100"/>

请注意粗体的内容, 看到这样的结果,我觉得真是不可思议。
有谁能解释一下吗?或者这是solaris的Bug。

posted @ 2005-10-21 09:47 InPractice 阅读(300) | 评论 (0)编辑 收藏

programming to interface 之我见

Programming to Interface 是OOD的基本原则之一。
但是不等于说只要应用了Interface就符合Programming to Interface的原则。
我对以下使用Interface的情形有不同看法。
为DDO建立一个接口(Interface)。然后当DDO跨层使用时,我们用该接口作为参数类型。
我认为这是没有意义的,根本实现不了Programming to Interface 的初衷。
1. Programming to Interface 的好处之一是可以为不同的实现提供统一的接口。但是这个案例中,只有一个DDO,对应这一个Interface。
2. Programming to Interface 的好处之二是当实现改变时,interface可以保持不变。这样Programming to Interface 部分的代码就可以不用随实现的改变而改变。但是这个案例中,一旦DDO发生了改变,Interface也需要发生改变。
总之,这这种情形下,增加一个接口纯属多余,没有增加任何价值,反而增加了维护接口的麻烦。
这也说明正确应用Programming to Interface 是多么重要。否则再漂亮的法则一旦滥用,误用,不仅没有任何好处,而且可能造成额外的负担。
造成这种误用的关键原因是,DDO并非一种理想的Object,getter和setter没有足够的抽象程度,不能提炼成接口。勉强用上接口也是徒劳的。

posted @ 2005-09-20 21:28 InPractice 阅读(251) | 评论 (0)编辑 收藏

安装Eclipse插件

今天成功的安装了Eclipse的UML插件。
要点如下:
1. 在eclipse下建立links目录,之下再建立任意文本文件如links.txt,内容为
PATH=.<插件所在目录>
2. 如果Eclipse启动之后没有自动识别到新的插件。删除eclipse下的configuration 下除了config.init外的所有文件。如果误删config.init文件,则Eclipse不能启动。

posted @ 2005-09-20 17:30 InPractice 阅读(247) | 评论 (0)编辑 收藏

仅列出标题
共6页: 上一页 1 2 3 4 5 6 下一页