《java與模式》----建立模式系列原廠模式、單態模式精講
來源:互聯網
上載者:User
建立
建立模式-----Creation Pattern
建立模式是對類執行個體化過程的抽象。
一些系統在建立對象的時候需要動態決定怎樣建立對象、建立哪些對象、以及如何組合,表示這些對象。建立模式描述了怎樣構造和封裝這些動態決定。
建立模式又分類的建立模式和對象的建立模式。
l 類的建立模式:類的建立模式使用繼承關係,把類的建立延遲到子類,從而封裝了用戶端將得到哪些具體類的資訊,並隱藏了這些類的執行個體是如何被建立的和放在一起的。、
l 對象的建立模式:對象的建立模式則把對象的建立過程動態委派給另一個對象,從而動態決定用戶端將得到哪些具體類的執行個體,以及這些類執行個體如何被建立和組合在一起。
原廠模式
原廠模式負責將大量有共同介面的類執行個體化。原廠模式可以決定將哪一個類執行個體化,不必事Crowdsourced Security Testing道每次要執行個體化哪一個類。
原廠模式的幾種形態:
l 簡單原廠模式。又稱靜態原廠模式。
l Factory 方法模式。Factory Method,又稱多態工廠或虛擬構造子模式(Virtual Constructor)。
l 抽象原廠模式。Abstract Factory,又稱工具箱(Kit或ToolKit)模式。
原廠模式的逐步遞演反映了抽象的步步加深、解決問題
簡單工廠--------Simple Factory
簡單原廠模式是由一個工廠對象決定建立何種產品類的執行個體。
簡單原廠模式的普通類圖:
工 廠
S-Factory
+create():C-P
P--interface
P--concrete
靜態建立---create
具體產品
抽象產品
簡單原廠模式設計到的角色:
1. 工廠類(creator)角色:這個角色是原廠模式的核心,它含有於應用緊密相關的商業邏輯。工廠類在用戶端的調用下建立產品對象,它往往又一個具體的java類實現。
2. 抽象產品(Abstract Product)角色:它為具體產品提供了一個共同的介面(類型)。是Factory 方法的傳回型別。
3. 具體產品(Concrete Product)角色:Factory 方法所建立的對象都是它的執行個體。
簡單原廠模式的特徵:靜態方法返回對象執行個體。
抽象產品
具體產品
簡單原廠模式的其它類圖:
l 這一種比較極端:!java類庫中也有
l 大量執行個體.退化的簡單原廠模式。
l 第二種:工廠角色和抽象產品合并。
單態模式和多態模式的建構函式都是私人的---對外不提供直接執行個體化的功能,它們都有自己的靜態Factory 方法,提供自身的執行個體。
當單態模式和多態模式使用一個集合來儲存自己建立的對象,以便通過查詢這個集合來得到建立的對象時,就成了備忘錄模式的應用。
MVC模式。MVC模式並不是嚴格意義上的設計模式,而是更高層次上的構架模式。MVC模式可以分解成幾個設計模式的組合,包括合成模式、策略模式、觀察者模式,也有可能包括裝飾模式、調停者模式、迭代子模式以及Factory 方法模式等。
簡單原廠模式說建立的對象往往屬於一個產品等級結構,這個產品的等級結構可是使MVC模式中的視圖(View),而工廠角色本身可以使控制器(Controller)。
AbstractView
View
View
Controller
簡單原廠模式使用靜態Factory 方法,而靜態方法無法由子類繼承,因此工廠角色無法形成給予繼承的等級結構。這一缺點在原廠模式中得到瞭解決。
簡單原廠模式中工廠角色是該系統的關鍵角色。它關係了系統的命運,也集中了所有的邏輯。這使得系統在將來進行功能拓展時變得異常複雜。
簡單原廠模式對“開閉”原則支援不夠。當產品角色的類功能拓展時,該模式完全支援。但當有新的產品角色加入時,就不得不修改工廠角色來適應了。它在有限程度上支援“開閉”原則。
Factory 方法返回抽象產品類型的做法稱作“針對抽象編程”。這是依賴倒轉原則的應用。這樣做是利用具體產品類的超類型將它的真實類型隱藏起來,其好處是為系統提供了可拓展性。如果將來有新的具體產品類加入到系統中來,那麼工廠類可以將其交給用戶端對象換成新的子類執行個體,而對用戶端沒有影響。
Factory 方法模式
Factory 方法模式是定義一個工廠角色的介面,將世紀的建立工作延遲到工廠角色的子類去完成。
在Factory 方法模式中核心的工廠類不再負責所有產品的建立,而是講具體的建立工作交給子類去完成。這個核心類變成了抽象工廠角色。抽象工廠角色僅給出具體工廠角色必須實現的介面,而不去接觸哪一個產品類應當被執行個體化這樣的細節。
這種進一步抽象的結果使得Factory 方法模式允許系統在不修改具體工廠角色的情況下引進新產品。
Factory 方法模式的基本類圖:
Abstract Factory
Concrete Factory
P--interface
P--concrete
create
原廠模式的角色:
l 抽象工廠(Abstract Factory)角色:這個角色使原廠模式的核心,它與應用程式無關。可以由介面或抽象類別擔任。
l 具體工廠(Concrete Factory)角色:擔任這個角色的類是實現了抽象工廠的介面的具體類。具體工廠角色含有與應用密切相關的邏輯,並且受到應用程式的調用以建立對象。
l 抽象產品角色:Factory 方法模式說建立的對象的父類型,也就是具體產品的共同介面。
l 具體產品角色:這個角色思想了抽象產品角色所聲明的介面。Factory 方法所建立的的每一個對象都是某個具體產品角色的執行個體。
抽象原廠模式
抽象工廠是原廠模式中最為抽象和普遍的一種形態。
原廠模式面對的問題是一個產品的等級結構,而抽象工廠需要面對多個產品的等級結構。
抽象工廠的類圖:
Creator1
+createA:ProductA
+createB:ProductB
Creator2
+createA:ProductA
+createB:ProductB
Interface ProducutA
ProducutA1
ProducutA2
Interface ProducutB
ProducutB1
ProducutB2
Interface Creator
+createA:ProductA
+createB:ProductB
抽象工廠面向的是產品等級結構中的產品族:
具體工廠Creator1在繼承了抽象工廠Creator的+createA:ProductA +createB:ProductB 的產品結構後,專註於產品族Producut*1 的開發。
橫向的產品族與縱向的產品結構通過抽象工廠聯絡到一起。
在什麼情況下使用抽象原廠模式:[GOF][閻宏]
l 一個系統不應當依賴於產品執行個體如何被建立、組合和表達的細節,這對於所有形態的原廠模式都是至關重要的。
l 這個系統產品有多餘一個的產品族,而系統只消費其中某一族的產品。這也是抽象工廠的原始用意。
l 同屬於同一產品族的產品是在一起使用的,這一約束必須在系統的設計中體現出來。
l 系統提供一個產品類的庫,所有的產品以同樣的介面出現,從而使用戶端不依賴於實現。
單態模式-----(Sigleton)
單態模式確保系統中,一個類子只有一個執行個體,而且自行執行個體化並向整個系統提供這個執行個體。這個類成為單態類。
單態模式的要點:
l 某一個類只有一個執行個體。
l 它必須自行建立這個執行個體。
l 它必須向整個系統提供這個執行個體。
l 建構函式私人:不被外部執行個體化,也不被繼承。
單態模式的執行個體:資源管理員,資源回收筒,印表機資源。
單態模式的結構:
0..1
1
餓漢式單態類:
Eager Singletion
-m instance: EagerSingletion = new EagerSingletion()
-EagerSingletion() //建構函式為私人
+getInstance():EagerSingletion //返回該執行個體,靜態Factory 方法
create
代碼:餓漢式單態類
public class EagerSingletion{
private static final EagerSingletion m_instance= new EagerSingletion();
private EagerSingletion(){} //私人建構函式,防止被new
/**
* 靜態Factory 方法
*/
public static EagerSingletion getInstance(){
return m_instance;
}
}
懶漢式單態類:
Lazy Singletion
-m instance: Lazy rSingletion = null;
- LazySingletion() //建構函式私人化
+getInstance():LazySingletion //返回該執行個體,靜態工廠,安全執行緒
create
代碼:懶漢式單態類
public class LazySingletion{
private static final LazySingletion m_instance= null;
private LazySingletion(){} //私人建構函式,防止被new
/**
* 安全執行緒,靜態Factory 方法,保證返回唯一執行個體
*/
public static synchronized EagerSingletion getInstance(){
if(m_instance = null){
m_instance = new EagerSingletion();
}
return m_instance;
}
}
登記式單態類:
登記式單態類是GOF為了克服前兩者不可繼承的缺點而設計的。只是它的子類執行個體化的方式只能是懶漢式的---這是無法改變的。
RegSingletion
-m registy:HashMap m_ registy = new HashMap();
# RegSingletion() //建構函式保護類型—可被子類繼承
+getInstance(name:String):RegSingletion //返回該執行個體
+about():String
create
代碼:登記式單態類 /*注釋:p213 出現印刷錯誤 static 關鍵字位置錯了*/
public class RegSingletion{
private static HashMap m_ registy = new HashMap();
/**
* 靜態塊,在類聲明前自動載入
*/
static{
RegSingletion x = new RegSingletion();
m_ registry.put(x.getClass().getName(),x);
}
protected RegSingletion(){} //保護的建構函式,可被子類繼承!
/**
* 安全執行緒,靜態Factory 方法,保證返回唯一執行個體
*/
public static synchronized RegSingletion getInstance(String name){
if(name = = null){
name = “com.javaptterns.singletion.RegSingletion”;
}
if(m_ registry.getname(name)= =null){
try{
m_ registry.put(name,Class.forName().newInstance());
}catch(Exception e){
}
}
return m_instance;
}
public String about(){
return “work complete”;
}
}
使用單態模式的條件:
在一個系統需要已給類的一個執行個體時才應使用。
例子:
l 系統中的全程變數是否可以放到一個單態類裡?
----不可以!一個設計得當的系統是不應當有所謂的“全程變數”的,這些變數應當放到他們所描述的實體所對應的類中去。如果將這些變數抽取出來放到一個不相干的單態類中,會使得這些類產生錯誤的依賴、耦合關係。
l 與資料庫的連線物件(Connection)也不應當被設計成單態模式。因為一個資料庫連接可以有幾個執行個體。
Java語言中的單態類:
Runtime對象每一個java應用程式內部都有唯一一個Runtime對象,通過這個對象,應用程式可以與運行環境發生相互作用。Runtime類提供一個靜態Factory 方法。
public static Runtime getRntime();
Runtime對象的用途常包括:執行外部命令、返回現有記憶體、運行垃圾收集器、載入動態類庫等。
Process pro = Runtime. getRntime().exec(“notPad.exe”);
java.awt.Toolkit類: