設計模式學習筆記--工廠(Factory)、建造(Builder)和原型(Prototype)
寫在模式學習之前
什麼是設計模式:在我們進行程式設計時,逐漸形成了一些典型問題和問題的解決方案,這就是軟體模式;每一個模式描述了一個在我們程式設計中經常發生的問題,以及該問題的解決方案;當我們碰到模式所描述的問題,就可以直接用相應的解決方法去解決這個問題,這就是設計模式。
設計模式就是抽象出來的東西,它不是學出來的,是用出來的;或許你根本不知道任何模式,不考慮任何模式,卻寫著最優秀的程式碼,即使以“模式專家”的角度來看,都是最佳的設計,不得不說是“最佳的模式實踐”,這是因為你積累了很多的實踐經驗,知道“在什麼場合程式碼應該怎麼寫”,這本身就是設計模式。
有人說:“水平沒到,學也白學,水平到了,無師自通”。誠然,模式背熟,依然可能寫不出好程式碼,更別說設計出好框架;OOP理解及實踐經驗到達一定水平,同時也意味著總結了很多好的設計經驗,但"無師自通",卻也未必盡然,或者可以說,恰恰是在水平和經驗的基礎上,到了該系統的學習一下“模式”的時候了,學習一下專家總結的結果,印證一下自己的不足,對於提高水平還是很有幫助的。
本系列的設計模式學習筆記,實際是對於《Java與模式》這本書的學習記錄。
工廠模式的幾種形態
工廠模式專門負責將大量有共同介面的類例項化。工廠模式有以下幾種形態:(1)簡單工廠(Simple Factory)模式:又稱靜態工廠方法(Static Factory Method)模式。
(2)工廠方法(Factory Method)模式:又稱多型性工廠(Polymorphic Factory)模式,或者虛擬構造(Virtual Constructor)模式。和簡單工廠模式相比,最大的區別是工廠的多型化。
(3)抽象工廠(Abstract Factory)模式:又稱工具箱(Kit或Toolkit)模式。我個人理解為生產工廠的工廠。
簡單工廠(Simple Factory)模式
定義
簡單工廠模式是類的建立模式,又叫做靜態工廠方法(Static Factory Method)模式。簡單工廠模式是由一個工廠類決定創建出哪一種產品類的例項。
結構圖
模式所涉及的角色
(1)工廠類(Creator)角色:擔任這個角色的是簡單工廠模式的核心,含有與應用緊密相連的商業邏輯。工廠類在客戶端的直接呼叫下建立產品物件,它往往由一個具體Java類實現。
(2)抽象產品(Product)角色:擔任這個角色的類是由簡單工廠模式所建立的物件的父類,或它們共同擁有的介面。抽象產品角色可以用一個Java介面或者Java抽象類實現。
(3)具體產品(Concrete Product)角色:簡單工廠模式所建立的任何物件都是這個角色的例項,具體產品角色由一個具體Java類實現。
注意:抽象產品角色可以省略、工廠角色與抽象產品角色可以合併、三個角色也可以全部合併、可以通過登記式的工廠方法達到產品物件的迴圈使用(例如單例的實現)。
程式碼演示
interface Product {}
class ConcreteProduct implements Product
{
public ConcreteProduct() {}
}
class Creator
{
//靜態工廠方法
public static Product factory()
{
return new ConcreteProduct();
}
}
優缺點
優點:允許客戶端相對獨立於產品建立的過程,並且在系統引入新產品的時候無需修改客戶端,也就是說,它在某種程度上支援“開-閉”原則。
缺點:對"開-閉"原則的支援不夠,因為如果有新的產品加入到系統中去,就需要修改工廠類,將必要的邏輯加入到工廠類中。
簡單工廠在Java中的應用
import java.util.*;
import java.text.*;
class DateTest
{
public static void main(String[] args)
{
Locale local = Locale.FRENCH;
Date date = new Date();
String now = DateFormat.getTimeInstance(DateFormat.DEFAULT,local).format(date);
System.out.println(now);
try
{
date = DateFormat.getDateInstance(DateFormat.DEFAULT,local).parse("16 nov. 01");
System.out.println(date);
}
catch (ParseException e)
{
System.out.println("Parsing exception:" + e);
}
}
}
DateFormat是個抽象類,在這個“簡單工廠模式”例子中,它是工廠類角色和抽象產品角色的合體,完成具體產品角色的建立。
工廠方法(Factory Method)模式
定義
工廠方法模式是類的建立模式,又叫做虛擬構造(Virtual Constructor)模式或者多型性工廠(Polymorphic Factory)模式。
工廠方法模式的用意是定義一個建立產品物件的工廠介面,將實際建立工作推遲到子類中。
工廠方法模式是簡單工廠模式的進一步抽象和推廣。由於使用了多型性,保持了簡單工廠的優點,客服了其缺點,允許系統在不修改具體工廠角色的情況下引進新的產品(實際是增加新的具體工廠角色)。
結構圖
模式所涉及的角色
(1)抽象工廠(Creator)角色:擔任這個角色的是工廠方法模式的核心,它是與應用程式無關的。任何在模式中建立物件的工廠類必須實現這個介面。這個角色可以由Java介面或者抽象類實現。
(2)具體工廠(Concrete Creator)角色:擔任這個角色的是實現了抽象工廠介面的具體Java類。具體工廠角色含有與應用密切相關的邏輯,並且受到應用程式的呼叫以建立產品物件。
(3)抽象產品(Product)角色:工廠方法模式所建立的物件的超型別,也就是產品物件的共同父類或共同擁有的介面。這個角色可以由Java介面或者抽象類實現。
(4)具體產品(Concrete Product)角色:這個角色實現了抽象產品角色所宣告的介面。工廠方法模式所建立的每一個物件都是某個具體產品角色的例項。
注意:一個工廠方法模式的實現依賴於工廠角色和產品角色的多型性,在有些情況下,這個模式可以出現退化,其特徵就是多型性的喪失。可以退化的很像簡單工廠模式,經常被簡單工廠模式代替;也可以退化的根本就不是工廠方法模式了,注意識別。
程式碼演示
interface Product
{
}
class ConcreteProduct1 implements Product
{
public ConcreteProduct1() {}
}
class ConcreteProduct2 implements Product
{
public ConcreteProduct2() {}
}
interface Creator
{
//工廠方法
public Product factory();
}
class ConcreteCreator1 implements Creator
{
public Product factory()
{
return new ConcreteProduct1();
}
}
class ConcreteCreator2 implements Creator
{
public Product factory()
{
return new ConcreteProduct2();
}
}
class Client
{
private static Creator c1,c2;
private static Product p1,p2;
public static void main(String[] args)
{
c1 = new ConcreteCreator1();
p1 = c1.factory();
c2 = new ConcreteCreator2();
p2 = c2.factory();
}
}
工廠方法在Java中的應用
在Java容器類中應用:
Collection介面有方法iterator(),返回Iterator介面,每個實現類實現了這個iterator()方法,用於建立一個Iterator型別的物件。
URL與URLConnection的應用:
import java.net.*;
import java.io.*;
class URLConnectionReader
{
public static void main(String[] args)
{
try
{
URL b = new URL("http://www.baidu.com");
URLConnection c = b.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
String s;
while((s = in.readLine())!=null)
{
System.out.println(s);
}
in.close();
}
catch (Exception e)
{
}
}
}
抽象工廠(Abstract Factory)模式
定義
抽象工廠模式是所有形態的工廠模式中最為抽象和最具一般性的一種形態。
起源
抽象工廠模式的起源或者說最早的應用,是用於建立分屬於不同作業系統的視窗構件。
更多瞭解
抽象工廠,是工廠的工廠,可以配備一個靜態方法,按照引數,返回所對應的具體工廠的例項(抽象工廠型別)。
建造(Builder)模式
定義
建造模式可以將一個產品的內部表象與產品的生成過程分割開來,從而可以使一個建造過程生成具有不同的內部表象的產品物件
結構圖
更多瞭解
(1)建造模式和抽象工廠模式非常相像,兩者有都是用來建立同時屬於幾個產品族的物件的模式。
(2)在抽象工廠模式中,每一次工廠物件被呼叫時都會返還一個完整的產品物件,而客戶端有可能會決定把這些產品組裝成一個更大更復雜的產品,也有可能不會;建造模式則不同,它一點一點地建造出一個複雜的產品,而這個產品的組裝過程就發生在建造者角色的內部。換言之,抽象工廠模式處在更加具體的制度上,而建造模式則處於更加巨集觀的制度上。
原型(Prototype)模式
定義
通過給出一個原型物件來指明所要建立的物件的型別,然後用複製這個原型物件的辦法創造出更多同類型的物件,這就是原型模式的用意。
結構圖--簡單形式的原始模式
結構圖--登記形式的原始模式
更多瞭解
關於原型模式,只需要深刻了解Java語言中的克隆機制,深層次克隆,淺層次克隆就可以了。實際上這種模型,就是對我們日常工作中使用克隆這種行為的總結。
建立模式(Creational Pattern)小結
建立模式(Creational Pattern)一共有七種,分別是:簡單工廠模式、工廠方法模式、抽象工廠模式、建造模式、原型模式、單例模式、多例模式。
大致描述如下: