Posted on 2008-10-29 22:20
非鱼 阅读(3042)
评论(0) 编辑 收藏 所属分类:
面向对象设计 、
Java技术
6. 使用具体的类定义变量
使用具体的类来定义变量,可能导致代码中存在抽象问题。这里所说的变量包括静态变量、实例变量、本地变量、方法的参数和返回值。
更加具体一点说,在组织内部的代码中,如果存在一个类继承关系,并且这个类继承关系中的具体类被用来定义变量,则这里有问题的可能性比较高。我们定义抽象类或接口的目的就是抽象使其脱离易变的实现细节,如果抽象了稳定的接口而不在变量定义中使用它,那还有什么意义呢?
使用具体类定义变量的问题就在于,这通常绑定了实现类而缺乏抽象,难以适应未来需求的发展,难以维护而增加成本。
相对来说,使用具体类定义本地变量的影响是最小的,在可以控制的范围之内;使用具体类定义实例变量和静态变量,如果变量是private的,基本也在可控的范围内。
如果实例变量和静态变量package、protected或public的,需要特别的当心。这时候实际上已经向外界(当前类之外)隐含的“发布”了这些变量,它们可能已经不在你的控制范围之内了。由于封装的不严密并且直接泄漏了具体的、不稳定的实现,极易导致代码在维护过程中的失控,并且给测试带来了困难。如果没有特别的理由,这样的代码是一定要修正的。修改变量的可见性是最好的方式,这要求对变量的使用情况进行检查(现代的IDE一般都支持Find Usage),如果这些变量已经被类外部的代码使用了,修改的工作量会大大增加,同时修改可见性也需要对最初的设计进行重新评估;这样把具体类修改成抽象类或者接口就成为了退而求其次的解决方案。如果时间允许,二者同时进行是最好的,长远来看也是最低成本的。
使用具体类定义方法的参数和返回值也不好,这样做的危险程度是中等的。这使对象之间的通信契约建立在了相对具体的层次上,缺乏抽象而难以适应变化,自然也带来了维护成本的增加。但契约的修改比直接对“隐私”的侵犯稍好一点,并不会带来对内部实现的大规模、不可控的破坏。当然,如果在代码检查中发现了这样的问题,也要尽可能修改。
在代码检查工具的实现上,对具体类定义本地变量、实例变量、静态变量、方法参数和返回值的检查可能是分离的。这样我们也有机会对检查的详细程度进行定制。我个人的观点是,除本地变量之外的情况是一定要检查的。
对于第三方产品来说,也应该尽量使用抽象类和接口来定义变量。不然你就把自己放在了一个比较危险的境地了。而且,部分代码检查工具,可能并不会检查这样的情况。
concrete class, variable, code review, abstraction, visibility