有一天,有人也許運行這個代碼並且注重到Stack沒有運行的如想象的那麼快,並且能夠在重負荷下使用。你能夠重寫Stack,以至於它不用ArrayList並且繼續提高Stack的效率。
<!-- frame contents -->
<!-- /frame contents -->
這是新的傾向的和有意義的版本:
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不再多次調用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