1. 程式人生 > >面試題7.java常用的設計模式有哪些

面試題7.java常用的設計模式有哪些

設計模式主要分三個型別:建立型、結構型和行為型。 

策略模式,代理模式,單例模式,多例模式,工廠方法模式,抽象工廠模式,門面模式,介面卡模式,模板方法模式,建造者模式,橋樑模式,命令模式,裝飾模式,迭代器模式,組合模式,觀察者模式,責任鏈模式,訪問者模式,狀態模式,原型模式,中介者模式,直譯器模式,亨元模式,備忘錄模式

保證一個類只有一個例項,並提供一個訪問它的全域性訪問點 

  • Abstract Factory,抽象工廠:

提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們的具體類。 

  • Factory Method,工廠方法:

定義一個用於建立物件的介面,讓子類決定例項化哪一個類,Factory Method使一個類的例項化延遲到了子類。 

  • Builder,建造模式:

將一個複雜物件的構建與他的表示相分離,使得同樣的構建過程可以建立不同的表示。 

用原型例項指定建立物件的種類,並且通過拷貝這些原型來建立新的物件。 

行為型有: 

提供一個方法順序訪問一個聚合物件的各個元素,而又不需要暴露該物件的內部表示。 

七.Observer,觀察者模式

定義物件間一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知自動更新。 

Template Method,模板方法:

定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中,TemplateMethod使得子類可以不改變一個演算法的結構即可以重定義該演算法得某些特定步驟。 

將一個請求封裝為一個物件,從而使你可以用不同的請求對客戶進行引數化,對請求排隊和記錄請求日誌,以及支援可撤銷的操作。 

允許物件在其內部狀態改變時改變他的行為。物件看起來似乎改變了他的類。 

定義一系列的演算法,把他們一個個封裝起來,並使他們可以互相替換,本模式使得演算法可以獨立於使用它們的客戶。 

  • China of Responsibility,職責鏈模式:

使多個物件都有機會處理請求,從而避免請求的送發者和接收者之間的耦合關係

  • Mediator,中介者模式:

用一箇中介物件封裝一些列的物件互動。 

表示一個作用於某物件結構中的各元素的操作,它使你可以在不改變各元素類的前提下定義作用於這個元素的新操作。 

  • Interpreter,直譯器模式:

給定一個語言,定義他的文法的一個表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。 

在不破壞物件的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。 

結構型有: 

  • Composite,組合模式:

將物件組合成樹形結構以表示部分整體的關係,Composite使得使用者對單個物件和組合物件的使用具有一致性。 

  • Facade,外觀模式:

為子系統中的一組介面提供一致的介面,fa?ade提供了一高層介面,這個介面使得子系統更容易使用。 

  • Proxy,代理模式

為其他物件提供一種代理以控制對這個物件的訪問 

二十、Adapter,介面卡模式:

將一類的介面轉換成客戶希望的另外一個介面,Adapter模式使得原本由於介面不相容而不能一起工作那些類可以一起工作。 

二十一、Decrator,裝飾模式:

動態地給一個物件增加一些額外的職責,就增加的功能來說,Decorator模式相比生成子類更加靈活。 

二十二、Bridge,橋模式:

將抽象部分與它的實現部分相分離,使他們可以獨立的變化。 

二十三、Flyweight,享元模式

1.單例模式

    確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。

使用場景:

● 要求生成唯一序列號的環境;

● 在整個專案中需要一個共享訪問點或共享資料,例如一個Web頁面上的計數器,可以不用把每次重新整理都記錄到資料庫中,使用單例模式保持計數器的值,並確保是執行緒安全的;

● 建立一個物件需要消耗的資源過多,如要訪問IO和資料庫等資源;

● 需要定義大量的靜態常量和靜態方法(如工具類)的環境,可以採用單例模式(當然,也可以直接宣告為static的方式)。

2.工廠模式

    定義一個用於建立物件的介面,讓子類決定例項化哪一個類。工廠方法使一個類的例項化延遲到其子類。

簡單工廠模式:

一個模組僅需要一個工廠類,沒有必要把它產生出來,使用靜態的方法

多個工廠類:

每個人種(具體的產品類)都對應了一個建立者,每個建立者獨立負責建立對應的產品物件,非常符合單一職責原則

代替單例模式:

單例模式的核心要求就是在記憶體中只有一個物件,通過工廠方法模式也可以只在記憶體中生產一個物件

延遲初始化:

ProductFactory負責產品類物件的建立工作,並且通過prMap變數產生一個快取,對需要再次被重用的物件保留

使用場景:jdbc連線資料庫,硬體訪問,降低物件的產生和銷燬

3.抽象工廠模式

        為建立一組相關或相互依賴的物件提供一個介面,而且無須指定它們的具體類。

使用場景:

● 多個子類有公有的方法,並且邏輯基本相同時。

● 重要、複雜的演算法,可以把核心演算法設計為模板方法,周邊的相關細節功能則由各個子類實現。

● 重構時,模板方法模式是一個經常使用的模式,把相同的程式碼抽取到父類中,然後通過鉤子函式(見“模板方法模式的擴充套件”)約束其行為。

5.建造者模式

        將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

使用場景:

● 相同的方法,不同的執行順序,產生不同的事件結果時,可以採用建造者模式。

● 多個部件或零件,都可以裝配到一個物件中,但是產生的執行結果又不相同時,則可以使用該模式。

● 產品類非常複雜,或者產品類中的呼叫順序不同產生了不同的效能,這個時候使用建造者模式非常合適。

建造者模式與工廠模式的不同:

建造者模式最主要的功能是基本方法的呼叫順序安排,這些基本方法已經實現了,順序不同產生的物件也不同;

工廠方法則重點是建立,建立零件是它的主要職責,組裝順序則不是它關心的。

6.代理模式

        為其他物件提供一種代理以控制對這個物件的訪問。

普通代理和強制代理:

普通代理就是我們要知道代理的存在,也就是類似的GamePlayerProxy這個類的存在,然後才能訪問;

強制代理則是呼叫者直接呼叫真實角色,而不用關心代理是否存在,其代理的產生是由真實角色決定的。

普通代理:

在該模式下,呼叫者只知代理而不用知道真實的角色是誰,遮蔽了真實角色的變更對高層模組的影響,真實的主題角色想怎麼修改就怎麼修改,對高層次的模組沒有任何的影響,只要你實現了介面所對應的方法,該模式非常適合對擴充套件性要求較高的場合。

強制代理:

強制代理的概念就是要從真實角色查詢到代理角色,不允許直接訪問真實角色。高層模組只要呼叫getProxy就可以訪問真實角色的所有方法,它根本就不需要產生一個代理出來,代理的管理已經由真實角色自己完成。

動態代理:

根據被代理的介面生成所有的方法,也就是說給定一個介面,動態代理會宣稱“我已經實現該介面下的所有方法了”。

兩條獨立發展的線路。動態代理實現代理的職責,業務邏輯Subject實現相關的邏輯功能,兩者之間沒有必然的相互耦合的關係。通知Advice從另一個切面切入,最終在高層模組也就是Client進行耦合,完成邏輯的封裝任務。

動態代理呼叫過程示意圖:

動態代理的意圖:橫切面程式設計,在不改變我們已有程式碼結構的情況下增強或控制物件的行為。 

首要條件:被代理的類必須要實現一個介面。

7.原型模式

        用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。

使用原型模式的優點:

● 效能優良

原型模式是在記憶體二進位制流的拷貝,要比直接new一個物件效能好很多,特別是要在一個迴圈體內產生大量的物件時,原型模式可以更好地體現其優點。

● 逃避建構函式的約束

這既是它的優點也是缺點,直接在記憶體中拷貝,建構函式是不會執行的(參見13.4節)。

使用場景:

● 資源優化場景

類初始化需要消化非常多的資源,這個資源包括資料、硬體資源等。

● 效能和安全要求的場景

通過new產生一個物件需要非常繁瑣的資料準備或訪問許可權,則可以使用原型模式。

● 一個物件多個修改者的場景

一個物件需要提供給其他物件訪問,而且各個呼叫者可能都需要修改其值時,可以考慮使用原型模式拷貝多個物件供呼叫者使用。

淺拷貝和深拷貝:

淺拷貝:Object類提供的方法clone只是拷貝本物件,其物件內部的陣列、引用物件等都不拷貝,還是指向原生物件的內部元素地址,這種拷貝就叫做淺拷貝,其他的原始型別比如int、long、char、string(當做是原始型別)等都會被拷貝。

注意:使用原型模式時,引用的成員變數必須滿足兩個條件才不會被拷貝:一是類的成員變數,而不是方法內變數;二是必須是一個可變的引用物件,而不是一個原始型別或不可變物件。

深拷貝:對私有的類變數進行獨立的拷貝    

  如:thing.arrayList = (ArrayList<String>)this.arrayList.clone();

8.中介者模式

        用一箇中介物件封裝一系列的物件互動,中介者使各物件不需要顯示地相互作用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。

使用場景:

中介者模式適用於多個物件之間緊密耦合的情況,緊密耦合的標準是:在類圖中出現了蜘蛛網狀結構,即每個類都與其他的類有直接的聯絡。

9.命令模式

        將一個請求封裝成一個物件,從而讓你使用不同的請求把客戶端引數化,對請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢復功能。

使用場景:

認為是命令的地方就可以採用命令模式,例如,在GUI開發中,一個按鈕的點選是一個命令,可以採用命令模式;模擬DOS命令的時候,當然也要採用命令模式;觸發-反饋機制的處理等

10.責任鏈模式

        使多個物件都有機會處理請求,從而避免了請求的傳送者和接受者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有物件處理它為止。

抽象的處理者實現三個職責:

一是定義一個請求的處理方法handleMessage,唯一對外開放的方法;

二是定義一個鏈的編排方法setNext,設定下一個處理者;

三是定義了具體的請求者必須實現的兩個方法:定義自己能夠處理的級別getHandlerLevel和具體的處理任務echo。

注意事項:

鏈中節點數量需要控制,避免出現超長鏈的情況,一般的做法是在Handler中設定一個最大節點數量,在setNext方法中判斷是否已經是超過其閾值,超過則不允許該鏈建立,避免無意識地破壞系統性能。

11.裝飾模式

        動態地給一個物件新增一些額外的職責。就增加功能來說,裝飾模式相比生成子類更為靈活。

使用場景:

● 需要擴充套件一個類的功能,或給一個類增加附加功能。

● 需要動態地給一個物件增加功能,這些功能可以再動態地撤銷。

● 需要為一批的兄弟類進行改裝或加裝功能,當然是首選裝飾模式。

12.策略模式

        定義一組演算法,將每個演算法都封裝起來,並且使它們之間可以互換。

使用場景:

● 多個類只有在演算法或行為上稍有不同的場景。

● 演算法需要自由切換的場景。

● 需要遮蔽演算法規則的場景。

注意事項:具體策略數量超過4個,則需要考慮使用混合模式

定義:

● 它是一個列舉。

● 它是一個濃縮了的策略模式的列舉。

注意:

受列舉型別的限制,每個列舉項都是public、final、static的,擴充套件性受到了一定的約束,因此在系統開發中,策略列舉一般擔當不經常發生變化的角色。

致命缺陷:

所有的策略都需要暴露出去,由客戶端決定使用哪一個策略。

13.介面卡模式

        將一個類的介面變換成客戶端所期待的另一種介面,從而使原本因介面不匹配而無法在一起工作的兩個類能夠在一起工作。

使用場景

你有動機修改一個已經投產中的介面時,介面卡模式可能是最適合你的模式。比如系統擴充套件了,需要使用一個已有或新建立的類,但這個類又不符合系統的介面,怎麼辦?使用介面卡模式,這也是我們例子中提到的。

注意事項:

詳細設計階段不要考慮使用介面卡模式,使用主要場景為擴充套件應用中。

物件介面卡:

 物件介面卡和類介面卡的區別:

類介面卡是類間繼承,物件介面卡是物件的合成關係,也可以說是類的關聯關係,這是兩者的根本區別。(實際專案中物件介面卡使用到的場景相對比較多)。

14.迭代器模式

        它提供一種方法訪問一個容器物件中各個元素,而又不需暴露該物件的內部細節。

ps:迭代器模式已經被淘汰,java中已經把迭代器運用到各個聚集類(collection)中了,使用java自帶的迭代器就已經滿足我們的需求了。

15.組合模式

        將物件組合成樹形結構以表示“部分-整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。

使用場景:

● 維護和展示部分-整體關係的場景,如樹形選單、檔案和資料夾管理。

● 從一個整體中能夠獨立出部分模組或功能的場景。

注意:

只要是樹形結構,就考慮使用組合模式。

16.觀察者模式

        定義物件間一種一對多的依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。

使用場景:

● 關聯行為場景。需要注意的是,關聯行為是可拆分的,而不是“組合”關係。

● 事件多級觸發場景。

● 跨系統的訊息交換場景,如訊息佇列的處理機制。

注意:

● 廣播鏈的問題

在一個觀察者模式中最多出現一個物件既是觀察者也是被觀察者,也就是說訊息最多轉發一次(傳遞兩次)。

● 非同步處理問題

觀察者比較多,而且處理時間比較長,採用非同步處理來考慮執行緒安全和佇列的問題。

17.門面模式

        要求一個子系統的外部與其內部的通訊必須通過一個統一的物件進行。門面模式提供一個高層次的介面,使得子系統更易於使用。

使用場景:

為一個複雜的模組或子系統提供一個供外界訪問的介面

子系統相對獨立——外界對子系統的訪問只要黑箱操作即可

預防低水平人員帶來的風險擴散

注意:

一個子系統可以有多個門面

門面不參與子系統內的業務邏輯

18.備忘錄模式

        在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。

使用場景:

● 需要儲存和恢復資料的相關狀態場景。

● 提供一個可回滾(rollback)的操作。

● 需要監控的副本場景中。

● 資料庫連線的事務管理就是用的備忘錄模式。

注意:

●備忘錄的生命期

●備忘錄的效能

   不要在頻繁建立備份的場景中使用備忘錄模式(比如一個for迴圈中)。

clone方式備忘錄:

● 發起人角色融合了發起人角色和備忘錄角色,具有雙重功效

多狀態的備忘錄模式

● 增加了一個BeanUtils類,其中backupProp是把發起人的所有屬性值轉換到HashMap中,方便備忘錄角色儲存。restoreProp方法則是把HashMap中的值返回到發起人角色中。

19.訪問者模式

        封裝一些作用於某種資料結構中的各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新的操作。

使用場景:

● 一個物件結構包含很多類物件,它們有不同的介面,而你想對這些物件實施一些依賴於其具體類的操作,也就說是用迭代器模式已經不能勝任的情景。

● 需要對一個物件結構中的物件進行很多不同並且不相關的操作,而你想避免讓這些操作“汙染”這些物件的類。

20.狀態模式

        當一個物件內在狀態改變時允許其改變行為,這個物件看起來像改變了其類。

使用場景:

● 行為隨狀態改變而改變的場景

這也是狀態模式的根本出發點,例如許可權設計,人員的狀態不同即使執行相同的行為結果也會不同,在這種情況下需要考慮使用狀態模式。

● 條件、分支判斷語句的替代者

注意:

狀態模式適用於當某個物件在它的狀態發生改變時,它的行為也隨著發生比較大的變化,也就是說在行為受狀態約束的情況下可以使用狀態模式,而且使用時物件的狀態最好不要超過5個。

21.直譯器模式

        給定一門語言,定義它的文法的一種表示,並定義一個直譯器,該直譯器使用該表示來解釋語言中的句子。

使用場景:

● 重複發生的問題可以使用直譯器模式

● 一個簡單語法需要解釋的場景

22.享元模式

        使用共享物件可有效地支援大量的細粒度的物件。

使用場景:

● 系統中存在大量的相似物件。

● 細粒度的物件都具備較接近的外部狀態,而且內部狀態與環境無關,也就是說物件沒有特定身份。

● 需要緩衝池的場景。

注意:

● 享元模式是執行緒不安全的,只有依靠經驗,在需要的地方考慮一下執行緒安全,在大部分場景下不用考慮。物件池中的享元物件儘量多,多到足夠滿足為止。

● 效能安全:外部狀態最好以java的基本型別作為標誌,如String,int,可以提高效率。

23.橋樑模式

        將抽象和實現解耦,使得兩者可以獨立地變化。

使用場景:

● 不希望或不適用使用繼承的場景

● 介面或抽象類不穩定的場景

● 重用性要求較高的場景

注意:

發現類的繼承有N層時,可以考慮使用橋樑模式。橋樑模式主要考慮如何拆分抽象和實現。

相關推薦

試題7.java常用設計模式哪些

設計模式主要分三個型別:建立型、結構型和行為型。  策略模式,代理模式,單例模式,多例模式,工廠方法模式,抽象工廠模式,門面模式,介面卡模式,模板方法模式,建造者模式,橋樑模式,命令模式,裝飾模式,迭代器模式,組合模式,觀察者模式,責任鏈模式,訪問者模式,狀態模式,原型模式

java常用設計模式7——責任鏈模式

嘿嘿,這次介紹一個好玩的設計模式 — — 責任鏈模式 相關程式碼下載: GitHub - GodisGod/DesignPatternStudy: 設計模式學習demo https://github.com/GodisGod/DesignPatternStudy

Java試題--關於 OOP 和設計模式

這部分包含 Java 面試過程中關於 SOLID 的設計原則,OOP 基礎,如類,物件,介面,繼承,多型,封裝,抽象以及更高階的一些概念,如組合、聚合及關聯。也包含了 GOF 設計模式的問題。 103)介面是什麼?為什麼要使用介面而不是直接使用具體類? 介面用於定義 API

JAVA常用設計模式

ipp targe aec atd jmh 設計模式 模式 java left 巴揭殼景枚嫡倚濫煽吠徑http://www.docin.com/vxuo069 蔚贍卣碩狼吠亢照某嶽魏徹http://www.docin.com/idj90593 黃濁偃由友兔兆凍寺敬踴酌沮持h

Java常用設計模式——觀察者模式

ray stat param servers face oid println override 角色 觀察者模式又叫做發布-訂閱-模式、模型-視圖-模式、源-監聽器-模式或者從屬者模式。觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對

Java常用設計模式——策略模式

nts static 管理 選擇 span disco rri contex 由於 策略模式定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換,策略模式讓算法獨立於使用它的客戶而獨立變化。策略模式使這些算法在客戶端調用它們的時候能夠互不影響地變化

java常用設計模式--觀察者模式簡單例子

package com.ruanyun;import java.util.List;import java.util.Vector;/** * @Auther: maxw * @Date: 2018/11/10 16:14 * @Description:觀察者模式 * 基本概念: * 觀察者模式屬於行為型模式

java常用設計模式--單例模式簡單例子

package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/10 17:29 * @Description: */public class Test4 { public static void main(String args[]){

java常用設計模式--工廠方法模式簡單例子

package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:02 * @Description:工廠方法模式:有四個角色,抽象工廠模式,具體工廠模式,抽象產品模式,具體產品模式。不再是由一個工廠類去例項化具體的產品,而是由抽象工廠的子類去例項化

java常用設計模式--抽象工廠模式簡單例子

package com.ruanyun;/** * @Auther: maxw * @Date: 2018/11/12 11:23 * @Description:抽象工廠模式:與工廠方法模式不同的是,工廠方法模式中的工廠只生產單一的產品,而抽象工廠模式中的工廠生產多個產品。 * 還有個抽象工廠方法模式 只需要

java常用設計模式--享元模式簡單例項

package com.ruanyun;import java.util.HashMap;import java.util.Map;/** * @Auther: maxw * @Date: 2018/11/21 09:47 * @Description:享元模式:“享”就是分享之意,指一物被眾人共享,而這也正

java常用設計模式連結

轉自:作者:dreamOwn     https://www.cnblogs.com/wabi87547568/p/5280905.html   Java中常用的設計模式 1.單例模式   單例模式有以下特點:  1、單例類只能有一個例項。  2、單例類必須自己

Java常用設計模式————觀察者模式

引言 作為設計模式中常用的行為型模式,其主要解決的是一個複合物件(或組合物件)的基礎依賴物件的通知問題。 簡單的說,當一個複合物件依賴多個其他物件時,我們稱這種關係為一對多的關係。當這個複合物件狀態發生了改變,其他組成它的物件都可以收到來自複合物件的通知。 依賴物件中存在一個指向複合

java常用設計模式10—裝飾模式

我的設計模式學習系列專案地址: GitHub - GodisGod/DesignPatternStudy: 設計模式學習demo https://github.com/GodisGod/DesignPatternStudy 介紹: 裝飾模式也稱為包裝模式,結構型設計

java常用設計模式9——代理模式

介紹:代理模式也稱為委託模式。 定義:為其它物件提供一種代理以控制對這個物件的訪問。 程式碼舉例: 山中有一個大王,大王有一個嘍囉,大王需要巡山來保證自己的地盤不被入侵,但是大王怎麼能自己去巡山呢?所以就要嘍囉代替大王來巡山。 我們用代理模式描述這個場景 //任務 publi

java常用設計模式8——模板方法模式

這個設計模式應該是最簡單的設計模式,因為大家平時都在使用,可能只是不知道它還是個設計模式吧 相關程式碼下載: GitHub - GodisGod/DesignPatternStudy: 設計模式學習demo https://github.com/GodisGod/Desi

java常用設計模式6——狀態模式

狀態模式介紹: 1、狀態模式中的行為是由狀態來決定的,不同的狀態下有不同的行為。 2、狀態模式和策略模式的結構幾乎完全一樣,但它們的目的、本質卻完全不一樣。狀態模式的行為是平行的,不可替換的,策略模式的行為是彼此獨立,可相互替換的。 3、狀態模式把物件的行為包裝在不同的狀態物件裡,每一個

java常用設計模式5——策略模式

通常一個問題有多個解決方案的時候,我們會把每個解決方案封裝到自己的類裡面,這樣可以避免在同一個類裡通過if,else或者switch來判斷使用哪種方案。 比如: if(type == 1){ return fun1(); }else if(type == 2){ return f

java常用設計模式4——觀察者模式

當被觀察者的狀態傳送改變的時候,所有觀察它的物件都會得到通知並自動更新。 觀察者模式UML圖: Subject: 抽象主題。把所有觀察者物件的引用儲存在一個集合裡,每個主題都可以有任意數量的觀察者,抽象主題提供一個介面,可以增加和刪除物件。 ConcreteSubject:具體主題

java常用設計模式3——工廠方法模式

1、工廠方法模式定義:定義一個用於建立物件的介面,讓子類決定例項化哪個類 2、工廠方法模式的使用場景:在任何需要生成複雜物件的地方,都可以使用工廠方法模式。複雜物件適合使用工廠模式,用new就可以完成建立的物件無需使用工廠模式 多工廠方法模式 程式碼示例: 1、定義一個抽象的產品