概述6 h3 S( l- c/ b* F# d/ j8 K9 z# s
年夜年夜都好的设计者象遁藏瘟疫一样来避免使用实现担任(extends 关系)。€的代码应该完全用interfaces写,不器具体的基类。事实上,四人帮的设计模式的书年夜量的关于若何用interface担任庖代实现担任。这个文章描述设计者为什媚暌剐这样的怪癖的设法。Extends是有害的;也许对于Charles Manson这个级此外不是,可是足够糟糕的它应该在任何的可能的时辰被避开。四人帮的设计模式花了很年夜的部门谈判用interface担任庖代实现担任。好的设计者在他的代滤鱿脯年夜部门用interface,而不是具体的基类。这个文章谈判,为什么设计者会有这样怪癖的习惯,而且也介绍一些基于interface的编程基本。Interface和Class
+ ~, _5 E3 ]1 j6 ^0 T" v 一次,我加入一个Java用户组的会议。在会议中,Jams Gosling(Java之父)做倡议人讲话。在那令人难忘的Q&A部门,有人问他:“如不美观你年夜头机关Java,你想改变什么?”。“我想丢弃classes”他回覆。在笑声平息后,它诠释说,真正的问题不是因为class自己,而是实现担任(extends 关系)。接口担任(implements关系)是更好的。你应该尽可能的避免实现担任。失踪去了矫捷性; E2 T9 F% @% y7 }
为什么你应该避免实现担任呢?第一个问题是明晰的利器具体类名将你固定到特定的实现,给底层的改变增添了不需要的坚苦。在当前的火速编程体例中,焦点是并行的设计和开发的概念。在你具体设计轨范前,你起头编程。这个手艺分歧于传统体例的形式----传统的体例是设计应该在编码起头前完成----可是良多成功的项目已经证实你能够更快速的开发高质量代码,相对于传统的按部就班的体例。可是在并行开发的焦点是主张矫捷性。你不得不以某一种体例写你的代码以至于最新发现的需求能够尽可能没有疾苦的合并到已有的代码中。胜于实现你也许需要的特征,你只需实现你明晰需要的特征,而且适度的对转变的包容。如不美观你没有这种矫捷,并行的开发,那简直不成能。对于Inteface的编程是矫捷结构的焦点。为了声名为什么,让我们看一下当使用它们的时辰,会发生什么。考虑下面的代码:* t/ H8 Q8 m- [$ H5 c3 Y/ Q% v, N- m
[/代码]* I, I" q! P# {/ A. o
f()) ]1 s' G2 }: f9 d% |4 r9 N
{ LinkedList list = new LinkedList();- ~3 P( O1 Y) `/ i" x) c8 ]
//...' c0 m b9 Z4 U9 A3 v8 w# w
g( list );
0 Y# L9 z+ _) L0 l+ U' @# ~. h }g( LinkedList list ) ^1 X J' u* V+ H
{* Z8 x' n" W& l- @% P& T8 W/ r# l
list.add( ... );7 {7 q B3 c4 b* s: ^4 b7 a9 ~. y" Z
g2( list )
% g# O, B; l) R: }# m" l, |8 Q3 G }
, d9 R5 Y# s) L [/代码]
7 Y; m; f: y2 a2 |+ [* z 此刻,假设一个对于快速发芽的需求被提出,以至于这个LinkedList不能够解决。你需要用HashSet来庖代它。在已有代滤鱿脯转变不能够局部化,因为你不仅仅需要改削f()也需要改削g()(它带有LinkedList参数),而且还有g()把列表传递给的任何代码。/ `6 g1 J6 @ n+ j$ s; Y
象下面这样重写代码:
0 `3 `6 a B% Z1 K [/代码]5 n- { [2 G+ X0 a
f()
, z7 K4 r1 E. M; U, j5 E: n { Collection list = new LinkedList();6 H" z+ p( u+ r8 u3 H2 n3 R0 r x0 `, l& B
//..., g3 b; B$ F3 H8 l1 C: _! Q
g( list );% A/ q+ K, o! f! |7 P/ w
}g( Collection list )5 s5 ]8 ~0 o7 Y1 ~) k; @% ~+ i
{( T* E9 p( Y- [4 M( q( d4 y2 c
list.add( ... );* o! {$ T% ]& B6 \) m9 y
g2( list )$ m% x5 b2 c2 p4 W
}; d4 R" Q6 O2 D5 B# J
[/代码]& t/ g2 d+ b0 i6 G9 k3 ^
这样改削Linked list成hash,可能只是简单的用new HashSet()庖代new LinkedList()。就这样。没有其他的需要改削的处所。
3 ^# W6 F# f1 T" z+ V( N! A: z 作为另一个例子,斗劲下面两段代码:8 _& n3 O% P' K, Z/ R9 G9 C
[/代码]' y5 t' k6 J2 [; S
f()* J, a! z/ w, B+ O0 q$ h/ A
{ Collection c = new HashSet();: L+ ]3 A; S) t/ [+ O! {4 }# m
//...
* H$ v5 O" a% n" p" ? g( c );' F; M- S$ T d8 N1 U1 ?1 n$ e
}g( Collection c ); f: O G* b" h i# v
{$ s' ?( l8 ^, b* L* E9 t
for( Iterator i = c.iterator(); i.hasNext() )
$ z$ g! f1 F0 @! ] do_something_with( i.next() );5 ^& [ q9 Q. r. \, K
}. w/ ~$ p- W8 f n3 R, r$ D' N
[/代码]
Z9 s- [ \5 }+ P( R/ b1 J- W6 _ 和
: }# u; U* S; q [/代码]0 v2 a. \- q# P' Q* `5 w7 ^
f2()' ^5 O6 Z7 U- v1 R0 r5 B
{ Collection c = new HashSet();6 c9 b! b9 E% d) a! i P: s
//...1 } F3 H3 b q( u+ n4 C
g2( c.iterator() );5 [9 h! i! O; ?# s7 k
}g2( Iterator i )
/ z8 a9 a' s1 l% A { while( i.hasNext() )" T! l; ?& ]$ T# ~4 Q
do_something_with( i.next() );
" w7 k. m ^7 |& W( V& N }; K' J) G7 J) j+ l% [
|