<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 16.5 抽象的應用 走到這一步,接下來該考慮一下設計模式剩下的部分了——在哪里使用類?既然歸類到垃圾箱的辦法非常不雅且過于暴露,為什么不隔離那個過程,把它隱藏到一個類里呢?這就是著名的“如果必須做不雅的事情,至少應將其本地化到一個類里”規則。看起來就象下面這樣: ![](https://box.kancloud.cn/37cbb34bf106495a9e38a4dd1192574b_372x109.gif) 現在,只要一種新類型的`Trash`加入方法,對`TrashSorter`對象的初始化就必須變動。可以想象,`TrashSorter`類看起來應該象下面這個樣子: ``` class TrashSorter extends Vector { void sort(Trash t) { /* ... */ } } ``` 也就是說,`TrashSorter`是由一系列引用構成的`Vector`(系列),而那些引用指向的又是由`Trash`引用構成的`Vector`;利用`addElement()`,可以安裝新的`TrashSorter`,如下所示: ``` TrashSorter ts = new TrashSorter(); ts.addElement(new Vector()); ``` 但是現在,`sort()`卻成為一個問題。用靜態方式編碼的方法如何應付一種新類型加入的事實呢?為解決這個問題,必須從`sort()`里將類型信息刪除,使其需要做的所有事情就是調用一個通用方法,用它照料涉及類型處理的所有細節。這當然是對一個動態綁定方法進行描述的另一種方式。所以`sort()`會在序列中簡單地遍歷,并為每個`Vector`都調用一個動態綁定方法。由于這個方法的任務是收集它感興趣的垃圾片,所以稱之為`grab(Trash)`。結構現在變成了下面這樣: ![](https://box.kancloud.cn/95a6ed6bd9d54dda7af6204375e8ab4d_408x214.gif) 其中,`TrashSorter`需要調用每個`grab()`方法;然后根據當前`Vector`容納的是什么類型,會獲得一個不同的結果。也就是說,`Vector`必須留意自己容納的類型。解決這個問題的傳統方法是創建一個基礎“Trash bin”(垃圾筒)類,并為希望容納的每個不同的類型都繼承一個新的派生類。若Java有一個參數化的類型機制,那就也許是最直接的方法。但對于這種機制應該為我們構建的各個類,我們不應該進行麻煩的手工編碼,以后的“觀察”方式提供了一種更好的編碼方式。 OOP設計一條基本的準則是“為狀態的變化使用數據成員,為行為的變化使用多性形”。對于容納`Paper`(紙張)的`Vector`,以及容納`Glass`(玻璃)的`Vector`,大家最開始或許會認為分別用于它們的`grab()`方法肯定會產生不同的行為。但具體如何卻完全取決于類型,而不是其他什么東西。可將其解釋成一種不同的狀態,而且由于Java有一個類可表示類型(`Class`),所以可用它判斷特定的`Tbin`要容納什么類型的`Trash`。 用于Tbin的構造器要求我們為其傳遞自己選擇的一個`Class`。這樣做可告訴`Vector`它希望容納的是什么類型。隨后,`grab()`方法用`Class BinType`和RTTI來檢查我們傳遞給它的`Trash`對象是否與它希望收集的類型相符。 下面列出完整的解決方案。設定為注釋的編號(如*1*)便于大家對照程序后面列出的說明。 ``` //: RecycleB.java // Adding more objects to the recycling problem package c16.recycleb; import c16.trash.*; import java.util.*; // A vector that admits only the right type: class Tbin extends Vector { Class binType; Tbin(Class binType) { this.binType = binType; } boolean grab(Trash t) { // Comparing class types: if(t.getClass().equals(binType)) { addElement(t); return true; // Object grabbed } return false; // Object not grabbed } } class TbinList extends Vector { //(*1*) boolean sort(Trash t) { Enumeration e = elements(); while(e.hasMoreElements()) { Tbin bin = (Tbin)e.nextElement(); if(bin.grab(t)) return true; } return false; // bin not found for t } void sortBin(Tbin bin) { // (*2*) Enumeration e = bin.elements(); while(e.hasMoreElements()) if(!sort((Trash)e.nextElement())) System.out.println("Bin not found"); } } public class RecycleB { static Tbin bin = new Tbin(Trash.class); public static void main(String[] args) { // Fill up the Trash bin: ParseTrash.fillBin("Trash.dat", bin); TbinList trashBins = new TbinList(); trashBins.addElement( new Tbin(Aluminum.class)); trashBins.addElement( new Tbin(Paper.class)); trashBins.addElement( new Tbin(Glass.class)); // add one line here: (*3*) trashBins.addElement( new Tbin(Cardboard.class)); trashBins.sortBin(bin); // (*4*) Enumeration e = trashBins.elements(); while(e.hasMoreElements()) { Tbin b = (Tbin)e.nextElement(); Trash.sumValue(b); } Trash.sumValue(bin); } } ///:~ ``` (1) `TbinList`容納一系列`Tbin`引用,所以在查找與我們傳遞給它的`Trash`對象相符的情況時,`sort()`能通過`Tbin`繼承。 (2) `sortBin()`允許我們將一個完整的`Tbin`傳遞進去,而且它會在`Tbin`里遍歷,挑選出每種`Trash`,并將其歸類到特定的`Tbin`中。請注意這些代碼的通用性:新類型加入時,它本身不需要任何改動。只要新類型加入(或發生其他事件)時大量代碼都不需要變化,就表明我們設計的是一個容易擴展的系統。 (3) 現在可以體會添加新類型有多么容易了。為支持添加,只需要改動幾行代碼。如確實有必要,甚至可以進一步地改進設計,使更多的代碼都保持“固定”。 (4) 一個方法調用使`bin`的內容歸類到對應的、特定類型的垃圾筒里。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看