07.Javascript設計模式之組合模式—-Composite

來源:互聯網
上載者:User
07.Javascript設計模式之組合模式----Composite

組合模式是一種專為建立WEB上的動態使用者介面而量身定製的模式。使用這種模式,可以用一條命令在多個對象上激發複雜的或遞迴的行為,這可以簡化粘合性代碼,使其更容易維護,而那些複雜行為則被委託給各個對象。

本文主要通過一個Windows檔案目錄結構的例子來闡述組合模式。

問題引入

Windows檔案目錄結構就像一棵樹,有根節點(我的電腦),然後有子節點(如C盤、D盤等),子節點也還有子節點(盤符下的檔案夾),檔案夾下還可能會有檔案夾,也可能會有單獨的檔案,於是,在樹的概念中,
我們稱單獨的檔案節點為葉子,而檔案夾則為樹枝。

於是,這一次有這樣一個命題,我們希望能夠有選擇地隱藏或顯示Windows目錄結構中的特定部分。這可能是單獨的檔案,也可能是檔案夾。考慮到Windows檔案目錄結構的複雜性,這裡我們只關注檔案或檔案夾的顯示和隱藏操作。

組合模式 類的定義

針對上面的命題,我們需要設計兩個類,一個用作檔案夾的組合對象類,一個用作檔案本身的葉子物件類。

//檔案夾介面:組合對象var IDirectory = new Interface("IDirectory",["add","delete","getFile"]);//檔案介面:葉子物件var IFile = new Interface("IFile",["show","hide"]);

接下來就是非常關鍵的了,這裡即將定義一個動態檔案系統類DynamicFileSystem,該類是IDirectory和IFile的實作類別。也就是說,通過DynamicFileSystem類執行個體化出來的對象,既可能是一個檔案,也可能是一個檔案夾。

其代碼如下:

//檔案系統類var DynamicFileSystem = function(id,fileName){    this.files = []; //子檔案清單(注意,檔案夾也是一個檔案)    this.createDate = new Date();//檔案的建立日期    this.fileName = fileName; //檔案名稱    //為了在WEB中很好的來描述這個問題,我們需要用到HTMLDOMElement    this.element = document.createElement("div");    this.element.id = id;};//實現兩個介面implements(DynamicFileSystem,IDirectory,IFile);//實現所有的抽象方法DynamicFileSystem.prototype = {    add : function(fileSystemChild){        this.files.push(fileSystemChild);        this.element.appendChild(fileSystemChild.getElement());    },    delete : function(fileSystemChild){        for(var file,i = 0;node = this.getFile(i),i++){            if(file == fileSystemChild){                this.files.splice(i,1);                break;            }        }        this.element.removeChild(fileSystemChild.getElement());    },    getFile : function(index){        return this.files[index];    },    show : function(){        //顯示檔案或檔案夾        this.element.style.display = "block";                   for(var file,i = 0;node = this.getFile(i),i++){            file.show(); //遞迴調用        }    },    hide : function(){                  for(var file,i = 0;node = this.getFile(i),i++){            file.hide(); //遞迴調用        }        //隱藏檔案或檔案夾        this.element.style.display = "none";    },    //拓展方法    getElement : function(){        return this.element;    }};

在上面的代碼中,首先定義的是組合對象類和葉子物件類應該實現的介面。除了常規的組合對象方法外,這些類要定義的操作只包含hide和show。
接下來定義的是組合對象類。由於DynamicFileSystem只是對div對象的封裝,所以檔案系統可以再嵌套子檔案系統,而我們因此也只需要用到一個組合對象類即可。

執行個體化示範

下面就是大家迫不及待想要看到的,如何執行個體化並操作整個Windows的分類樹結構呢?

其實到這裡還沒有完,我們必須要有一個真正的檔案實體類,比如Word文檔、PDF文檔、Text文檔等等,它們都是File,因此我們可以隨便的定義一個檔案類,並讓它繼承DynamicFileSystem類即可(因為它同樣具備檔案系統的功能),
下面以Text文檔為例,建立TextFile類:

var TextFile = function(id,fileName){    //檔案名稱    this.fileName = fileName;    this.element = document.createElement("div");    this.element.id = id;};//實施繼承inherits(TextFile,DynamicFileSystem);

如此一來,TextFile類就已經具備了DynamicFileSystem類的所有方法,而且還有一個自己獨特的構造器,接收一個參數----檔案名稱。

接下來就是真正的開始應用了,我們首先建立一個檔案系統(檔案夾)的執行個體,再建立三個文字檔TextFile類的執行個體,最後將這三個文字檔添加到檔案系統中去:

//建立檔案夾var fileSystem = new DynamicFileSystem("dirRoot","C盤");//建立文字檔var txtFile1 = new TextFile("txtFile1","文字檔1");var txtFile2 = new TextFile("txtFile2","文字檔2");var txtFile3 = new TextFile("txtFile3","文字檔3");//將三個文字檔添加到檔案夾中fileSystem.add(txtFile1);fileSystem.add(txtFile2);fileSystem.add(txtFile3);

在這個時候你可能想說了,我想在C盤下建立兩個檔案夾,分別是“Windows”和“Program Files”,該怎麼辦呢?很簡單,繼續之前的代碼:

var windowsDir = new DynamicFileSystem("dirWindows","Windows"); //Windows檔案夾var programDir = new DynamicFileSystem("dirProgram","Program Files"); //Program Files檔案夾//添加到C盤fileSystem.add(windowsDir);fileSystem.add(programDir);

OK,到了這一步,一切都順利的完成了。

如果你是一個愛問的同學,你想知道,如果我突然需要安裝一個軟體,該軟體的安裝目錄必須為C:Program FilesMicrosoft,安裝完成後還會在Microsoft目錄下產生一個microsoft.exe的檔案,又該怎麼類比呢?

照貓畫虎:

第一步,建立ExeFile類第二步,建立Microsoft目錄第三步,將其添加到C:/Program Files下第四步,建立ExeFile類的執行個體microsoft.exe檔案第五步,將microsoft.exe添加到C:/Program Files/Microsoft目錄下,完成
總結
如果應用得當,組合模式將是一種非常管用的設計模式。它把一批子物件組織為樹形結構,只要一條命令就可以操作樹上的所有對象,提高了代碼的模組化程度,而且便於代碼重構和對象的更換。這種模式特別適合於動態HTML使用者介面,在它的協助下,你可以在不知道使用者介面的最終格局的情況下進行開發。對於我們每一個前端Javascript程式員來說,能掌握好組合模式,一定會大受益處滴。

本文參考《Javascript設計模式》【Ross Harmes,Dustin Diaz】

小生愚昧,文中如有闡述之不當,還請不要介懷

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.