国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

為什么extends是有害的(二)

2019-11-18 13:18:43
字體:
來源:轉載
供稿:網友

  有一天,有人也許運行這個代碼并且注重到Stack沒有運行的如想象的那么快,并且能夠在重負荷下使用。你能夠重寫Stack,以至于它不用ArrayList并且繼續提高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不再多次調用push()—它做塊傳輸。新的Stack運行正常;事實上,比前一個版本更好。不幸的是,派生類Monitorable_stack不再運行,因為假如push_many()被調用,它不正確的跟蹤堆棧的使用(push()的派生類版本不再通過繼續的push_many()方法調用,所以push_many()不再更新high_water_mark)。Stack是一個脆弱的類。與關閉它一樣,事實上不可能通過小心來消滅這些類型的錯誤。
  
  注重假如你用接口繼續,你就沒有這個問題,因為你沒有繼續對你有害的函數。假如Stack是接口,由Simple_stack和Monitorable_stack實現,那么代碼就是更加健壯的。
  
  我提供了一個基于接口的方法在Listing 0.1。這個解決方法和繼續實現的方法一樣的靈活:你能夠用Stack抽象術語來寫代碼而不必擔心你事實上在操作那種具體的堆棧。因為兩個實現必須提供公共接口的所有東西,它很難使事情變糟。我仍然有和寫基類的代碼一樣的只寫一次,因為我用封裝而不是繼續。在底層,我不得不通過封裝類中的瑣碎的訪問器方法來訪問缺省的實現。(例如,Monitorable_Stack.push(…)(在41行)不得不調用在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
  [/代碼]
  
  沒有提到基于框架編程,那使對于脆弱的基類的討論是不完整的。諸如Microsoft Foundation Classes(MFC)的基類已經成為建立類庫的流行途徑。盡管MFC本身正在神圣的隱退,但是MFC的基口已經是根深蒂固,而這無關于Microsoft在那終止,程序員會一直認為Microsoft的方法是最好的方法。
  
  一個基于框架的系統典型的使用半成品的類的構成庫開始,這些類不做任何需要做的事,而是依靠于派生類來提供需要的功能。在Java中,一個好的例子就是組件的paint()方法,它是一個有效的占位者;一個派生類必須提供真正的版本。
  
  你能夠適度的多國一些東西,但是一個基于定制的派生類的完整的類框架是非常脆弱的?;愂翘嗳趿恕.斘覀冇肕FC編程時,每次Microsoft公布新版本時,我不得不重寫我的應用。這些代碼將經常編譯,但是由于一些基類的改變,它們不能運行。
  
  所有提供的Java包工作的非常好。為了使它們運行,你不需要擴展任何東西。這個已經提供的結構比派生類的框架結構更好。它輕易維護和使用,并且假如Sun Microsystems提供的類改變了它的實現,也不會使你的代碼處在危險中。
  
  總結脆弱基類
  一般,最好避開具體基礎類和extends關系,而用接口和implements關系。我的處理規則是,在我的至少80%的代碼中完全用接口來完成。例如,我從不用對HashMap的引用;我用對Map接口的引用。(我對interface這個字不是嚴格的。當你看怎樣用接口的時候,InputStream是一個好的接口,盡管它在Java中是作為抽象類來實現的。)
  
  你增加的越抽象,就越靈活。在今天的商業環境下,需求隨著程序開發而改變,靈活就是最主要的。而且靈敏編程中的大多數只有代碼使用抽象來寫才會很好的運行。
  
  假如你近距離的檢查四人幫的模式,你將看到這些模式中的很多是提供方法消除實現繼續,而最好用接口繼續,并且大多數模式的共有特征是用接口繼續。這個重要事實是我們開始時提到的:模式是發現而不是發明。模式的出現是當你發現寫得很好,易維護的運行代碼時。它講的是這些寫得好的,易維護的代碼根本的避開了實現繼續。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 休宁县| 秦皇岛市| 墨江| 阿坝县| 阿荣旗| 兰考县| 湟源县| 屏东市| 增城市| 揭阳市| 宜丰县| 永新县| 鹤壁市| 同江市| 宣化县| 汉沽区| 开封市| 宣恩县| 即墨市| 乌苏市| 三门峡市| 光泽县| 沙田区| 乾安县| 乐昌市| 永川市| 安泽县| 上蔡县| 库伦旗| 深泽县| 凤山市| 泾源县| 托里县| 鲁甸县| 札达县| 信宜市| 柘荣县| 德庆县| 竹溪县| 和政县| 罗山县|