您现在的位置: 弘智首页 > JAVA > JAVA资料下载 >

关于能提高Java代码可重用性的三个措施(中)

时间:2012-10-31 10:54 来源:未知 作者:zcl

从类的名字pPolygon可以看出,该类所封装的过程主要与Polygon类型的对象有 关。名字前面的p表示该类的目的是组织公用静态过程。在Java中,类的名字以小写字母开头是一种非标准的做法,但象pPloygon这样的类事实上 并不提供普通Java类的功能。也就是说,它并不代表着一类对象,它只是Java语言组织代码的一种机制。

在上面这个例子中,改动代码的最终效果是使得应用Polygon功能的客户代码不必再从 Polygon继承。Polygon类的功能现在已经由pPolygon类以过程为单位提供。客户代码只使用自己需要的代码,无需关心 Polygon类中自己不需要的功能。但它并不意味着在这种新式过程化编程中类的作用有所削弱。恰恰相反,在组织和封装对象数据成员的过程中,类起到了不 可或缺的作用,而且正如本文接下来所介绍的,类通过多重接口实现多态性的能力本身也带来了卓越的代码重用支持。然而,由于用实例方法封装代码功能并不是首 选的代码重用手段,所以通过类继承达到代码重用和多态性支持也不是最理想的。

措施二:把参数类型改成接口

正如Allen Holub在《Build User Interfaces for Object-Oriented Systems》中所指出的,在面向对象编程中,代码重用真正的要点在于通过接口参数类型利用多态性,而不是通过类继承:

“……我们通过对接口而不是对类编程达到代码重用的目的。如果某个方法的所有参数都是对一些已知接口的引用,那么这个方法就能够操作这样一些对象:当我们编写方法的代码时,这些对象的类甚至还不存在。从技术上说,可重用的是方法,而不是传递给方法的对象。”

在“措施一”得到的结果上应用Holub的看法,当某块代码能够编写为独立的全局过程时,只 要把它所有类形式的参数改为接口形式,我们就可以进一步提高它的可重用能力。经过这个改动之后,过程的参数可以是实现了该接口的所有类的对象,而不仅仅是 原来的类所创建的对象。由此,过程将能够对可能存在的大量的对象类型进行操作。

例如,假设有这样一个全局静态方法:

以下是引用片段:
static public boolean contains(Rectangle rect, int x, int y) {...} 

这个方法用于检查指定的点是否包含在矩形里面。在这个例子中,rect参数的类型可以从Rectangle类改变为接口类型,如下所示:

以下是引用片段:
static public boolean contains(Rectangular rect, int x, int y) {...} 

而Rectangular接口的定义是:

以下是引用片段:
public interface Rectangular 
{
Rectangle getBounds();

现在,所有可以描述为矩形的类(即,实现了Rectangular接口的类)所创建的对象都可以作为提供给pRectangular.contains()的rect参数。通过放宽参数类型的限制,我们使方法具有更好的可重用性。

不过,对于上面这个例子,Rectangular接口的getBounds方法返回 Rectangle,你可能会怀疑这么做是否真正值得。换言之,如果我们知道传入过程的对象会在被调用时返回一个Rectangle,为什么不直接传入 Rectangle取代接口类型呢?之所以不这么做,最重要的原因与集合有关。让我们假设有这样一个方法:

以下是引用片段:
static public boolean areAnyOverlapping(Collection rects) {...} 
该 方法用于检查给定集合中的任意矩形对象是否重叠。在这个方法的内部,当我们用循环依次访问集合中的各个对象时,如果我们不能把对象cast成为 Rectangular之类的接口类型,又如何能够访问对象的矩形区域呢?的选择是把对象cast成为它特有的类形式(我们知道它有一个方法可以返回 矩形),它意味着方法必须事先知道它所操作的对象类型,从而使得方法的重用只限于那几种对象类型。而这正是前面这个措施力图先行避免的问题!
(责任编辑:admin)