麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

為什么extends是有害的(二)

2019-11-18 13:18:43
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  有一天,有人也許運(yùn)行這個(gè)代碼并且注重到Stack沒(méi)有運(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 ) < stack.length;
      
        System.arraycopy( articles, 0, stack, stack_pointer + 1, articles.length );
        Stack_pointer += articles.length;
      }
  }
  [/代碼]
  
  注重到push_many不再多次調(diào)用push()—它做塊傳輸。新的Stack運(yùn)行正常;事實(shí)上,比前一個(gè)版本更好。不幸的是,派生類Monitorable_stack不再運(yùn)行,因?yàn)榧偃鏿ush_many()被調(diào)用,它不正確的跟蹤堆棧的使用(push()的派生類版本不再通過(guò)繼續(xù)的push_many()方法調(diào)用,所以push_many()不再更新high_water_mark)。Stack是一個(gè)脆弱的類。與關(guān)閉它一樣,事實(shí)上不可能通過(guò)小心來(lái)消滅這些類型的錯(cuò)誤。
  
  注重假如你用接口繼續(xù),你就沒(méi)有這個(gè)問(wèn)題,因?yàn)槟銢](méi)有繼續(xù)對(duì)你有害的函數(shù)。假如Stack是接口,由Simple_stack和Monitorable_stack實(shí)現(xiàn),那么代碼就是更加健壯的。
  
  我提供了一個(gè)基于接口的方法在Listing 0.1。這個(gè)解決方法和繼續(xù)實(shí)現(xiàn)的方法一樣的靈活:你能夠用Stack抽象術(shù)語(yǔ)來(lái)寫代碼而不必?fù)?dān)心你事實(shí)上在操作那種具體的堆棧。因?yàn)閮蓚€(gè)實(shí)現(xiàn)必須提供公共接口的所有東西,它很難使事情變?cè)恪N胰匀挥泻蛯懟惖拇a一樣的只寫一次,因?yàn)槲矣梅庋b而不是繼續(xù)。在底層,我不得不通過(guò)封裝類中的瑣碎的訪問(wèn)器方法來(lái)訪問(wèn)缺省的實(shí)現(xiàn)。(例如,Monitorable_Stack.push(…)(在41行)不得不調(diào)用在Simple_stack等價(jià)的方法).程序員埋怨寫所有這些行,但是寫這非凡行代碼同消除重要的潛在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
  [/代碼]
  
  沒(méi)有提到基于框架編程,那使對(duì)于脆弱的基類的討論是不完整的。諸如Microsoft Foundation Classes(MFC)的基類已經(jīng)成為建立類庫(kù)的流行途徑。盡管MFC本身正在神圣的隱退,但是MFC的基口已經(jīng)是根深蒂固,而這無(wú)關(guān)于Microsoft在那終止,程序員會(huì)一直認(rèn)為Microsoft的方法是最好的方法。
  
  一個(gè)基于框架的系統(tǒng)典型的使用半成品的類的構(gòu)成庫(kù)開始,這些類不做任何需要做的事,而是依靠于派生類來(lái)提供需要的功能。在Java中,一個(gè)好的例子就是組件的paint()方法,它是一個(gè)有效的占位者;一個(gè)派生類必須提供真正的版本。
  
  你能夠適度的多國(guó)一些東西,但是一個(gè)基于定制的派生類的完整的類框架是非常脆弱的?;愂翘嗳趿?。當(dāng)我們用MFC編程時(shí),每次Microsoft公布新版本時(shí),我不得不重寫我的應(yīng)用。這些代碼將經(jīng)常編譯,但是由于一些基類的改變,它們不能運(yùn)行。
  
  所有提供的Java包工作的非常好。為了使它們運(yùn)行,你不需要擴(kuò)展任何東西。這個(gè)已經(jīng)提供的結(jié)構(gòu)比派生類的框架結(jié)構(gòu)更好。它輕易維護(hù)和使用,并且假如Sun Microsystems提供的類改變了它的實(shí)現(xiàn),也不會(huì)使你的代碼處在危險(xiǎn)中。
  
  總結(jié)脆弱基類
  一般,最好避開具體基礎(chǔ)類和extends關(guān)系,而用接口和implements關(guān)系。我的處理規(guī)則是,在我的至少80%的代碼中完全用接口來(lái)完成。例如,我從不用對(duì)HashMap的引用;我用對(duì)Map接口的引用。(我對(duì)interface這個(gè)字不是嚴(yán)格的。當(dāng)你看怎樣用接口的時(shí)候,InputStream是一個(gè)好的接口,盡管它在Java中是作為抽象類來(lái)實(shí)現(xiàn)的。)
  
  你增加的越抽象,就越靈活。在今天的商業(yè)環(huán)境下,需求隨著程序開發(fā)而改變,靈活就是最主要的。而且靈敏編程中的大多數(shù)只有代碼使用抽象來(lái)寫才會(huì)很好的運(yùn)行。
  
  假如你近距離的檢查四人幫的模式,你將看到這些模式中的很多是提供方法消除實(shí)現(xiàn)繼續(xù),而最好用接口繼續(xù),并且大多數(shù)模式的共有特征是用接口繼續(xù)。這個(gè)重要事實(shí)是我們開始時(shí)提到的:模式是發(fā)現(xiàn)而不是發(fā)明。模式的出現(xiàn)是當(dāng)你發(fā)現(xiàn)寫得很好,易維護(hù)的運(yùn)行代碼時(shí)。它講的是這些寫得好的,易維護(hù)的代碼根本的避開了實(shí)現(xiàn)繼續(xù)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 久久成年网站 | 久久精品视频亚洲 | 国产在线精品一区二区 | 久久久久久免费 | 亚洲网站在线观看视频 | 免费网址黄 | 国产美女视频一区二区三区 | 精品一区二区三区日本 | 久久99精品久久久久久园产越南 | 国产日本在线播放 | 99精品视频在线看 | 巨乳毛片| av资源在线天堂 | 国产精品久久久久久久久久大牛 | 国产一级一区二区 | 国产成人高潮免费观看精品 | 亚洲免费看片网站 | 欧美成人精品欧美一级乱黄 | 欧美特一级片 | 国产亚洲欧美视频 | 嗯~啊~弄嗯~啊h高潮视频 | 曰批全过程120分钟免费69 | 久久老司机 | 欧美日韩专区国产精品 | v11av在线播放 | 久久靖品 | 九九热九九热 | 亚洲视色 | 小雪奶水翁胀公吸小说最新章节 | 亚洲最新色 | 视频一区二区三区在线观看 | 国产色视频一区 | 特级黄色影院 | 亚洲成人免费电影 | 黄色影院在线看 | 亚洲午夜天堂吃瓜在线 | 一级毛片电影网 | 亚洲午夜一区二区三区 | 国产午夜精品一区二区三区免费 | 欧美日韩亚州综合 | 免费一级毛片观看 |