設計模式 - 面試題



尊敬的讀者們,這些設計模式面試題是專門為了讓您熟悉在設計模式面試中可能遇到的問題型別而設計的。根據我的經驗,優秀的 interviewers 很少會預先計劃好要問哪些特定問題,通常問題會從該主題的一些基本概念開始,然後根據後續的討論和您的回答繼續下去。

設計模式代表了經驗豐富的面向物件軟體開發人員使用的最佳實踐。設計模式是對軟體開發人員在軟體開發過程中遇到的常見問題的解決方案。這些解決方案是眾多軟體開發人員在相當長的一段時間內透過反覆試驗獲得的。

1994年,四位作者 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 出版了一本名為《設計模式——可複用面向物件軟體的基礎》的書,該書開啟了軟體開發中設計模式的概念。這些作者統稱為四人幫 (GOF)。

設計模式可以分為三大類:建立型模式、結構型模式和行為型模式。

  • 建立型模式 - 這些設計模式提供了一種建立物件的方式,同時隱藏了建立邏輯,而不是直接使用 new 運算子例項化物件。這使得程式在決定為給定用例需要建立哪些物件方面更具靈活性。

  • 結構型模式 - 這些設計模式關注類和物件的組合。繼承的概念用於組合介面並定義組合物件以獲得新功能的方法。

  • 行為型模式 - 這些設計模式專門關注物件之間的通訊。

這些設計模式專門關注表示層。這些模式由 Sun Java 中心確定。

工廠模式是 Java 中最常用的設計模式之一。這種設計模式屬於建立型模式,因為它提供了一種建立物件的最佳方式。

在工廠模式中,我們建立物件而不向客戶端公開建立邏輯,並使用公共介面引用新建立的物件。

抽象工廠模式圍繞一個超級工廠工作,該超級工廠建立其他工廠。這個工廠也稱為工廠的工廠。這種設計模式屬於建立型模式,因為它提供了一種建立物件的最佳方式。

在抽象工廠模式中,一個介面負責建立相關物件的工廠,而無需明確指定它們的類。每個生成的工廠都可以根據工廠模式提供物件。

單例模式是 Java 中最簡單的設計模式之一。這種設計模式屬於建立型模式,因為它提供了一種建立物件的最佳方式。

這種模式涉及一個單一類,該類負責建立物件,同時確保只建立單個物件。此類提供了一種訪問其唯一物件的方式,可以直接訪問該物件,而無需例項化該類的物件。

這是一個兩步過程。首先,將建構函式設為私有,以便 new 運算子不能用於例項化該類。如果物件不為空,則返回該物件的例項,否則建立該物件並透過方法返回。

以下是靜態類和單例類之間的區別。

  • 靜態類不能是頂級類,也不能實現介面,而單例類可以。

  • 靜態類的所有成員都是靜態的,但對於單例類來說,這不是必需的。

  • 靜態類在載入時被初始化,因此不能延遲載入,而單例類可以延遲載入。

  • 靜態類物件儲存在堆疊中,而單例類物件儲存在堆記憶體空間中。

可以。

在 clone() 方法的主體中丟擲異常。

以下是 JDK 庫中使用的一些設計模式。

  • 裝飾器模式由包裝類使用。

  • 單例模式由 Runtime、Calendar 類使用。

  • 工廠模式由包裝類(如 Integer.valueOf)使用。

  • 觀察者模式由事件處理框架(如 swing、awt)使用。

工廠模式封裝了實現細節,可以在不影響呼叫者 API 的情況下更改底層實現。

建造者模式使用簡單的物件和循序漸進的方法構建複雜物件。此構建器獨立於其他物件。

原型模式是指在考慮效能的同時建立重複物件。此模式涉及實現一個原型介面,該介面指示建立當前物件的克隆。

當直接建立物件成本很高時使用此模式。例如,物件需要在代價高昂的資料庫操作後建立。我們可以快取該物件,在下一個請求時返回其克隆,並在需要時更新資料庫,從而減少資料庫呼叫次數。

介面卡模式充當兩個不相容介面之間的橋樑。此模式涉及一個單一類,該類負責連線獨立或不相容介面的功能。

一個現實生活中的例子可能是讀卡器的情況,它充當記憶體卡和筆記型電腦之間的介面卡。您將記憶體卡插入讀卡器,並將讀卡器插入筆記型電腦,以便可以透過筆記型電腦讀取記憶體卡。

當我們需要將抽象與其實現解耦時使用橋接模式,以便兩者可以獨立變化。這種設計模式屬於結構型模式,因為它透過在它們之間提供橋接結構來解耦實現類和抽象類。

此模式涉及一個充當橋樑的介面,該介面使具體類的功能獨立於介面實現類。兩種型別的類都可以在結構上進行更改,而不會相互影響。

過濾器模式或標準模式是一種設計模式,它使開發人員能夠使用不同的標準過濾物件集,並透過邏輯運算以解耦的方式將它們連結起來。這種設計模式屬於結構型模式,因為它組合了多個標準以獲得單個標準。

組合模式用於我們需要以類似於單個物件的方式處理一組物件的情況。組合模式根據樹結構組成物件,以表示部分和整體層次結構。這種設計模式屬於結構型模式,因為它建立了物件組的樹結構。

此模式建立包含其自身物件組的類。此類提供修改其相同物件組的方法。

裝飾器模式允許使用者向現有物件新增新功能,而無需更改其結構。這種設計模式屬於結構型模式,因為它充當現有類的包裝器。

此模式建立一個裝飾器類,該類包裝原始類並提供附加功能,同時保持類方法簽名不變。

外觀模式隱藏了系統的複雜性,並向客戶端提供了一個介面,客戶端可以使用該介面訪問系統。這種設計模式屬於結構型模式,因為它向現有系統添加了一個介面來隱藏其複雜性。

此模式涉及一個單一類,該類提供客戶端所需的簡化方法,並將呼叫委託給現有系統類的該方法。

享元模式主要用於減少建立的物件數量,以減少記憶體佔用並提高效能。這種設計模式屬於結構型模式,因為它提供了一種減少物件數量從而改進應用程式物件結構的方法。

享元模式嘗試透過儲存已經存在的類似物件來重用它們,並在找不到匹配的物件時建立新物件。

在代理模式中,一個類代表另一個類的功能。這種設計模式屬於結構型模式。

在代理模式中,我們建立具有原始物件的介面來將其功能介面到外部世界。

顧名思義,責任鏈模式為請求建立接收者物件的鏈。此模式根據請求型別解耦請求的傳送者和接收者。此模式屬於行為模式。

在此模式中,通常每個接收者都包含對另一個接收者的引用。如果一個物件無法處理請求,則將其傳遞給下一個接收者,依此類推。

命令模式是一種資料驅動的設計模式,屬於行為模式類別。請求被包裝在一個物件中作為命令,並傳遞給呼叫者物件。呼叫者物件查詢可以處理此命令的適當物件,並將命令傳遞給執行該命令的相應物件。

直譯器模式提供了一種評估語言語法或表示式的方法。這種模式屬於行為型模式。這種模式涉及實現一個表示式介面,該介面指示如何解釋特定上下文。

這種模式用於SQL解析、符號處理引擎等。

迭代器模式在Java和.Net程式設計環境中非常常用。此模式用於以順序方式訪問集合物件的元素,而無需瞭解其底層表示。迭代器模式屬於行為型模式。

以下是這種設計模式的實體。

  • 服務 - 將處理請求的實際服務。此類服務的引用將在JNDI伺服器中查詢。

  • 上下文/初始上下文 - JNDI上下文包含用於查詢目的的服務引用。

  • 服務定位器 - 服務定位器是透過JNDI查詢獲取服務並快取服務的單點聯絡。

  • 快取 - 用於儲存服務引用以重用它們。

  • 客戶端 - 客戶端是透過ServiceLocator呼叫服務的物件。

中介者模式用於減少多個物件或類之間的通訊複雜性。此模式提供一箇中介者類,該類通常處理不同類之間的所有通訊,並通過鬆散耦合支援程式碼的輕鬆維護。中介者模式屬於行為型模式。

備忘錄模式用於將物件的狀體恢復到之前的狀體。備忘錄模式屬於行為型模式。

備忘錄模式使用三個參與者類。備忘錄包含要恢復的物件的狀體。發起者建立並將狀體儲存在備忘錄物件中,而管理者物件負責從備忘錄中恢復物件狀體。

當物件之間存在一對多關係時,例如,如果修改了一個物件,則其依賴物件將自動收到通知,則使用觀察者模式。觀察者模式屬於行為型模式。

觀察者模式使用三個參與者類:主題、觀察者和客戶端。主題是一個具有方法的物件,用於將觀察者附加和分離到客戶端物件。我們建立了一個抽象類觀察者和一個擴充套件觀察者類的具體類主題。

在狀體模式中,類的行為根據其狀體而變化。這種設計模式屬於行為型模式。在狀體模式中,我們建立表示各種狀體的物件和一個上下文物件,其行為隨其狀體物件的更改而變化。

在空物件模式中,空物件替換了對NULL物件例項的檢查。與其對空值進行if檢查,不如使用空物件來反映不執行任何操作的關係。如果資料不可用,此類空物件也可用於提供預設行為。

在空物件模式中,我們建立一個抽象類,指定要執行的各種操作,擴充套件此類的具體類和一個提供此類不執行任何操作實現的空物件類,並在需要檢查空值的地方無縫使用。

在策略模式中,可以在執行時更改類的行為或其演算法。這種設計模式屬於行為型模式。

在策略模式中,我們建立表示各種策略的物件和一個上下文物件,其行為根據其策略物件而變化。策略物件更改上下文物件的執行演算法。

在模板模式中,抽象類公開定義的執行其方法的方式/模板。其子類可以根據需要重寫方法實現,但呼叫方式必須與抽象類定義的方式相同。此模式屬於行為型模式。

在訪問者模式中,我們使用一個訪問者類來更改元素類的執行演算法。透過這種方式,元素的執行演算法可以隨著訪問者的變化而變化。此模式屬於行為型模式。根據該模式,元素物件必須接受訪問者物件,以便訪問者物件處理元素物件的操作。

MVC模式代表模型-檢視-控制器模式。此模式用於分離應用程式的關注點。

  • 模型 - 模型表示攜帶資料的物件或JAVA POJO。如果其資料更改,它還可以具有更新控制器的邏輯。

  • 檢視 - 視圖表示模型包含的資料的視覺化。

  • 控制器 - 控制器作用於模型和檢視。它控制資料流入模型物件,並在資料更改時更新檢視。它使檢視和模型保持分離。

業務委託模式用於解耦表示層和業務層。它基本上用於減少表示層程式碼中對業務層程式碼的通訊或遠端查詢功能。在業務層中,我們有以下實體。

  • 客戶端 - 表示層程式碼可以是JSP、servlet或UI java程式碼。

  • 業務委託 - 客戶端實體的單一入口點類,用於訪問業務服務方法。

  • 查詢服務 - 查詢服務物件負責獲取相關的業務實現並將業務物件訪問提供給業務委託物件。

  • 業務服務 - 業務服務介面。具體類實現此業務服務以提供實際的業務實現邏輯。

組合實體模式用於EJB持久化機制。組合實體是一個EJB實體bean,它表示物件的圖形。當更新組合實體時,內部依賴物件bean會自動更新,因為它們由EJB實體bean管理。以下是組合實體bean中的參與者。

  • 組合實體 - 它是主要的實體bean。它可以是粗粒度的,也可以包含粗粒度的物件,用於持久化目的。

  • 粗粒度物件 - 此物件包含依賴物件。它有自己的生命週期,也管理依賴物件的生命週期。

  • 依賴物件 - 依賴物件是一個依賴於粗粒度物件來實現其持久化生命週期的物件。

  • 策略 - 策略表示如何實現組合實體。

資料訪問物件模式或DAO模式用於將低階資料訪問API或操作與高階業務服務分離。以下是資料訪問物件模式中的參與者。

  • 資料訪問物件介面 - 此介面定義要對模型物件執行的標準操作。

  • 資料訪問物件具體類 - 此類實現上述介面。此類負責從資料來源獲取資料,資料來源可以是資料庫/xml或任何其他儲存機制。

  • 模型物件或值物件 - 此物件是簡單的POJO,包含用於儲存使用DAO類檢索的資料的get/set方法。

前端控制器設計模式用於提供集中式請求處理機制,以便所有請求都由單個處理程式處理。此處理程式可以執行請求的身份驗證/授權/日誌記錄或跟蹤,然後將請求傳遞給相應的處理程式。以下是這種設計模式的實體。

  • 前端控制器 - 應用程式接收的所有型別請求(基於Web/基於桌面的)的單個處理程式。

  • 排程程式 - 前端控制器可以使用排程程式物件,該物件可以將請求排程到相應的特定處理程式。

  • 檢視 - 檢視是發出請求的物件。

當我們希望對應用程式的請求或響應進行一些預處理/後處理時,使用攔截過濾器設計模式。在將請求傳遞到實際的目標應用程式之前,定義並應用過濾器。過濾器可以執行請求的身份驗證/授權/日誌記錄或跟蹤,然後將請求傳遞給相應的處理程式。

以下是這種設計模式的實體。

  • 過濾器 - 在請求處理程式執行請求之前或之後執行某些任務的過濾器。

  • 過濾器鏈 - 過濾器鏈承載多個過濾器,並幫助按定義的順序在目標上執行它們。

  • 目標 - 目標物件是請求處理程式。

  • 過濾器管理器 - 過濾器管理器管理過濾器和過濾器鏈。

  • 客戶端 - 客戶端是向目標物件傳送請求的物件。

當我們希望使用JNDI查詢來定位各種服務時,使用服務定位器設計模式。考慮到查詢服務的JNDI成本很高,服務定位器模式利用快取技術。第一次需要服務時,服務定位器在JNDI中查詢並快取服務物件。透過服務定位器進一步查詢或相同服務在其快取中進行,這在很大程度上提高了應用程式的效能。

當我們希望一次性將具有多個屬性的資料從客戶端傳遞到伺服器時,使用傳輸物件模式。傳輸物件也稱為值物件。傳輸物件是一個簡單的POJO類,具有getter/setter方法並且是可序列化的,以便它可以跨網路傳輸。它沒有任何行為。伺服器端業務類通常從資料庫中獲取資料並填充POJO並將其傳送到客戶端或按值傳遞它。對於客戶端,傳輸物件是隻讀的。客戶端可以建立自己的傳輸物件並將其傳遞到伺服器,以便一次性更新資料庫中的值。以下是這種設計模式的實體。

  • 業務物件 - 業務服務使用資料填充傳輸物件。

  • 傳輸物件 - 只有設定/獲取屬性的方法的簡單POJO。

  • 客戶端 - 客戶端向業務物件請求或傳送傳輸物件。

下一步是什麼?

接下來,您可以回顧一下您過去完成的作業,並確保您能夠自信地談論它們。如果您是應屆畢業生,面試官並不期望您能夠回答非常複雜的問題,而是您必須使自己的基礎概念非常紮實。

其次,如果您無法回答一些問題,這實際上並不重要,重要的是,無論您回答了什麼,都必須自信地回答。所以面試時要有自信。Tutorialspoint祝您能遇到一位好面試官,並祝您未來的事業一切順利。乾杯 :-)

廣告