天天看點

【轉】JS設計模式開篇

(原文位址:http://blog.chinaunix.net/uid-26672038-id-3904513.html)

    本文主要講述一下,什麼是設計模式(Design

pattern),作為敲鍵盤的我們要如何學習設計模式。設計模式真的是一把萬能鑰匙麼?

    各個代碼的設計模式幾乎每個人都知曉,就算不會那也一定在一些裝逼的大牛(部分而已)口中聽過。但可能很少有人知道設計模式的由來:

    設計模式該術語源自Erich

Gamma等人在上世紀90年代從建築設計領域引入到計算機科學的(很難想象到底有多大關聯)。它是對軟體設計中一些反複出現,普遍存在的問題所提出的解決方案。是以說設計模式并不是某種語言的某塊代碼,設計模式是一種思想,提供給在編碼時候遇到的各種問題是可以采取的解決方案,更傾向于一種邏輯思維,而不是萬能代碼塊。

    設計模式使人可以更加簡單友善的複用一些較為成功的設計和體系結構,使用設計模式來使人了解整個系統的開發思路。

    模式名稱(pattern

name):助記名,以幾個詞來描述問題,解決方案和效果。模式名可以幫助我們思考,一邊與其他程式員進行設計思想交流。

    問題(problem):描繪使用設計模式的具體情況。解釋設計問題和問題存在的因果,可能描述特定的設計問題,也可能描述導緻不靈活的設計的類或者對象結構等。

    解決方案(solution):描述設計的組成成分,它們之間的互相關系與各自的職責和協作方式。解決方案并不具體的描述某種設計的實作,而是提供設計問題的抽象描述和怎樣用一些一般意義的元素來解決這個問題。

    效果(consequences):描述模式的應用效果以及使用模式需要權衡的問題,雖然很少提到模式的效果,但是對于評價該模式在該問題下是有很重要的意義。模式效果包括此模式對于系統的靈活性,擴充性或者可移植性的影響,顯示列出這些效果可以客觀的評價該模式對于該問題的适用性。

    建立型模式:單例模式,抽象工廠模式,建造者模式,工廠模式與原型模式。

    結構型模式:擴充卡模式,橋接模式,裝飾者模式,組合模式,外觀模式,享元模式以及代理模式。

    行為型模式:模闆方法模式,指令模式,疊代器模式,觀察者模式,中介者模式,備忘錄模式,解釋器模式,狀态模式,政策模式,職責鍊模式和通路者模式。

客戶類與工廠類分開,當客戶需要某種産品時向對應工廠送出請求。缺點是當産品需要修改時,工廠類也需要做相應的修改。

    意圖:

        提供一個建立一系列相關或者互相依賴的對象接口,無需指定它們具體的類。

    适用性:

        一個系統要獨立于它的産品建立,組合的時候。

    一個系統要由多個産品系列中的一個來配置的時候。

強調一系列相關産品對象設計以便進行聯合使用時。

對于一個産品庫,隻想顯示接口而不是具體的實作的時候。

其核心工廠類不再負責所有的産品撞見,而是将具體工作委托給子類,自身成為一個抽象的工廠角色,僅負責給出工廠類必須實作的接口,而不需要關系具體哪種産品被執行個體化的細節。

        定義一個用于建立對象接口,讓子類來決定執行個體化哪一個類,将類的執行個體化延遲到其子類。

當一個類不知道它所必須建立的對象的類的時候。

當一個類希望由其子類來建立對象的時候。

将對象的内部表象和對象的生産過程分割開來,進而使得一個建造過程具有不同内部表象的産品對象。建造模式使得産品内部表象可以獨立出來變化,客戶不需要知道内部細節,可以強制實行一種分步建造過程。

将一個複雜的對象的建構與它的表現分離,使同樣的建構形式可以得到不同的表示。

将複雜對象的算法需要獨立于對象的組成部分以及裝配方式的時候。

        構造過程允許構造不同的對象表示。

将一個類的接口變為用戶端所希望的接口類型,進而使原先因接口不比對而無法工作的兩個類可以一起工作。

        将某個接口改裝變為所需要類型的接口,也可以是原本不相容的接口适配成相容。

希望使用一個已經存在的類,但是與你所需要的接口有些不吻合時。

希望建立一個可以複用的類,可以與其他已存在或者未存在的類進行協同工作。

将抽象畫和執行個體化解耦,使得兩者可以獨立變化。即降低耦合度。也就是說将抽象化和執行個體化之間的關系使用組合/聚合的關系而非繼承關系,兩者可以獨立的變化。

将抽象部分與它的實作部分分離,使它們可以獨立的變化。

在對于抽象部分和實作部分不希望使用固定的關系。

類的抽象和類的實作都應該都應該可以可以通過生成子類的方式來加以擴充。

對一個抽象的實作部分的修改應對客戶不産生影響。

希望在多個對象之間共享(比如使用引用計數),但是客戶不知道該點。

在職責鍊模式中,很多對象由每一個對象對其下家的引用而連接配接起來的一條鍊。請求在這個鍊上進行傳遞直到鍊上的某一個對象決定處理該請求。對于鍊上的每一個對象成為處理者,處理者有兩個選擇:承擔處理責任揮着将請求傳遞給下家,請求可以不被任何對象處理。

使多個對象都有機會處理請求,進而避免請求發送者和接受者之間的耦合關系。将這些對象連成一條鍊,并且沿着該鍊傳輸,直到有對象對他進行處理。

有對個對象可以處理一個請求,具體是哪個對象處理會在運作時自動确定。

在不明确接受者情況下,向多個對象送出一個請求。

        可以動态的指定那個對象集。

指令模式将一個請求或者操作封裝到一個對象中。指令模式将發出指令和執行指令的責任分割開,委派給不同的對象。指令模式也允許請求方個接受方互相獨立,使得請求方不需要知道接收方的接口等。

将一個請求封裝為一個對象,進而可以使你應不同的請求對客戶進行參數化。對于一些排隊的請求可以進行取消操作。

抽象出待執行的動作以參數化某對象可以使用回調表達這種參數化機制。

        在不同的時刻指定,排列和執行請求。一個 command

對象可以有一個與初始請求無關的生存期。

        支援對于取消,修改操作。

用建構在原語上的高層操作構造一個系統,一個事務封裝了對資料的一組變動,Command模式提供了對事務進行模組化的方法,有一個公共的接口,使得可以使用同一種方式來調用所有的事務。也易于添加新事務以擴充系統。

組合模式間對象組織到樹結構中,可以用來描述整體和部分的關系。組合模式就是一個處理對象的樹結構的模式。

        将對象組合成樹形結構以表示“部分 -

整體”的層次關系,使使用者對于單個對象群組合對象使用具有一緻性。    

        對于對象希望表現出 部分 - 整體

的層次結構。

        希望統一使用組合結構中的所有對象。

裝飾者模式以對用戶端透明的方式來擴充對象功能,是繼承關系的一個替代方案,提供比繼承更多的靈活性。動态給對象添加功能,這些功能也能動态撤銷。常用于對增加一些基本功能的排列組合而産生的非常大量的功能。

動态的給一個對象添加一些額外的職責。就增加功能來說,裝飾者模式比生成子類更為靈活。

在不影響其他的對象情況下,以動态,透明的方式給單個兌現添加職責。

當無法使用類似生成子類的方式進行類的拓展的時候。如有大量的獨立應用,為支援各種組合那麼将出現數量級爆炸的情況,或者類定義被隐藏等不能用于生成子類。

外部與一個子系統的通信必須通過一個統一的門面對象進行。門面模式提供一個更進階的接口使得子系統更容易使用。每一個子系統隻有一個門面模式,此門面模式隻有一個執行個體,即單例模式。整個系統中可以有多種門面類。

為子類系統中的一組接口提供一緻的界面,外觀模式定義一個進階接口以便子類更容易的調用。

當需要為一個非常複雜的子類系統提供一個簡單的接口的時候。

外觀模式提供一個簡單的預設視圖,這一視圖對大多數使用者來說已經OK,而對進階使用者可以繞過外觀層進行所需要的處理。

享元模式以共享的方式高效的支援大量細粒度對象。共享的關鍵是區分内蘊狀态和外蘊狀态。内蘊狀态存儲在享元内部不會随環境的改變而有所不同。外蘊狀态就是随環境的改變而變化的。兩者互相獨立互不影響。将可以共享的狀态和非共享的狀态從正常類裡面區分出來。客戶不可以直接建立共享對象,應當使用一個工廠對象負責建立共享的對象。享元模式可以大幅度的降低記憶體中對象的數量。

運用共享技術有效地支援大量細粒度的對象。

        一個程式中使用了大量的對象。

        由于對象數量造成了大量存儲開銷。

        大多對象的狀态可以變為外部的狀态

        可以使用較少的共享對象來進行處理。

給定一個語言後,解析器模式可以定義出其文法的表示,并提供一個解析器。用戶端可以使用這個解析器來解析該語言中的語句。解析器模式将描述怎樣再有了一個簡單的文法後使用模式設計解析這些語句。該語言是指任何解析器對象能夠解釋的任何組合。在解析器模式中需要定義一個代表文法的指令類的等級結構,每一個指令都有一個對應的解釋。

給定一種語言,定義文法表示,并且在定義一個解析器來轉化該語言。

        簡化文法所需要的邏輯處理,文法簡單。

疊代器模式可以順序通路一個聚集中的元素而不必暴露内部表象。多個對象聚集在一起形成的整體稱之為聚集,聚集對象則是包含一組對象的容器。疊代模式将疊代邏輯封裝到一個獨立的對象中,與本身的聚集對象分離開來。疊代模式簡化了聚集的邏輯思想,将行為獨立分割開來友善調整修改替換。是以疊代算法可以獨立于聚集對象進行變化。

提供一個方法順序通路一個聚合對象中的各個元素而又不暴露該對象的内部表示。

        通路聚合對象,而不希望内部暴露。

        支援對于聚合對象的多種周遊。

        為周遊各種對象提供統一的接口。

中介者模式包裝了一系列對象互相作用的方式,使得這些對象不必互相有明顯的聯系。使耦合變得松散。當某些對象發生改變的時候也不會影響其他的對象之間的作用,保證各個對象之間的作用互相獨立,這邊并不是對象與對象之間,而是作用與作用之間的聯系變得獨立開。中介者模式将多對多的互相作用轉化為一對多的互相作用,将對象的行為和協作抽象畫,把對象的一些小行為與其他對象的互相作用分開處理。

使用中介者來封裝一系列的對象之間的互動,不顯示的表示各個對象的互相引用關系,降低對象之間的耦合度。

定義良好的一組對象需要很複雜的通信方式。進而産生的互相依賴關系但以了解。

一個對象直接對其他很多對象進行通信導緻了難以複用該對象。

需要定制一個分布在各個類中的行為又不想生成太多子類。    

備忘錄對象是一個用來存儲另外一個對象内部狀态的快照對象,在意在不破壞對象封裝的前提下将一個對象的狀态捕捉到,存儲在外部以便可以随時觀察記錄,以便将來可以還原到某一個狀态。

在不破壞封裝性的前提下捕獲一個對象的内部狀态并将該狀态儲存在對象之外來标記。

需要注意必須保持對象的某一時刻狀态并且不對對象造成封裝性的破壞,不制造多餘的暴露接口。

觀察者模式定義一種一對多的狀态,讓多個觀察者同時監聽某一個對象。這個對象主題發生變化的時候會告知所有的觀察者對象,使它們自動更新自己。

定義對象間的一種一對多的依賴關系,當一個對象發生改變的時候,所有依賴于該對象的其他對象都将得到通知,并且被自動更新。

當抽象模型具有兩個方面,其中一個方面依賴于另一個方面,将這兩者分開封裝在獨立的對象中使得他們可以獨立改變以及複用。

當一個對象在改變的時候需要同時改變其他對象,并且這個對象集合有可能會改變。并且不能假定這些對象來增加耦合度。

通過給出一個原型對象來指明所要建立的對象類型,複用這個原型對象來建立出個更多的同類型對象。原型模式允許動态的增加或者減少産品類,可以不需要任何的等級結構,原型模式适用于任何結構。

用原型執行個體來指定對象建立的種類,并且通過拷貝這些原型來建立新的對象。

需要執行個體化的類在運作時候指定。(對于前端的JSer來說,這是最熟悉不過的了)

代理模式給某一個對象提供一個代理對象,并由代理對象控制對象源對象的引用。在某些情況下客戶不想活着不能夠直接引用一個人對象,代理對象在客戶和目标對象中起到中介者的作用,代理對象可以僅僅隻有一個被代理的接口,這時候代理對象不能建立被代理的對象,被代理的對象必須由系統的其他角色代為建立和傳入。

為其他對象提供一種代理來來控制對于某個特定對象的通路或者處理。

在需要使用比較愛通用和複雜的對象指針來代替簡單指針的時候。

單例模式確定每一個類隻有一個執行個體,而且自行的執行個體化并且想整個系統提供該執行個體的接口。單例模式隻有在真正需要單一模式的時候使用。

    結構:

        保證一個類隻有一個執行個體,并提供一個通路它的全局通路點。

當類隻能有一個執行個體,用戶端通過規範的通路點來進行通路。

狀态模式允許一個對象在其内部狀态改變的時候改變行為。使得看上去和改變了類是一樣的。狀态模式将所研究的對象的行為包裝在不同的對象裡,每一個狀态都屬于一個抽象狀态類的一個子類。狀态模式需要對每一個系統可能取得的狀态建立一個狀态類的子類。當系統的狀态發生變化的時候,系統便改變所選的子類。

允許一個對象在其内部狀态改變的時候改變行為。

一個對象的行為取決于它的狀态,并且必須在運作時刻根據狀态來改變行為。

政策模式針對一組算法,将每一個算法封裝到具有共同接口的獨立類中,進而使得它們可以互相替換。政策模式使得算法可以在不影響用戶端的情況下發生變化。将行為與環境分開。環境類負責維持和查詢行為類,各個算法在具體的政策類中提供。是以算法的增減不會影響環境和用戶端。

        定義一系列算法進行單獨封裝,并且是它們可以互相替換,使算法獨立于客戶變化而變化。

許多相關的類,僅僅是行為上有所差别,政策模式可以實作在多個行為中選取一個來配置一個類。

模闆方法模式準備一個抽象類,将部分邏輯以及具體方法以構造子類的方式實作,然後聲明一些抽象方法來事子類實作剩餘的邏輯。不同的子類可以以不同的方式來實作這些抽象方法,進而對剩餘邏輯的實作。先定制一個頂級的邏輯架構,而将邏輯的細節劉诶具體的子類去實作。

定義一個算法骨架,将一些步驟延遲到子類中,使子類可以不改變一個算法結構卻可以重新定義算法的步驟。

一次性實作算法的不變部分,将可變部分留在子類中實作。

一個類定義多種行為,并且這些行為在這個類中的操作是以多個條件語句的形式出現。

通路者模式的目的是封裝一些施加于某種資料結構元素之上的操作。一旦操作需要做修改,接受設個操作的資料結構可以保持不變。适用于資料結構相對未定的系統,将資料結構和作用于結構上的操作耦合解脫開使得操作可以相對自由的演化。通路者模式使得增加新的操作變得更為容易。通路者模式将有關的行為集中到一個通路者對象中,而不是分散在一個個環節節點中。當使用通路者模式的時候要将盡可能多的對象浏覽邏輯放在通路者類中,而不是子類中。

表示一個作用于某個對象結構中的各元素的操作,使你可以在不改變各個元素的類的情況下定義作用于這些元素的新的操作。

一個對象結構中包含多個類對象,具有不同的接口,而你希望對這些對象實施一些依賴于具體某個類的操作。

需要對一個對象結構中的對象進行很多不同的并且不想關的操作,這些操作需要避免污染對象。通路者模式可以将相關的操作集中放入一個類中,被對象結構所共享,進而對象結構中的每個子對象都可以被共享到。