快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

www9778con:提高Java代码可重用性的三个措施



作者:松下客

本文先容了三种改动现有代码前进其可重用性的措施,它们分手是:改写类的实例措施,把参数类型改成接口,选择最简单的参数接口类型。

步伐一:改写类的实例措施

经由过程类承袭实今世码重用不是正确的代码重用技巧,是以它并不是最抱负的代码重用机制。换句话说,假如不承袭全部类的所有措施和数据成员,我们无法重用该类里面的单个措施。承袭老是带来一些多余的措施和数据成员,它们老是使得重用类里面某个措施的代码繁杂化。别的,派生类对父类的依附关系也使得www9778con代码进一步繁杂化:对父类的篡改可能影响子类;改动父类或者子类中的随意率性一个类时,我们很难记得哪一个措施被子类覆盖、哪一个措施没有被子类覆盖;着末,子类中的覆盖措施是否要调用父类中的对应措施无意偶尔并不显而易见。

任何措施,只要它履行的是某个单一观点的义务,就其本身而言,它就应该是首选的可重用代码。为了重用这种代码,我们必须回归到面向历程的编程模式,把类的实例措施移出成为全局性的历程。为了前进这种历程的可重用性,历程代码应该象静态对象措施一样编写:它只能应用自己的输入参数,只能调用其他全局性的历程,不能应用任何非局部的变量。这种对外部依附关系的限定简化了历程的利用,使得历程能够方便地用于任何地方。当然,因为这种组织要领老是使得代码具有更清晰的布局,纵然是不斟酌重用性的代码也同样能够从中获益。

在Java中,措施不能离开类而零丁存在。为此,我们可以把相关的历程组织成为自力的类,并把这些历程定义为公用静态措施。

例如,对付下面这个类:

class Polygon {

.

.

public int getPerimeter() {...}

public boolean isConvex() {...}

public boolean containsPoint(Point p) {...}

.

.

}

我们可以把它改写成:

class Polygon {

.

.

public int getPerimeter() {return pPolygon.computePerimeter(this);}

public boolean isConvex() {return pPolygon.isConvex(this);}

public boolean containsPoint(Point p) {return pPolygon.containsPoint(this, p);}

.

}

此中,pPolygon是:

class pPolygon {

static public int computePerimeter(Polygon polygon) {...}

static public boolean isConvex(Polygon polygon) {...}

static public boolean

containsPoint(Polygon polygon, Point p) {...}

}

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

在上面这个例子中,篡改代码的终极效果是使得利用Polygon功能的客户代码不必再从Polygon承袭。Polygon类的功能现在已经过pPolygon类以历程为单位供给。客户代码只应用自己必要的代码,无需关心Polwww9778conygon类中自己不必要的功能。但它并不料味着在这种新式历程化编程中类的感化有所削弱。恰好相反,在组织和封装工具数据成员的历程中,类起到了弗成或缺的感化,而且正如本文接下来所先容的,类经由过程多重接口实现多态性的能力本身也带来了卓越的代码重用支持。然而,因为用实例措施封装代码功能并不是首选的代码重用手段,以是经由过程类承袭达到代码重用和多态性支持也不是最抱负的。

步伐二:把参数类型改成接口

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

“……我们经由过程对接口而不是对类编程达到代码重用的目的。假如某个措施的所有参数都是对一些已知接口的引用,那么这个措施就能够操作这样一些工具:当我们编写措施的代码时,这些工具的类以致还不存在。从技巧上说,可重用的是措施,而不是通报给措施的工具。”

在“步伐一”获得的结果上利用Holub的见地,当某块代码能够编写为自力的全局历程时,只要把它所有类形式的参数改为接口形式,我们就可以进一步前进它的可重用能力。颠末这个篡改之后,历程的参数可所以实现了该接口的所有类的工具,而不仅仅是原本的类所创建的工具。由此,历程将能www9778con够对可能存在的大年夜量的工具类型进行操作。

例如,假设有这样一个全局静态措施:

static public boolean contains(Rectangle rect, int x, int y) {...}

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

static publiwww9778conc 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成为它特有的类形式(我们知道它有一个措施可以返回矩形),它意味着措施必须事先知道它所操作的工www9778con具类型,从而使得措施的重用只限于那几种工具类型。而这恰是前面这个步伐力求先行避免的问题!

步伐三:选择最简单的参数接口类型

在实施第二个步伐时,应该选用哪一种接口类型来取代给定的类形式?谜底是哪一个接口完全满意历程对参数的需求,同时又具有起码的多余代码和数据。描述参数工具要求的接口越简单,其他类实现该接口的时机就越大年夜??由此,其工具能够作为参数应用的类也越多。从下面这个例子可以很轻易地看出这一点:

static public boolean areOverlapping(Window window1, Window window2) {...}

这个措施用于反省两个窗口(假定是矩形窗口)是否重叠。假如这个措施只要求从参数得到两个窗口的矩形坐标,此时响应地简化这两个参数是一种更好的选择:

static public boolean areOverlapping(Rectangular rect1, Rectangular rect2) {...}

上面的代码假定Window类型实现了Rectangular接口。颠末篡改之后,对付任何矩形工具我们都可以重用该措施的功能。

有些时刻可能会呈现描述参数需求的接口拥有太多措施的环境。此时,我们应该在全局名称空间中定义一个新的公共接口供其他面临同一问题的代码重用。

当我们必要象应用C说话中的函数指针一样应用参数时,创建独一的接口描述参数需求是最好的选择。例如,假设有下面这个历程:

static public void sort(List list, SortComparison comp) {...}

该措施运用参数中供给的对照工具comp,经由过程对照给定列表list中的工具排序list列表。sort对comp工具的独一要求是要调用一个措施进行对照。是以,SortComparison应该是只带有一个措施的接口:

public interface SortComparison {

boolean comesBefore(Object a, Object b);

}

SortComparison接口的独一目的在于为sort供给一个它所需功能的钩子,是以SortComparison接口不能在其他地方重用。

总而言之,本文三个步伐得当于改造现有的、按照面向工具常规编写的代码。这三个步伐与面向工具编程技巧结合就获得了一种可在今后编写代码时应用的新式代码编写技巧,它能够简化措施的繁杂性和依附关系,同时前进措施的可重用能力和内部凝聚力。

当然,这里的三个步伐不能用于那些生造诣不得当重用的代码。不得当重用的代码平日呈现在利用的体现层。例如,创建法度榜样用户界面的代码,以及联络到输入事故的节制代码,都属于那种在法度榜样和法度榜样之间千差万其余代码,这种代码险些弗成能重用。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: