久久―日本道色综合久久,亚洲欧美精品在线,狼狼色丁香久久婷婷综合五月,香蕉人人超,日本网站黄,国产在线观看不卡免费高清,无遮挡的毛片免费

2023信創(chuàng)獨(dú)角獸企業(yè)100強(qiáng)
全世界各行各業(yè)聯(lián)合起來,internet一定要實(shí)現(xiàn)!

為什么Java中繼承是有害的二

2004-02-15 eNet&Ciweek

  有一天,有人也許運(yùn)行這個代碼并且注意到Stack沒有運(yùn)行的如想象的那么快,并且能夠在重負(fù)荷下使用。你能夠重寫Stack,以至于它不用ArrayList并且繼續(xù)提高Stack的效率。這是新的傾向的和有意義的版本:

class Stack
{
private int stack_pointer = -1;
private Object[] stack = new Object[1000];

public void push( Object article )
{
assert stack_pointer < stack.length;

stack[ ++stack_pointer ] = article;
}

public Object pop()
{
assert stack_pointer >= 0;
return stack[ stack_pointer-- ];
}

public void push_many( Object[] articles )
{
assert ( stack_pointer + articles.length )



  注意到push_many不再多次調(diào)用push()—它做塊傳輸。新的Stack運(yùn)行正常;事實(shí)上,比前一個版本更好。不幸的是,派生類Monitorable_stack不再運(yùn)行,因?yàn)槿绻鹥ush_many()被調(diào)用,它不正確的跟蹤堆棧的使用(push()的派生類版本不再通過繼承的push_many()方法調(diào)用,所以push_many()不再更新high_water_mark)。Stack是一個脆弱的類。與關(guān)閉它一樣,事實(shí)上不可能通過小心來消滅這些類型的錯誤。

  注意如果你用接口繼承,你就沒有這個問題,因?yàn)槟銢]有繼承對你有害的函數(shù)。如果Stack是接口,由Simple_stack和Monitorable_stack實(shí)現(xiàn),那么代碼就是更加健壯的。

  我提供了一個基于接口的方法在Listing 0.1。這個解決方法和繼承實(shí)現(xiàn)的方法一樣的靈活:你能夠用Stack抽象術(shù)語來寫代碼而不必?fù)?dān)心你事實(shí)上在操作那種具體的堆棧。因?yàn)閮蓚€實(shí)現(xiàn)必須提供公共接口的所有東西,它很難使事情變糟。我仍然有和寫基類的代碼一樣的只寫一次,因?yàn)槲矣梅庋b而不是繼承。在底層,我不得不通過封裝類中的瑣碎的訪問器方法來訪問缺省的實(shí)現(xiàn)。(例如,Monitorable_Stack.push(…)(在41行)不得不調(diào)用在Simple_stack等價的方法).程序員埋怨寫所有這些行,但是寫這特別行代碼同消除重要的潛在bug是非常小的成本。

  Listing 0.1. 用接口消除脆弱基類

1  import java.util.*;
2 
3  interface Stack
4  {
5  void push( Object o );
6  Object pop();
7  void push_many( Object[] source );
8  }
9 
10  class Simple_stack implements Stack
11  { private int stack_pointer = -1;
12  private Object[] stack = new Object[1000];
13 
14  public void push( Object o )
15  { assert stack_pointer < stack.length;
16 
17  stack[ ++stack_pointer ] = o;
18  }
19 
20  public Object pop()
21  { assert stack_pointer >= 0;
22 
23  return stack[ stack_pointer-- ];
24  }
25 
26  public void push_many( Object[] source )
27  { assert (stack_pointer + source.length) < stack.length;
28 
29  System.arraycopy(source,0,stack,stack_pointer+1,
source.length);
30  stack_pointer += source.length;
31  }
32  }
33 
34 
35  class Monitorable_Stack implements Stack
36  {
37  private int high_water_mark = 0;
38  private int current_size;
39  Simple_stack stack = new Simple_stack();
40 
41  public void push( Object o )
42  { if( ++current_size > high_water_mark )
43  high_water_mark = current_size;
44  stack.push(o);
45  }
46 
47  public Object pop()
48  { --current_size;
49  return stack.pop();
50  }
51 
52  public void push_many( Object[] source )
53  {
54  if( current_size + source.length > high_water_mark )
55  high_water_mark = current_size + source.length;
56 
57  stack.push_many( source );
58  }
59 
60  public int maximum_size()
61  { return high_water_mark;
62  }
63  }
64 



  框架(Frameworks)

  沒有提到基于框架編程,那使對于脆弱的基類的討論是不完整的。諸如Microsoft Foundation Classes(MFC)的基類已經(jīng)成為建立類庫的流行途徑。盡管MFC本身正在神圣的隱退,但是MFC的基口已經(jīng)是根深蒂固,而這無關(guān)于Microsoft在那終止,程序員會一直認(rèn)為Microsoft的方法是最好的方法。

  一個基于框架的系統(tǒng)典型的使用半成品的類的構(gòu)成庫開始,這些類不做任何需要做的事,而是依賴于派生類來提供需要的功能。在Java中,一個好的例子就是組件的paint()方法,它是一個有效的占位者;一個派生類必須提供真正的版本。

  你能夠適度的多國一些東西,但是一個基于定制的派生類的完整的類框架是非常脆弱的。基類是太脆弱了。當(dāng)我們用MFC編程時,每次Microsoft公布新版本時,我不得不重寫我的應(yīng)用。這些代碼將經(jīng)常編譯,但是由于一些基類的改變,它們不能運(yùn)行。

  所有提供的Java包工作的非常好。為了使它們運(yùn)行,你不需要擴(kuò)展任何東西。這個已經(jīng)提供的結(jié)構(gòu)比派生類的框架結(jié)構(gòu)更好。它容易維護(hù)和使用,并且如果Sun Microsystems提供的類改變了它的實(shí)現(xiàn),也不會使你的代碼處在危險中。

  總結(jié)脆弱的基類

  一般,最好避開具體基礎(chǔ)類和extends關(guān)系,而用接口和implements關(guān)系。我的處理規(guī)則是,在我的至少80%的代碼中完全用接口來完成。例如,我從不用對HashMap的引用;我用對Map接口的引用。(我對interface這個字不是嚴(yán)格的。當(dāng)你看怎樣用接口的時候,InputStream是一個好的接口,盡管它在Java中是作為抽象類來實(shí)現(xiàn)的。)

  你增加的越抽象,就越靈活。在今天的商業(yè)環(huán)境下,需求隨著程序開發(fā)而改變,靈活就是最主要的。而且靈敏編程中的大多數(shù)只有代碼使用抽象來寫才會很好的運(yùn)行。

  如果你近距離的檢查四人幫的模式,你將看到這些模式中的很多是提供方法消除實(shí)現(xiàn)繼承,而最好用接口繼承,并且大多數(shù)模式的共有特征是用接口繼承。這個重要事實(shí)是我們開始時提到的:模式是發(fā)現(xiàn)而不是發(fā)明。模式的出現(xiàn)是當(dāng)你發(fā)現(xiàn)寫得很好,易維護(hù)的運(yùn)行代碼時。它講的是這些寫得好的,易維護(hù)的代碼根本的避開了實(shí)現(xiàn)繼承。

  這個文章是從我即將出版的書,暫時命名為《Holub on Patterns:Learning Design Patterns by Looking at Code》,將有Apress在今年秋季出版。

相關(guān)頻道: eNews

您對本文或本站有任何意見,請?jiān)谙路教峤?,謝謝!

投稿信箱:tougao@enet16.com