23種設(shè)計(jì)模式

概述

設(shè)計(jì)模式代表了最佳的實(shí)踐,通常被有經(jīng)驗(yàn)的面向?qū)ο蟮能浖_(kāi)發(fā)人員所采用。設(shè)計(jì)模式是軟件開(kāi)發(fā)人員針對(duì)某一類(lèi)問(wèn)題的最優(yōu)解決方案,是從許多優(yōu)秀的軟件系統(tǒng)中總結(jié)出來(lái)的。

使用設(shè)計(jì)模式的目的:為了提高代碼的可重用性、讓代碼更容易被他人理解、保證代碼可靠性,讓代碼編寫(xiě)更加工程化。

Java中設(shè)計(jì)模式通常有23種。

1.大致可分為3類(lèi):創(chuàng)建型、行為型和結(jié)構(gòu)型。

設(shè)計(jì)模式的六大原則

2.開(kāi)閉原則

開(kāi)閉原則的意思是:對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。簡(jiǎn)言之,是為了使程序的擴(kuò)展性好,易于維護(hù)和升級(jí)。想要達(dá)到這樣的效果,我們需要使用接口和抽象類(lèi)

3.里氏轉(zhuǎn)換原則

里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。里氏代換原則中說(shuō),任何基類(lèi)可以出現(xiàn)的地方,子類(lèi)一定可以出現(xiàn)。LSP 是繼承復(fù)用的基石,只有當(dāng)派生類(lèi)可以替換掉基類(lèi),且軟件單位的功能不受到影響時(shí),基類(lèi)才能真正被復(fù)用,而派生類(lèi)也能夠在基類(lèi)的基礎(chǔ)上增加新的行為。里氏代換原則是對(duì)開(kāi)閉原則的補(bǔ)充。實(shí)現(xiàn)開(kāi)閉原則的關(guān)鍵步驟就是抽象化,而基類(lèi)與子類(lèi)的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。

依賴(lài)倒轉(zhuǎn)原則

這個(gè)原則是開(kāi)閉原則的基礎(chǔ),具體內(nèi)容:針對(duì)接口編程,依賴(lài)于抽象而不依賴(lài)于具體

4. 接口隔離原則

這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好。它還有另外一個(gè)意思是:降低類(lèi)之間的耦合度。由此可見(jiàn),其實(shí)設(shè)計(jì)模式就是從大型軟件架構(gòu)出發(fā)、便于升級(jí)和維護(hù)的軟件設(shè)計(jì)思想,它強(qiáng)調(diào)降低依賴(lài),降低耦合。

5.迪米特法則,又稱(chēng)最少知道原則

最少知道原則是指:一個(gè)實(shí)體應(yīng)當(dāng)盡量少地與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立。

6. 合成復(fù)用原則

合成復(fù)用原則是指:盡量使用合成/聚合的方式,而不是使用繼承。

創(chuàng)建型模式

創(chuàng)建型模式設(shè)計(jì)對(duì)象的實(shí)例化,特點(diǎn)是不讓用戶(hù)代碼依賴(lài)于對(duì)象的創(chuàng)建或排列方式,避免用戶(hù)直接用new創(chuàng)建對(duì)象。

創(chuàng)建型模式有5種。

工廠模式、抽象工廠模式、建造者模式、原型模式和單列模式

工廠模式

工廠模式是java中最常見(jiàn)的設(shè)計(jì)模式之一,它提供了一種創(chuàng)建對(duì)象的最佳方式。在工廠模式中,我們?cè)趧?chuàng)建對(duì)象時(shí)不會(huì)對(duì)客戶(hù)端暴露創(chuàng)建邏輯,并且是通過(guò)使用一個(gè)共同的接口來(lái)指向新創(chuàng)建的對(duì)象。

目的:定義一個(gè)創(chuàng)建對(duì)象的接口,讓子類(lèi)自己去決定實(shí)例化那個(gè)產(chǎn)品類(lèi),也就是子類(lèi)去實(shí)現(xiàn)接口

注意事項(xiàng):

作為一種創(chuàng)建類(lèi)模式,在任何需要生成復(fù)雜對(duì)象的地方,都可以使用工廠方法模式。有一點(diǎn)需要注意的地方就是復(fù)雜對(duì)象適合使用工廠模式,而簡(jiǎn)單對(duì)象,特別是只需要通過(guò) new 就可以完成創(chuàng)建的對(duì)象,無(wú)需使用工廠模式。如果使用工廠模式,就需要引入一個(gè)工廠類(lèi),會(huì)增加系統(tǒng)的復(fù)雜度。

抽象工廠模式

抽象工廠模式(Abstract

Factory Pattern)是圍繞一個(gè)超級(jí)工廠創(chuàng)建其他工廠。該超級(jí)工廠又稱(chēng)為其他工廠的工廠。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。

在抽象工廠模式中,接口是負(fù)責(zé)創(chuàng)建一個(gè)相關(guān)對(duì)象的工廠,不需要顯式指定它們的類(lèi)。每個(gè)生成的工廠都能按照工廠模式提供對(duì)象。

意圖:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴(lài)對(duì)象的接口,而無(wú)需指定它們具體的類(lèi)。

兩種設(shè)計(jì)模式主要的區(qū)別在于產(chǎn)品,工廠模式是用來(lái)創(chuàng)建同一個(gè)產(chǎn)品的不同類(lèi)型的,而抽象工廠模式是用來(lái)創(chuàng)建不同類(lèi)的產(chǎn)品。一般來(lái)說(shuō),產(chǎn)品種類(lèi)單一,適合用工廠模式;如果有多個(gè);多種類(lèi)型時(shí),通過(guò)抽象工廠模式來(lái)創(chuàng)建時(shí)很合適的。

單例模式

單例模式是Java最簡(jiǎn)單的設(shè)計(jì)模式,這種設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。

這種設(shè)計(jì)模式涉及到一個(gè)單一的類(lèi),該類(lèi)負(fù)責(zé)創(chuàng)建自己的對(duì)象同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建。這個(gè)類(lèi)提供了一種訪問(wèn)其唯一的對(duì)象的方式,可以直接訪問(wèn),不需要實(shí)例化該類(lèi)的對(duì)象。

注意:

單例類(lèi)只能有一個(gè)實(shí)例。

單例類(lèi)必須自己創(chuàng)建自己的唯一實(shí)例

單例類(lèi)必須給所有其他對(duì)象提供這一實(shí)例關(guān)鍵代碼:構(gòu)造函數(shù)是私有的。

建造者模式

建造者模式使用多個(gè)簡(jiǎn)單的對(duì)象一步步構(gòu)建成復(fù)雜的對(duì)象。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型設(shè)計(jì)模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。

一個(gè)Builder類(lèi)會(huì)一步一步構(gòu)造最終的對(duì)象。該Builder類(lèi)是獨(dú)立于其他對(duì)象的。

原型模式

原型模式是用于創(chuàng)建重復(fù)的對(duì)象,同時(shí)又能保證性能。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。

這種設(shè)計(jì)模式是實(shí)現(xiàn)了一個(gè)原型接口,該接口用于創(chuàng)建當(dāng)前對(duì)象的克隆。當(dāng)直接創(chuàng)建對(duì)象的代價(jià)比較大時(shí),則采用這種模式。

意圖:用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi),并且通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象。

關(guān)鍵代碼:實(shí)現(xiàn)cloneable接口,重寫(xiě)clone()方法。當(dāng)通過(guò)new產(chǎn)生一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問(wèn)權(quán)限,或者類(lèi)初始化消耗非常多的資源,這個(gè)資源包括數(shù)據(jù)、硬件資源時(shí)??梢允褂迷湍J?/p>

裝飾者模式

裝飾器模式(Decorator Pattern)允許向一個(gè)現(xiàn)有的對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。這種類(lèi)型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類(lèi)的一個(gè)包裝。

這種模式創(chuàng)建了一個(gè)裝飾類(lèi),用來(lái)包裝原有的類(lèi),并在保持類(lèi)方法簽名完整性的前提下,提供了額外的功能。

意圖:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō),裝飾器模式相比生成子類(lèi)更為靈活。

主要解決:一般的,我們?yōu)榱藬U(kuò)展一個(gè)類(lèi)經(jīng)常使用繼承方式實(shí)現(xiàn),由于繼承為類(lèi)引入靜態(tài)特征,并且隨著擴(kuò)展功能的增多,子類(lèi)會(huì)很膨脹。

何時(shí)使用:在不想增加很多子類(lèi)的情況下擴(kuò)展類(lèi)。

舉例

裝飾模式:以對(duì)客戶(hù)端透明的方式擴(kuò)展對(duì)象的功能,是繼承關(guān)系的一個(gè)替代方案;代理模式:給一個(gè)對(duì)象提供一個(gè)代理對(duì)象,并有代理對(duì)象來(lái)控制對(duì)原有對(duì)象的引用;

裝飾模式應(yīng)該為所裝飾的對(duì)象增強(qiáng)功能;代理模式對(duì)代理的對(duì)象施加控制,并不提供對(duì)象本身的增強(qiáng)功能

裝飾者模式的定義:動(dòng)態(tài)的將責(zé)任附加到被裝飾者對(duì)象上,用于擴(kuò)展對(duì)象的功能。比繼承的靈活性大。典型的如Java IO的設(shè)計(jì)即是裝飾者模式的典型應(yīng)用。  代理模式模式的定義:對(duì)其他對(duì)象進(jìn)行代理,以控制對(duì)被代理對(duì)象的訪問(wèn)。Spring的為業(yè)務(wù)邏輯層方法生成的代理類(lèi),主要進(jìn)行一些事務(wù)控制等。由定義可以看出裝飾的責(zé)任是擴(kuò)展功能 ,而代理主要控制訪問(wèn)。

動(dòng)態(tài)代理技術(shù):動(dòng)態(tài)代理技術(shù)就是用來(lái)產(chǎn)生一個(gè)對(duì)象的代理對(duì)象。

代理對(duì)象的價(jià)值:

1.代理對(duì)象存在的價(jià)值主要用于攔截對(duì)真實(shí)業(yè)務(wù)對(duì)象的訪問(wèn)。2.代理對(duì)象應(yīng)該具有和目標(biāo)對(duì)象(真實(shí)業(yè)務(wù)對(duì)象)相同的方法。

Java中的代理:java.lang.reflect.Proxy類(lèi)

要生成某一個(gè)對(duì)象的代理對(duì)象,這個(gè)代理對(duì)象通常也要編寫(xiě)一個(gè)類(lèi)來(lái)生成,java在JDK1.5之后提供了一個(gè)"java.lang.reflect.Proxy"類(lèi),通過(guò)"Proxy"類(lèi)提供的一個(gè)newProxyInstance方法用來(lái)創(chuàng)建一個(gè)對(duì)象的代理對(duì)象。

newProxyInstance方法用來(lái)返回一個(gè)代理對(duì)象,這個(gè)方法總共有3個(gè)參數(shù),ClassLoader loader用來(lái)指明生成代理對(duì)象使用哪個(gè)類(lèi)裝載器,Class<?>[]

interfaces用來(lái)指明生成哪個(gè)對(duì)象的代理對(duì)象,通過(guò)接口指定,InvocationHandler h用來(lái)指明產(chǎn)生的這個(gè)代理對(duì)象要做什么事情


注意:在java中規(guī)定,要想產(chǎn)生一個(gè)對(duì)象的代理對(duì)象,那么這個(gè)對(duì)象必須要有一個(gè)接口

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容