首頁 Java java教程 java三種工廠模式

java三種工廠模式

Dec 15, 2016 pm 01:54 PM
java工廠模式

適用場合: 
7.3 工廠模式的適用場合 

建立新物件最簡單的方法是使用new關鍵字和特定類別。只有在某些場合下,創建和維護物件工廠所帶來的額外複雜性才是物有所值。本節概括了這些場合。 

7.3.1 動態實作 

如果需要像前面自行車的例子一樣,創建一些用不同方式實現同一接口的對象,那麼可以使用一個工廠方法或簡單工廠對象來簡化選擇實現的過程。這種選擇可以是明確進行的也可以是隱含的。前者如自行車那個例子,顧客可以選擇需要的自行車型號;而下一節所講的XHR工廠那個例子則屬於後者,該例中所返回的連接對象的類型取決於所探查到的頻寬和網絡延時等因素。在這些場合下,你通常要與一系列實作了同一個介面、可以被同等對待的類別打交道。這是JavaScript中使用工廠模式的最常見的原因。 

7.3.2 節省設置開銷 

如果物件需要複雜且彼此相關的設置,那麼使用工廠模式可以減少每種物件所需的程式碼量。如果這種設定只需要為特定類型的所有實例執行一次即可,這種作用尤其突出。把這種設定程式碼放到類別的建構函式中並不是一種高效的做法,這是因為即便設定工作已經完成,每次創建新實例的時候這些程式碼還是會執行,而且這樣做會把設定程式碼分散到不同的類別中。工廠方法非常適合於這種場合。它可以在實例化所有需要的物件之前先一次性地進行設定。無論有多少不同的類別會被實例化,這種辦法都可以讓設定程式碼集中在一個地方。 

如果所使用的類別要求載入外部程式庫的話,這尤其有用。工廠方法可以對這些庫進行檢查並動態載入那些未找到的庫。這些設定代碼只存在於一個地方,因此以後改起來也方便許多。 

7.3.3 用許多小型物件組成一個大物件 

工廠方法可以用來創造封裝了許多較小物件的物件。考慮一下自行車物件的建構函數。自行車包含許多較小的子系統:車輪、車架、傳動部件以及車閘等。如果你不想讓某個子系統與較大的那個物件之間形成強耦合,而是想在運作時從許多子系統中進行挑選的話,那麼工廠方法是一個理想的選擇。使用這種技術,某天你可以為售出的所有自行車配上某種鏈條,要是第二天找到另一種更中意的鏈條,可以改而採用這個新品種。要實現這種改變很容易,因為這些自行車類別的構造函數並不依賴某種特定的鏈條品種。本章後面RSS閱讀器的例子示範了工廠模式在這方面的用途。 


工廠模式主要是為創建物件提供了介面。工廠模式依《Java與模式》中的提法分為三類: 
1. 簡單工廠模式(Simple Factory) 
2. 工廠方法模式(Factory Method) 
3. 抽象工廠模式(Abstract Factory) 
這三種模式從上到下逐步抽象,並且更具一般性。還有一種分類法,就是將簡單工廠模式看為工廠方法模式的一種特例,兩個歸為一類。以下是使用工廠模式的兩種情況: 
1.在編碼時不能預見需要建立哪一種類別的實例。 
2.系統不應依賴產品類別實例如何被創建、組合和表達的細節 


三、簡單工廠模式 
顧名思義,而這個模式本身很簡單,而且使用在業務較簡單的情況下。 
它由三個角色組成(關係見下面的類別圖): 
1、工廠類別角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯。在java中它往往由一個具體類別實現。 
2、抽象產品角色:它一般是特定產品繼承的父類別或實作的介面。在java中由介面或抽象類別來實作。 
3、具體產品角色:工廠類別所創建的物件就是此角色的實例。在java中由一個具體類別實作。 
那麼簡單工廠模式怎麼用呢?我來舉個例子吧,我想這個比講一大段理論上的文字描述要容易理解的多!下面就來給那個暴發戶治病: P 
在使用了簡單工廠模式後,現在暴發戶只需要坐在車裡對司機說句:"開車"就可以了。來看看怎麼實現的: 
//抽象產品角色 
public interface Car{ 
public void drive(); 

//特定產品角色 
public class Benz implements Car{ 
//特定產品角色 
public class Benz implements Car{ out.println("Driving Benz "); 


public class Bmw implements Car{ 
public void drive() { 
System.out.println("Driving Bmw ");。 。 。 (Audi我就不寫了:P) 
//工廠類別角色 
public class Driver{ 
//工廠方法 
//注意返回類型為抽象產品角色 
public static Car driverCar(String s)throws Exception { 
public static Car driverCar(String s)throws Exception { 
/ /判斷邏輯,傳回特定的產品角色給Client 
if(s.equalsIgnoreCase("Benz")) return new Benz(); 
else if(s.equalsIgnoreCase("Bmw")) 
return new Bm); ...... 
else throw new Exception(); 
。 。 。
//歡迎暴發戶出場...... 
public class Magnate{ 
public static void main(String[] args){ 
try{ 
//告訴司機我今天坐奔馳 
Car car = Driver.driver( "benz"); 
//下命令:開車 
car.drive(); 
。 。 。 
如果將所有的類別放在一個檔案中,請不要忘記只能有一個類別被宣告為public。 程序中類別的關係如下: 
這便是簡單工廠模式了。以下是其好處: 
首先,使用了簡單工廠模式後,我們的程式不在"有病",更加符合現實中的情況;而且客戶端免除了直接創建產品對象的責任,而僅僅負責"消費"產品(如暴發戶所為)。 
下面我們從開閉原則上來分析下簡單工廠模式。當暴發戶增加了一輛車的時候,只要符合抽象產品製定的合同,那麼只要通知工廠類知道就可以被客戶使用了。那麼對於產品部分來說,它是符合開閉原則的--對擴展開放、對修改關閉;但是工廠部分好像不太理想,因為每增加一輛車,都要在工廠類中增加相應的商業邏輯和判斷邏輯,這顯自然是違反開閉原則的。 
對於這樣的工廠類別(在我們的例子中是為司機師傅),我們稱它為全能類或上帝類。 
我們舉的例子是最簡單的情況,而在實際應用中,很可能產品是一個多層次的樹狀結構。由於簡單工廠模式中只有一個工廠類別來對應這些產品,所以這可能會把我們的上帝類壞了,進而累壞了我們可愛的程式設計師:( 
正如我前面提到的簡單工廠模式適用於業務將簡單的情況下。工廠角色:這是工廠方法模式的核心,它與應用程式無關。 :它含有和具體業務邏輯有關的程式碼。或是實作的介面。用類別圖來清楚的表示下的它們之間的關係: 
我們還是老規矩使用一個完整的例子來看看工廠模式各個角色之間是如何來協調的。的愛車也越來越多。上,以後你不用這麼辛苦了,我給你分配幾個人手,你只管管好他們就行了! 於是,工廠方法模式的管理出現了。工廠模式類似,只是變得複雜了一些,這裡略。 new Benz(); 


public class BmwDriver implements Driver{ 
public Car driverCar() { 
return new Bmw(); 

}/對應關係,這裡略... 
//有請暴發戶先生 
public class Magnate 

public static void main(String[] args) 

try{ 
Driver .driverCar(); 
car.drive(); 
}catch(Exception e) 
{ } 


工廠方法使用一個抽象工廠角色作為核心來取代在簡單工廠模式中使用特定類別作為核心。讓我們來看看工廠方法模式為我們帶來了什麼?使用開閉原則來分析下工廠方法模式。當有新的產品(即暴發戶的汽車)產生時,只要按照抽象產品角色、抽象工廠角色提供的合約來生成,那麼就可以被客戶使用,而不必去修改任何已有的程式碼。看來,工廠方法模式是完全符合開閉原則的! 
使用工廠方法模式足以應付我們可能遇到的大部分業務需求。但是當產品種類非常多時,就會出現大量的與之對應的工廠類,這不應該是我們所希望的。所以我建議在這種情況下使用簡單工廠模式與工廠方法模式相結合的方式來減少工廠類:即對於產品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡單工廠模式來實現。 
當然特殊的情況,就要特殊對待了:對於系統中存在不同的產品樹,而且產品樹上存在產品族,那麼這種情況下就可能可以使用抽象工廠模式了。
五、小結 
讓我們來看看簡單工廠模式、工廠方法模式給我們的啟蒙: 
如果不使用工廠模式來實現我們的例子,也許代碼會減少很多--只需要實現已有的車,不使用多態。但是在可維護性上,可擴展性上是非常差的(你可以想像一下,添加一輛車後要牽動的類)。因此為了提高擴充性和維護性,多寫些程式碼是值得的。 
六、抽象工廠模式 
先來認識下什麼是產品族:位於不同產品等級結構中,功能相關聯的產品組成的家族。如果光看這句話就能清楚的理解這個概念,我不得不佩服你啊。還是讓我們用一個例子來形象化說明一下吧。 
圖中的BmwCar和BenzCar就是兩個產品樹(產品層次結構);而如圖所示的BenzSportsCar和BmwSportsCar就是一個產品族。他們都可以放到跑車家族中,因此功能有所關聯。同理BmwBussinessCar和BenzSportsCar也是一個產品族。 
回到抽象產品模式的議題上,可以這麼說,它和工廠方法模式的差異就在於需要創造物件的複雜程度。而且抽象工廠模式是三個裡面最抽象、最具一般性的。抽象工廠模式的用意為:給客戶端提供一個接口,可以建立多個產品族中的產品物件。而且使用抽象工廠模式還要滿足一下條件: 
1.系統中有多個產品族,而係統一次只可能消費其中一族產品 
2.同屬於同一個產品族的產品以其使用。 
來看看抽象工廠模式的各個角色(和工廠方法的如出一轍): 
抽象工廠角色:這是工廠方法模式的核心,它與應用程式無關。是具體工廠角色必須實作的介面或是必須繼承的父類別。在java中它是由抽象類別或介面來實作。 
具體工廠角色:它含有和具體業務邏輯有關的程式碼。由應用程式呼叫以建立對應的特定產品的物件。在java中它是由具體的類別來實作。 
抽象產品角色:它是特定產品繼承的父類別或是實作的介面。在java中一般有抽象類別或介面來實作。 
具體產品角色:具體工廠角色所創造的物件就是此角色的實例。在java中由具體的類別來實作。 
看過了前兩個模式,對這個模式各個角色之間的協調情況應該心裡有個數了,我就不舉具體的例子了。只是一定要注意滿足使用抽象工廠模式的條件哦,不然即使存在了多個產品樹,也存在產品族,但是不能使用的



更多java PHP中文網!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1327
25
PHP教程
1273
29
C# 教程
1253
24
公司安全軟件導致應用無法運行?如何排查和解決? 公司安全軟件導致應用無法運行?如何排查和解決? Apr 19, 2025 pm 04:51 PM

公司安全軟件導致部分應用無法正常運行的排查與解決方法許多公司為了保障內部網絡安全,會部署安全軟件。 ...

如何將姓名轉換為數字以實現排序並保持群組中的一致性? 如何將姓名轉換為數字以實現排序並保持群組中的一致性? Apr 19, 2025 pm 11:30 PM

將姓名轉換為數字以實現排序的解決方案在許多應用場景中,用戶可能需要在群組中進行排序,尤其是在一個用...

如何使用MapStruct簡化系統對接中的字段映射問題? 如何使用MapStruct簡化系統對接中的字段映射問題? Apr 19, 2025 pm 06:21 PM

系統對接中的字段映射處理在進行系統對接時,常常會遇到一個棘手的問題:如何將A系統的接口字段有效地映�...

如何優雅地獲取實體類變量名構建數據庫查詢條件? 如何優雅地獲取實體類變量名構建數據庫查詢條件? Apr 19, 2025 pm 11:42 PM

在使用MyBatis-Plus或其他ORM框架進行數據庫操作時,經常需要根據實體類的屬性名構造查詢條件。如果每次都手動...

IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? IntelliJ IDEA是如何在不輸出日誌的情況下識別Spring Boot項目的端口號的? Apr 19, 2025 pm 11:45 PM

在使用IntelliJIDEAUltimate版本啟動Spring...

Java對像如何安全地轉換為數組? Java對像如何安全地轉換為數組? Apr 19, 2025 pm 11:33 PM

Java對象與數組的轉換:深入探討強制類型轉換的風險與正確方法很多Java初學者會遇到將一個對象轉換成數組的�...

如何利用Redis緩存方案高效實現產品排行榜列表的需求? 如何利用Redis緩存方案高效實現產品排行榜列表的需求? Apr 19, 2025 pm 11:36 PM

Redis緩存方案如何實現產品排行榜列表的需求?在開發過程中,我們常常需要處理排行榜的需求,例如展示一個�...

電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? 電商平台SKU和SPU數據庫設計:如何兼顧用戶自定義屬性和無屬性商品? Apr 19, 2025 pm 11:27 PM

電商平台SKU和SPU表設計詳解本文將探討電商平台中SKU和SPU的數據庫設計問題,特別是如何處理用戶自定義銷售屬...

See all articles