<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 前言 設計模式(design pattern)是一套被反復使用、多數人知曉、經過分類編目的優秀代碼設計經驗的總結。關鍵詞:重用代碼、工程化、面向對象。設計模式起源于建筑設計學,最先由 [*Gang of Four*](http://baike.baidu.com/link?url=zWA56qEFuEzh6ikR326s4zGIw1ktjeXXFKMn8G-rgyp15KK72aMfW9k5VSiWW7ZhkDhpYgY0dd0_hHXDHP2pRa)?提升到了理論高度。 可復用面向對象體系分為兩大系統:工具箱和框架。Java中的API屬于工具箱(toolkit),Java EE (Enterprise Edition)屬于框架(Framework)。設計模式是大神們在構造 Java EE 的時候的重要理論依據,學習設計模式有助于深入了解 Java EE。 我最近在[*實驗樓*](https://www.shiyanlou.com/courses/100) 學習完了一門課程《Java進階之設計模式》。截止至2015年12月16日,我已經在實驗樓網站有效學習了960分鐘,完整學習了5門課程。功夫在課外,我認為實驗樓是一個能夠開闊視野,快速入門新領域的地方。其主要特點是:課程設置廣泛,內容深入淺出,提供linux環境。 GOF最早提出的設計模式總共有23個,分為三類型:創建型模式(5個),構造型模式(7個),行為型模式(11個)。后來,人們總結出了更多的設計模式,[參考wikipedia](https://en.wikipedia.org/wiki/Software_design_pattern) - 創建型:單例模式、工廠方法模式、抽象工廠模式、建造者模式、原型模式 - 構造性:適配器模式、裝飾模式、代理模式、組合模式、橋梁模式、外觀模式、享元模式 - 行為型:模板方法模式、命令模式、責任鏈模式、迭代器模式、中介者模式、觀察者模式、訪問者模式、狀態模式、解釋器模式 實驗樓里面講解了其中的6個,這6個大體上是23個中使用頻率最高的6個:工廠方法模式、抽象工廠模式、單例模式、適配器模式、裝飾者模式、觀察者模式。**我下面將首先簡單介紹設計原則,然后小結一下上述常用6種模式**。我寫本篇博客使用的參考資料包括:實驗樓的課程、《Head First Design Patterns》、《設計模式(Java版)》、wikipedia、百度百科。 # 設計原則 - 開閉原則(OCP):open for extension, but close for modification。在設計一個模塊的時候,應當使這個模塊可以在不被修改的前提下被擴展。這個是最最基礎的原則。 - 單一職責原則(SRP):never be more than one reason for a class to change。專注做一件事情,僅有一個引起變化的原因,“職責”可以理解成“變化的原因”。唯有專注,才能夠保證對象的高內聚;唯有單一,才能保證對象的細粒度。 - 里氏替換原則(LSP):Liskov提出:” Let?Φ(x) be a property provable about objects x of type T. Then ?Φ(y) should be true for objects y of type S, where S is a subtype of T.” 這里的type,我理解成class。子類的對象可以無條件地替換父類的對象,并且不引起程序的改變。或者說:只要父類能出現的地方,子類就可以出現。 - 依賴倒置原則(DIP):High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. 即高層模塊不依賴低層模塊;高、低層模塊都依賴其抽象;抽象不依賴細節,反過來細節依賴抽象。在JAVA中,所謂的抽象,就是接口或者抽象類;所謂細節,就是就實現類(能夠實例化生成對象的類)。為什么說“倒置”?因為在傳統的面向過程的設計中,高層次的模塊依賴于低層次的模塊,抽象層依賴于具體層(這樣不好),倒置過來后,就成為了面向對象設計的一個原則了(這樣子好)。 - 接口隔離原則(ISP):The dependency of one class to another should depend on the smallest possible interface. 類間的依賴關系應該建立在最小的接口上面。客戶端不應該依賴他不需要的接口,只提供調用者需要的方法,屏蔽不需要的方法。一個接口代表一個角色,使用多個專門的接口比使用單一的總接口更好。 - 迪米特法則(LoD)又稱最少知識原則(LKP): Each unit should only talk to its friends; don’t talk to strangers. Only talk to your immediate friends. Each unit should have only limited knowledge about other units. 曾經在美國有一個項目叫做Demeter。LoD is a specific case of loose coupling.此原則的核心觀念就是類之間的弱耦合,在這種情況下,類的復用率才可以提升。 # 工廠方法模式 *Head First* (簡稱*HF* ) 說:There is more to making objects than just using the **new** operator. Instantiation is an activity that shouldn’t always be done in public and can often lead to coupling problems. 這就是工廠方法的來源。 首先簡單提一下:簡單工廠。*HF* : The Simple Factory isn’t actually a Design Pattern; it’s more of a programming idiom. 代碼實現:把 new操作的過程封裝到一個class SimpleFactory 的一個方法中。這個方法有一個參數,這個參數決定如何new。 簡單工廠進行抽象化,得到工廠方法模式。工廠方法模式**定義**:Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method let a class defer instantiation to subclasses. 簡而言之**,一個工廠父類作為“總管”,管理旗下的具體工廠子類,new 操作在具體工廠子類里面**。定義中”defer”的意思是:父類不立刻進行new操作,而是交給子類進行new操作。 **代碼**:[工廠方法模式例子Java源代碼 (推薦在新標簽頁打開)](http://blog.csdn.net/u013390476/article/details/50377680)。我改編自*HF* 的pizza例子(我本學期早上流行吃包子) **小結**:(看完代碼之后再看小結) 一個工廠子類,看上去很像一個簡單工廠。確實如此,不過這一些工廠子類都繼承自同一個工廠父類,需要實現同一個抽象方法createBaoZi,然后利用多態性。簡單工廠像是一個“一錘子買賣”,而工廠方法模式則搭建了一個框架,讓工廠子類決定生產那一個具體產品。工廠方法模式更加抽象,更具有通用性,耦合度更低。 在Main類里面,**new 一個工廠子類,把其引用賦給一個工廠父類的引用**。從代碼層面可以看出,當需要擴充新的工廠的時候,增加一個繼承工廠父類的子類就行了。Main類里面的那個**工廠父類的引用無需改變**。更進一步說,Main類里面的所有的用到工廠父類的引用的地方都無需改變,這就是體現了開閉原則的中的“close for modification” # 抽象工廠模式 抽象工廠模式**定義**:Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. 首先需要知道一個概念“a family of products”,翻譯成“產品族”。*Head First* : Factory Method provides an abstract interface for creating **one product**. Abstract Factory provides an abstract interface for creating **a family of products**. **產品族:**假設有三類抽象產品:手機、筆記本、平板。手機分為兩個具體產品:iphone 6s和華為Mate8;電腦分為兩個具體產品:Macbook Pro和Surface Book;平板分為iPad Air和Surface 3。那么從手機里面二選一,從筆記本里面二選一,從平板里面二選一,總共產生了8個不同的產品族。比如”iphone 6s + Macbook Pro + iPad Air”就是8個產品族中的1個(土豪!)。 **代碼**:[抽象工廠模式例子Java源代碼 (推薦在新標簽頁打開)](http://blog.csdn.net/u013390476/article/details/50396360) **小結:**抽象工廠模式是對工廠方法的進一步抽象。是把一組具有同一主題的單獨的工廠封裝起來。抽象工廠可以看成是”工廠的工廠“,抽象工廠中的一個抽象方法,很像一個工廠方法模式。一個工廠有多抽象工廠,就像是有多個工廠方法模式。 # 單例模式 有時候存在這種需求:強制要求某個類只能實例化一個對象, one and only one. 單例模式解決了這種需求,其**定義**是:Singleton Pattern ensures a class has only one instance, and provide a global point of access to it. 應用場景: - 要求生成唯一序列號的環境 - 需要共享訪問點或共享數據,例如CSDN每一篇博客都有一個計數器,用來統計閱讀人數,使用單例模式保持計數機的值 - 需要創建的對象消耗大量資源,比如IO和數據庫資源 - 需要定義大量的靜態常量或者靜態方法(工具類)的環境,比如Java基礎類庫中的java.lang.Runtime類 仔細想想,如果使用全局變量,則可以實現定義中的后半句,但是無法實現定義中的前半句,而且使用全局變量會污染命名空間。 **代碼:**[單例模式Java源代碼,可以在新標簽頁打開](http://blog.csdn.net/u013390476/article/details/50405825#t4) **小結:**單例模式,顧名思義,讓一個類**有且只有一個**實例對象。這樣做可以達到節約或者控制系統資源的目的。在代碼層面,其最主要的特征是其**構造函數是私有的**。次要特點是:數據成員Singleton的實例引用是**靜態**的,而且有一個**靜態**的getInstance()方法,用來負責 new Singleton() 和返回 Singleton的實例引用。 # 觀察者模式 這是一個常用的行為型模式,又稱為“發布者——訂閱者”模式。發布者比如報社,訂閱者比如老百姓。清晨爺爺奶奶們出去晨練,看見一個賣報紙的小男孩在街上大聲吆喝:“今天的報紙來了!”,然后爺爺奶奶們得到通知,都去買了報紙。報社是主題(Subject),爺爺奶奶們是觀察者(Observer),賣報紙的小男孩,負責告訴Observer:“Subject更新了!” **定義**:The Observation Pattern defines a one-to-many dependency between objects so that when one objects changes state, all of its dependents are notified and updated automatically. **代碼**:[觀察者模式Java代碼,可以在新標簽頁打開](http://blog.csdn.net/u013390476/article/details/50428014) **小結**:定義中的one就是Subject, many就是Observers;one就是發布者,many就是訂閱者;one就是事件源,many就是監聽者。多個觀察者(Observer)“圍觀”一個被觀察者(Subject),可以說被觀察者是萬眾矚目的焦點。觀察者和被觀察者之間是抽象耦合(類圖在上面的鏈接里),它們屬于不同的抽象化層次,非常容易擴展。使用場景是:關聯行為;事件多級觸發;消息隊列等。 # 適配器模式 這是一個結構型模式。周邊適配器到處都是,比如手機充電器就是一個把插座上面的兩孔國標插座,轉換成USB接口。去了美國,怎么給我的榮耀手機充電?那就那一個適配器,把美國的兩孔/三孔美標插座轉換成兩孔國標插座。 **定義**:The Adapter Pattern converts the interface of a class into another interface the client expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. 在上面的情景中,榮耀手機就是定義中的“client”;兩孔國標接口就是”interface the client expect”;美國的兩孔/三孔美標插座就是定義中 “converts the interface of a class”中的”interface”;Adapter 負責動詞”convert”。 **代碼**:[適配器模式 Java源代碼,可以在新標簽頁中打開](http://blog.csdn.net/u013390476/article/details/50444955) **小結**:適配器Adapter的核心,是**實現Target接口, 組合Adaptee接口**。通過實現和組合,這兩種類與類之間的關系,把兩個本不兼容的類(Target 和 Adaptee)聯系在一起。增強了類的透明性,松耦合,提高了類的復用,增強了代碼的靈活性。 # 裝飾者模式 這是一個結構型模式。 很多情況下,需要擴展功能,增加職責。如果說生成子類是靜態的添加額外的職責的話,那么裝飾者模式則提供了一種動態的方法,較為靈活。 **定義**:attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. **代碼**:[裝飾者模式 Java源代碼,可以在新標簽頁中打開](http://blog.csdn.net/u013390476/article/details/50550256) **小結**:關鍵是**Decorator同時繼承和組合Component**,Component是被裝飾者裝飾的對象。裝飾者和被裝飾者可以獨立發展,耦合度很低,很好的符合了開閉原則,是繼承關系的一種替代方案。或者說,是一種對繼承關系的有力的補充,可以解決類膨脹的問題。Java.IO就是參照裝飾者模式設計的。 # 一點感悟 我現在是計算機科學與技術(CS)的大三上學期。設計模式的學習,我都是利用課外時間。我學習設計模式的初衷,除了見見世面之外,就是學習Java(我大一大二都是寫C++,大三上學期才學Java),可謂一箭雙雕。我下載了《Head First Design Patterns》在GitHub上的樣例代碼, which is written in Java。我一邊看書,一邊看代碼,抄代碼,一邊改編代碼。理論與敲代碼結合,快速提升、強化基本能力。 - 敲了不少Java代碼,對Java的”感覺”加深了,代碼是需要積累的 - 我在eclipse裝一個插件,用來繪制UML類圖。我對eclipse的”感覺”加深了,體會到了插件的強大威力 - 繼承,多態。以前寫C++代碼,只用封裝,很少用繼承和多態。畢竟平時主要在寫”小算法”,沒有涉及到大的宏觀層面的設計。在設計模式中,大量運用繼承(還有實現),多態 - decouple。這個詞在*HF* 中高頻率出現。降低耦合,面向接口,可以增強整個程序的擴展性,便于維護,適合多團隊多人合作開發 - 通過幾個設計模式,慢慢體會了設計模式中的6條原則,這些原則不是”教條主義“,不能刻板遵守。而是要慢慢把這些思想融入到程序設計中 - 關于算法和設計模式。網上看到一些評論,有一個評論很生動:算法像是”單兵作戰和武器裝備“,設計模式像是”仗列的陣型“。算法用來解決具體問題,設計模式用來合理的把算法隔離到各個正確的地方去。真正體會設計模式,還是需要很多年的實踐積累 設計模式的博客就寫到這里。最近在較短時間內,集中學習了6個常用設計模式,收獲頗豐。**掌握了基本思想和方法**,在以后的學習和實踐中,遇到新的需要使用的模式,我就能快速學會和運用。 [一個設計模式學習網站](http://www.runoob.com/design-pattern/design-pattern-tutorial.html)
                  <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>

                              哎呀哎呀视频在线观看