定義:
抽象工廠模式是工廠方法模式的升級版。抽象工廠模式的定義是爲創建一組相關或相互依賴的對象提供一個接口,而且無須指定它們的具體類,抽象工廠模式對應的是更復雜的情況。在工廠方法模式中,如有新的需求改動,只能修改工廠類,新增或修改工廠類,到但是工廠方法模式只是針對一個系列的產品,如果是多個系列的產品呢?抽象工廠模式應運而生。
示例:
還是關於造車的例子,在工廠方法的示例的造的是汽車,是廠子的常規業務。之前的工廠主要是汽車組裝,是代加工。但是由於今年疫情的原因,進出口貿易受到限制。很多汽車的配件貿易受到限制。老闆決定自己研發汽車的配件,主要先從輪胎和油漆開始。但是之前的工廠是專門來組裝汽車的,如果要研發生產輪胎和油漆,只能改工廠完全改造。但是汽車畢竟是主營業務,而且效益也是最高的。疫情畢竟只是暫時的,主要業務恢復只是時間問題。所有老闆決定新建一個工廠來生產汽車配件,受到汽車的等級不同,生產的配件也會有等級上的區別。分兩個車間,一個車間生產專門生產等級A的產品,另一個車間生成等級B的產品。
/**
* 接口
*/
public interface PartsFactory {
}
/**
* 生產B等級的汽車配件抽象工廠
*/
public abstract class AbstractAutoPartAFactory implements PartsFactory {
//生產B等級輪胎
public abstract AbstractAutoPartA creatTyreA();
//生產B等級油漆
public abstract AbstractAutoPartA creatPaintA();
}
/**
* 生產A等級的汽車配件實際工廠
*/
public class AutoPartAFactory extends AbstractAutoPartAFactory{
@Override
public AbstractAutoPartA creatTyreA() {
return new TyreA();
}
@Override
public AbstractAutoPartA creatPaintA() {
return new PaintA();
}
}
注:B等級代碼類似,這裏就不贅述了
工廠建好了,來看下即將要生產的產品,目前要生產的產品主要是油漆和輪胎兩種汽車配件,兩種配件又分爲A、B兩個等級。
/**
* 汽車配件
*/
public interface AutoPart {
}
/**
* A等級汽車配件
*/
public abstract class AbstractAutoPartA implements AutoPart{
//配件的基本功能
public abstract void getFunction();
//配件的等級
public abstract void getGrade();
}
/**
* A等級油漆
*/
public class PaintA extends AbstractAutoPartA{
@Override
public void getFunction() {
System.out.println("油漆");
}
@Override
public void getGrade() {
System.out.println("A等級");
}
}
**
* A等級輪胎
*/
public class TyreA extends AbstractAutoPartA{
@Override
public void getFunction() {
System.out.println("輪胎");
}
@Override
public void getGrade() {
System.out.println("A等級");
}
}
產品和工廠都準備就續剩下的就是開足馬力準備生產了
public class TestAbstarctFactory {
public static void main(String[] args) {
//開動生產線
AbstractAutoPartAFactory factoryA = new AutoPartAFactory();
AbstractAutoPartBFactory factoryB = new AutoPartBFactory();
//開足馬力開始生產
System.out.println("奔馳的配件訂單.......");
AbstractAutoPartA BMWPaint = factoryA.creatPaintA();
BMWPaint.getFunction();
BMWPaint.getGrade();
AbstractAutoPartA BMWTyre = factoryA.creatTyreA();
BMWTyre.getFunction();
BMWTyre.getGrade();
System.out.println("奧拓的配件訂單.......");
AbstractAutoPartB AUTOPaint = factoryB.creatPaintB();
AUTOPaint.getFunction();
AUTOPaint.getGrade();
AbstractAutoPartB AUTOType = factoryB.creatTyreB();
AUTOType.getFunction();
AUTOType.getGrade();
}
}
執行結果:
奔馳的配件訂單.......
油漆
A等級
輪胎
A等級
奧拓的配件訂單.......
油漆
B等級
輪胎
B等級
解讀:
抽象工廠模式具有良好的封裝性,上層模塊並不考慮產品產生的細節,只是需要獲得產品,而且是多個產品。雖然抽象工廠的確解決了工廠方法模式不支持多系列的產品的問題。但是也存在同樣的問題。如上面的例子中,如果想增加一個系列。那麼需要修改的抽象工廠AbstractAutoPartAFactory 和實現類以及新增一個產品類。違背了開閉原則。這也是抽象工廠模式最大的弊端。但是,如果在同一個系列中要擴展一個新的等級的產品呢?只需要新建一個工廠就可以實現,從這一角度又滿足了開閉原則。所以抽象工廠是橫向擴展容易,縱向擴展困難。所以在設計過程中要充分考慮縱向擴展的可能性,不要冗餘也不要過於保守。
應用場景:
抽象工廠模式真正解決是多產品多系場景。每個系列之間存在約束,每個系列產品之間也存在等級上的約束。當需要創建的對象是一系列相互關聯或相互依賴的產品族時,便可以使用抽象工廠模式。