第三步:选择低耦合的输入参数接口类型 完成第二步之后,应该选择什么样的接口类型来取代给定的类型呢?答案是能够通过参数完全描述过程的需求,同时又具有最少的额外负担的接口类型。参数对象所要实现的接口越简单,其他特定类实现此接口的机会就越大——由此,其对象可以作为参数使用的类也就越多。通过下面的例子可以很容易地看到这点:+ _2 j7 V) L/ ]8 p0 k( K
static public boolean areOverlapping(Window window1, Window window2) {...}( f! X7 K8 t0 H, l# S
这个方法用于检查两个窗口(假定是矩形窗口)是否重叠,如果这个方法只要求从参数获得两个窗口的矩形坐标,那么简化参数的类型使其能反映这个事实是一种更好的选择:, P/ d4 r* j, e) Q" Q3 H- r$ ^
static public boolean areOverlapping(Rectangular rect1, Rectangular rect2) {...}
# j! v- G# `7 i( r6 T. c" M. Z 以上的代码假设先前的Window类型的对象同样可以实现Rectangular接口。现在对于所有的矩形对象,都可以重用第一个方法所包含的功能了。3 a Q% H* m; d! M
你可能多次体验到当一个接口能够完全确定需要通过参数获哪那些内容时,会存在太多不必要的方法。在这种情况下,应该在全局命名空间中定义一个新的公共接口以供其他可能面临同一困境的方法重用。& c: d3 a4 k5 h# G5 B/ {5 Q+ j0 A: C
你可能还会不止一次地发现,在确定需要通过单一过程的一个参数获取哪些内容时,最好创建一个单独的接口。你应该只为这个参数使用此接口。这通常会在你希望如同C语言中的函数指针一样使用参数的情况下出现。例如下面的过程:& D: I$ i$ H# l
static public void sort(List list, SortComparison comp) {...}# x `; `2 j! n {, ^. P3 Q) |" a
此过程使用参数所提供的比较对象comp,通过比较给定列表中的所有对象而对其进行排序,sort对comp的全部要求是调用一个单独的方法进行比较。因此,SortComparison应该是只带有一个方法的接口:
7 \: `: ^; q" _, I public interface SortComparison {8 @/ L8 y* x7 q3 |, u. ~9 J' p. z5 P
boolean comesBefore(Object a, Object b);9 Y7 D) t+ h; ]& w+ g/ X1 e: k
}
% {4 Z& S0 T; I* S5 C2 R8 X8 J 这个接口的唯一目的是为sort提供一个与其完成任务所需功能相联系的钩子(hook),因此SortComparison无法在其他地方重用。
: E& \% m, `- C6 ^3 Z+ ]7 W1 d 结束语/ C5 @' L; w6 w2 F+ ~
以上所述的三个步骤用于现有的、按照相对传统的面向对象方法所编写的代码。这些步骤与面向对象编程技术结合就形成了一种可以运用于今后代码编写中的新方法,它可以提高代码的可重用性和内聚性,同时降低了耦合度及复杂性。. p0 v/ c9 S! ?& C( }
很显然,这些步骤无法运用于那些在本质上就不适合于重用的代码。这类代码通常出现在应用程序的表示层(presentation layer)。例如程序中用于创建用户界面的代码,以及将输入事件与完成实际工作的过程相联系的控制代码,都是属于那种其功能在不同的程序中差别很大的代码,这种代码的重用几乎是不可能的。 |