組合模式一般是將一系列類似的小物件組合成大的物件,由這個大物件提供介面來對裡面的小物件進行操作,下買呢我們來詳細看一下設計模式中的組合模式在JavaScript程式建構中的使用
定義
組合,顧名思義是指用包含多個元件的物件建立單一實體。這個單一實體將用作所有這些部件的存取點,雖然這大大簡化了操作,但也可能具有相當的欺騙性,因為沒有哪種隱性方式明確表明該組合包含多少部件。
組合模式的目標是解耦客戶程式與複雜元素內部架構,使得客戶程式對待所有子元素都一視同仁。
每個子節點都可以讓複雜的存在,對於父節點來說,不需要知道子節點的複雜性或實作子節點的複雜性,只需要關注子節點的特定方法,便可以使用子節點。簡化了父和子之間的關係。
對於子節點來說也是一樣的,過多的介面暴露有時候也是一種濫用,同時也減少了對外部的依賴。
範例我們最好使用例證解說組合。在下圖中,您可以看到兩種不同類型的物件: 容器和庫是組合,圖像是葉片。組合可承載子項,但一般不會實施更多行為。葉片包含絕大多數行為,但不能承載子項,至少在傳統的組合範例中不可以。
此範例建立圖片庫,並將其作為組合模式範例。只有三個層次: 專輯、庫和圖像。專輯和庫將作為組合,圖像是葉片,如上面那張圖所示。這是一種比組合本身需求更明確的結構,但對於本範例而言,將這些層次僅限制為組合或葉片很有意義。標準組合不會限制哪些結構層次可以具有葉片,也不會限制葉片數量。
要開始操作,應先建立用於專輯和庫的 GalleryComposite「類別」。請注意,我正在使用 jQuery 執行 DOM 操作以簡化流程。
var GalleryComposite = function (heading, id) { this.children = []; this.element = $('<p id="' + id + '" class="composite-gallery"></p>') .append('<h2>' + heading + '</h2>'); } GalleryComposite.prototype = { add: function (child) { this.children.push(child); this.element.append(child.getElement()); }, remove: function (child) { for (var node, i = 0; node = this.getChild(i); i++) { if (node == child) { this.children.splice(i, 1); this.element.detach(child.getElement()); return true; } if (node.remove(child)) { return true; } } return false; }, getChild: function (i) { return this.children[i]; }, hide: function () { for (var node, i = 0; node = this.getChild(i); i++) { node.hide(); } this.element.hide(0); }, show: function () { for (var node, i = 0; node = this.getChild(i); i++) { node.show(); } this.element.show(0); }, getElement: function () { return this.element; } }
這個位置有點棘手,能否允許我再更多的解釋一下?我們同時使用 add, remove, 和getChild getChild 方法來建構這個組合。本範例不會實際使用 remove 和 getChild,但它們對於建立動態組合非常有用。 hide, show, 和getElement 方法則用來操縱 DOM。該組合旨在作為庫的 表示在頁面上向用戶展示。此組合可透過 hide 和 show控制這些庫元素。如果在專輯上調用 hide,則整張專輯將消失,或者您也可以只在單一圖像上調用它,這樣只有該圖像會消失。
現在,建立一個 GalleryImage類別。請注意,它使用的方法與 GalleryComposite完全相同。換句話說,它們實現同一接口,不同的是該圖像是葉片,因此不會實際對子項相關方法執行任何操作,就像不具有任何子項一樣。必須使用相同介面運行該組合,因為組合元素不知道自身添加的是另一個組合元素還是葉片,因此如果嘗試在其子項上呼叫這些方法,則需要運行完全正常,沒有任何錯誤。
var GalleryImage = function (src, id) { this.children = []; this.element = $('<img />') .attr('id', id) .attr('src', src); } GalleryImage.prototype = { // Due to this being a leaf, it doesn't use these methods, // but must implement them to count as implementing the // Composite interface add: function () { }, remove: function () { }, getChild: function () { }, hide: function () { this.element.hide(0); }, show: function () { this.element.show(0); }, getElement: function () { return this.element; } }
鑑於您已經建立了物件原型,您現已能夠進行使用。從下面您可以看到實際建立圖像庫的程式碼。
var container = new GalleryComposite('', 'allgalleries'); var gallery1 = new GalleryComposite('Gallery 1', 'gallery1'); var gallery2 = new GalleryComposite('Gallery 2', 'gallery2'); var image1 = new GalleryImage('image1.jpg', 'img1'); var image2 = new GalleryImage('image2.jpg', 'img2'); var image3 = new GalleryImage('image3.jpg', 'img3'); var image4 = new GalleryImage('image4.jpg', 'img4'); gallery1.add(image1); gallery1.add(image2); gallery2.add(image3); gallery2.add(image4); container.add(gallery1); container.add(gallery2); // Make sure to add the top container to the body, // otherwise it'll never show up. container.getElement().appendTo('body'); container.show();
組合模式之利:簡單的操作也能產生複雜的結果,只需對最頂層的物件執行操作,讓每個子物件自己傳遞這個操作即可。這對於那些再三執行的操作尤其有用。
在組合模式中,各個物件之間的耦合非常鬆散。只要它們實現了同樣的介面那麼改變它們的位置或互換它們只是舉手之勞。著促進了程式碼的重用,也有利於程式碼重構。
每當對頂層組合物件執行一個操作時,實際上是在對整個結構進行深度優先的搜尋以查找節點,而創建組合物件的程式設計師對這些細節一無所知。在這個層次體系中新增、刪除和尋找節點都非常容易。
組合模式之弊:組合物件的易用性可能掩蓋了它所支援的每一種操作的代價。由於組合物件呼叫的任何操作都會被傳遞到它的所有子物件如果這個層次體系很大的話,系統的效能將會受到影響。組合模式的正常運作需要用到某種形式的介面。
組合物件和節點類別被用作HTML元素的包裝工具時,組合物件必須遵守HTML的使用規則。例如,表格就很難轉換為一個組合物件。
介面檢查越嚴格,組合物件類別也就越可靠。
上面是我整理給大家的,希望今後對大家有幫助。
相關文章:
JavaScript設計模式開發中組合模式的使用教學(進階篇)
設計模式中的facade外觀模式在JavaScript開發中的運用(高級篇)
#詳細解讀在JavaScript中實現設計模式中的適配器模式的方法(圖文教學)
以上是設計模式中的組合模式在JavaScript程式建置中的使用(進階篇)的詳細內容。更多資訊請關注PHP中文網其他相關文章!