您好,登錄后才能下訂單哦!
設(shè)計模式——抽象工廠模式(JAVA)
在抽象工廠模式中,一個具體工廠可以生產(chǎn)一組相關(guān)的具體產(chǎn)品,這樣的一組產(chǎn)品成為產(chǎn)品族,產(chǎn)品族中的每一個產(chǎn)品都屬于某一個產(chǎn)品繼承等等級結(jié)構(gòu)。當(dāng)系統(tǒng)所提供的工廠生產(chǎn)的具體產(chǎn)品并不是一個簡單的對象,而是多個位于不同產(chǎn)品等級結(jié)構(gòu)、屬于不同類型的具體產(chǎn)品時就可以使用抽象工廠模式。
抽象工廠模式與工廠方法模式最大的區(qū)別在于,工廠方法模式針對的是一個產(chǎn)品等級結(jié)構(gòu),而抽象工廠模式需要面對多個產(chǎn)品等級結(jié)構(gòu),一個工廠等級結(jié)構(gòu)可以負(fù)責(zé)多個不同產(chǎn)品等級結(jié)構(gòu)中的產(chǎn)品對象的創(chuàng)建,當(dāng)一個工廠等級結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級結(jié)構(gòu)的一個產(chǎn)品族中的所有對象時,抽象工廠模式比工廠方法模式更為簡單、更有效率。
抽象工廠模式為創(chuàng)建一組對象提供了一種解決方案。與工廠方法模式相比,抽象工廠模式中的具體工廠不只是創(chuàng)建一種產(chǎn)品,而是負(fù)責(zé)創(chuàng)建一組產(chǎn)品。
抽象工廠模式定義:提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無須指定它們具體的類。
一、抽象工廠模式的結(jié)構(gòu)
在抽象工廠模式張,每一個具體工廠都提供了多個工廠方法用于產(chǎn)生多種不同類型的產(chǎn)品,這些產(chǎn)品構(gòu)成一個產(chǎn)品族。
抽象工廠模式包含以下4個角色:
(1)AbstractFactory(抽象工廠):它聲明了一組用于創(chuàng)建一族產(chǎn)品的方法,每一個方法對應(yīng)一種產(chǎn)品。
(2)ConcreteFactory(具體工廠):它實現(xiàn)了抽象工廠中聲明的創(chuàng)建產(chǎn)品的方法,生成一組具體產(chǎn)品,這些產(chǎn)品構(gòu)成了一個產(chǎn)品族,每一個產(chǎn)品都位于某個產(chǎn)品等級結(jié)構(gòu)中。
(3)AbstractProduct(抽象產(chǎn)品):它為每種產(chǎn)品聲明接口,在抽象產(chǎn)品中聲明了產(chǎn)品所具有的業(yè)務(wù)方法。
(4)ConcreteProduct(具體產(chǎn)品):它定義具體工廠生產(chǎn)的具體產(chǎn)品對象,它實現(xiàn)抽象產(chǎn)品接口中聲明的業(yè)務(wù)方法。
二、抽象工廠模式的實現(xiàn)
在抽象工廠中聲明了多個工廠方法,用于創(chuàng)建不同類型的產(chǎn)品,抽象工廠可以是接口,也可以是抽象類或具體類。
abstract class AbstractFactory
{
public abstract AbstractProduct CreateProduct(); //工廠方法
......
}
具體工廠實現(xiàn)了抽象工廠,每一個具體的工廠方法創(chuàng)建一個特定的產(chǎn)品對象,而同一個具體工廠所創(chuàng)建的產(chǎn)品對象構(gòu)成了一個產(chǎn)品族。對于每一個具體工廠類:
class ConcreteFactory : AbstractFactory
{
//工廠方法
public override AbstractProduct CreateProduct()
{
return new ConcreteProduct();
}
......
}
與工廠方法模式一樣,抽象工廠模式也可以為每一種產(chǎn)品提供一組重載的工廠方法,以不同的方式來創(chuàng)建產(chǎn)品對象。
三、抽象工廠模式的應(yīng)用
在上面的類圖中,兩廂車和三廂車稱為兩個不同的等級結(jié)構(gòu);而2.0排量車和2.4排量車則稱為兩個不同的產(chǎn)品族。再具體一點,2.0排量兩廂車和2.4排量兩廂車屬于同一個等級結(jié)構(gòu),2.0排量三廂車和2.4排量三廂車屬于另一個等級結(jié)構(gòu);而2.0排量兩廂車和2.0排量三廂車屬于同一個產(chǎn)品族,2.4排量兩廂車和2.4排量三廂車屬于另一個產(chǎn)品族。
明白了等級結(jié)構(gòu)和產(chǎn)品族的概念,就理解工廠方法模式和抽象工廠模式的區(qū)別了,如果工廠的產(chǎn)品全部屬于同一個等級結(jié)構(gòu),則屬于工廠方法模式;如果工廠的產(chǎn)品來自多個等級結(jié)構(gòu),則屬于抽象工廠模式。在本例中,如果一個工廠模式提供2.0排量兩廂車和2.4排量兩廂車,那么他屬于工廠方法模式了如果一個工廠模式提供2.4排量兩廂車和2.4排量三廂車兩個產(chǎn)品,那么這個工廠模式就是抽象工廠模式,因為他提供的產(chǎn)品是分屬兩個不同的等級結(jié)構(gòu)。當(dāng)然,如果一個工廠提供全部四種車型的產(chǎn)品,因為產(chǎn)品分屬兩個等級結(jié)構(gòu),他當(dāng)然也屬于抽象工廠模式了。
抽象工廠模式代碼:
package AbstractFactoryModel;
interface IProduct1 {
public void show();
}
interface IProduct2{
public void show();
}
class Product1 implements IProduct1{
public void show(){
System.out.println("這是1型產(chǎn)品");
}
}
class Product2 implements IProduct2{
public void show(){
System.out.println("這是2型產(chǎn)品");
}
}
interface IFactory{
public IProduct1 createProduct1();
public IProduct2 createProduct2();
}
class Factory implements IFactory{
public IProduct1 createProduct1(){
return new Product1();
}
public IProduct2 createProduct2(){
return new Product2();
}
}
客戶端代碼:
package AbstractFactoryModel;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
IFactory factory=new Factory();
factory.createProduct1().show();
factory.createProduct2().show();
}
}
四、抽象工廠模式的優(yōu)缺點
優(yōu)點:
(1)隔離了具體類的生成,使得客戶端并不需要知道什么被創(chuàng)建。只需要改變具體工廠的實例,就可以在某種程度上改變整個軟件系統(tǒng)的行為。
(2)當(dāng)一個產(chǎn)品族中的多個對象被設(shè)計成一起工作時,它能保證客戶端始終只使用同一個產(chǎn)品族。
(3)增加新產(chǎn)品族很方便,無須修改已有系統(tǒng),符合開閉原則
缺點:
增加新的產(chǎn)品等級結(jié)構(gòu)麻煩,需要對原有系統(tǒng)進行較大規(guī)模的修改,甚至需要修改抽象層代碼,這顯然會帶來很大的不便,違背了開閉原則。
五、使用場景
(1)一個系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實例如何被創(chuàng)建、組合和表達的細節(jié),這對于所有類型的工廠模式都是很重要的,用戶無須關(guān)心對象的創(chuàng)建過程,將對象的創(chuàng)建和使用解耦。
(2)系統(tǒng)中有多于一個的產(chǎn)品族,但每次只使用其中某一產(chǎn)品族,可以通過配置文件等方式使用戶能夠動態(tài)地改變產(chǎn)品族,也可以很方便地增加新的產(chǎn)品族。
(3)屬于同一個產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計中體現(xiàn)出來。同一個產(chǎn)品族中的產(chǎn)品可以是沒有任何關(guān)系的對象,但是它們都具有一些共同的約束,如同一操作系統(tǒng)下的按鈕和文件框,按鈕和文件框之間沒有直接的關(guān)系,但它們都是屬于某一操作系統(tǒng)的。此時具有一個共同的約束條件:操作系統(tǒng)的類型。
(4)產(chǎn)品等級結(jié)構(gòu)穩(wěn)定,設(shè)計完成之后,不會向系統(tǒng)中增加新的產(chǎn)品等級結(jié)構(gòu)或者刪除已有的產(chǎn)品等級結(jié)構(gòu)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。