文章更新時間:2020/07/15
一、一句話背景
假如我是一個汽車經銷商,那我不光是賣車,也得賣相關的配件吧,比如潤滑油,輪胎之類的...
基於這個需求那我能不能整一個抽象的工廠,我需要啥直接告訴這個抽象工廠,具體生產哪一類產品讓這個抽象工廠自己去對接,這樣我不管需要啥都只用找這個抽象工廠的負責人就可以,而不用找每一類具體產品工廠的負責人,我可就省事多了~
二、使用場景
使用場景:調用一整套產品族的場景。
如:參加不同類型的抽獎活動,QQ換皮膚
優點:抽象工廠可以簡單的理解成為其他工廠的總工廠,基於這個概念我們可以把一整套的東西再次進行抽象出來,這樣調用起來就更方便了。
缺點:如果抽象工廠功能十分強大時(可創建工廠的種類很多時),工廠類中會有很多無關代碼,會顯得比較雜亂(工廠類繼承抽象工廠,需要實現抽象工廠的抽象方法)
三、模型分析
抽象工廠:定義創建抽象產品的方法,由具體工廠去繼承,生成具體產品
抽象產品:定義產品的共有屬性和方法,由具體產品去繼承
具體工廠:實現/繼承工廠類,生產具體產品
具體產品:實現/繼承抽象產品類
四、UML類圖
從UML類圖來看,抽象工廠模式與工廠方法模式其實大體上是差不多的,他們的區別主要在於:
區別主要在於產品。
工廠方法模式:
- 定義一個用於創建對象的接口,讓子類決定實例化哪一個類,主要是生成一類相關的產品
- 工廠模式針對的是產品單一的情況,即一個產品等級結構
抽象工廠模式:
- 為創建一組相關或相互依賴的對象提供一個接口,而且無需指定他們的具體類,通常生成一系列相關的產品
- 抽象工廠模式針對的是面向多個業務品種、業務分類,即多個產品等級結構
- 抽象工廠是在工廠方法的基礎上再次提煉出一層更具“通性”的工廠,使生產一類產品變為生產一系列產品
五、代碼分析
抽象工廠
/** * 汽車工廠【抽象工廠】 */ public abstract class CarAbstractFactory { //組裝發動機【抽象產品】 public abstract Motor packageMotor() throws Exception; //組裝輪胎【抽象產品】 public abstract Tyre packageTyre() throws Exception; }
具體工廠
奧迪工廠
/** * 奧迪工廠【具體工廠】 */ public class AudiFactory extends CarAbstractFactory { //具體的屬性 private Motor motor; private Tyre tyre; //組裝發動機 @Override public Motor packageMotor() throws Exception { Motor motor = new AudiMotor(); this.motor = motor; return motor; } //組裝輪胎 @Override public Tyre packageTyre() throws Exception { Tyre tyre = new GTYTyre(); this.tyre = tyre; return tyre; } /** * 輸出汽車信息 */ public void carInfo() { System.out.println("=====獲得一輛奧迪車,配置如下====="); this.motor.motorInfo(); this.tyre.tyreInfo(); } }
奔馳工廠
/** * 奔馳工廠【具體工廠】 */ public class BenzFactory extends CarAbstractFactory { //具體的屬性 private Motor motor; private Tyre tyre; //組裝發動機 @Override public Motor packageMotor() throws Exception { Motor motor = new BenzMotor(); this.motor = motor; return motor; } //組裝輪胎 @Override public Tyre packageTyre() throws Exception { Tyre tyre = new MQLTyre(); this.tyre = tyre; return tyre; } /** * 輸出汽車信息 */ public void carInfo() { System.out.println("=====獲得一輛奔馳車,配置如下====="); this.motor.motorInfo(); this.tyre.tyreInfo(); } }
寶馬工廠
/** * 寶馬車工廠【具體工廠】 */ public class BmwFactory extends CarAbstractFactory { //具體的屬性 private Motor motor; private Tyre tyre; //組裝發動機 @Override public Motor packageMotor() throws Exception { Motor motor = new BmwMotor(); this.motor = motor; return motor; } //組裝輪胎 @Override public Tyre packageTyre() throws Exception { Tyre tyre = new MQLTyre(); this.tyre = tyre; return tyre; } /** * 輸出汽車信息 */ public void carInfo() { System.out.println("=====獲得一輛寶馬車,配置如下====="); this.motor.motorInfo(); this.tyre.tyreInfo(); } }
抽象產品
發動機
/** * 發動機【抽象產品】 */ public abstract class Motor { /** * 發動機信息 */ public abstract void motorInfo(); }
輪胎
/** * 輪胎【抽象產品】 */ public abstract class Tyre { /** * 輪胎信息 */ public abstract void tyreInfo(); }
具體產品
奧迪發動機
/** * 奧迪發動機【具體產品】 */ public class AudiMotor extends Motor { @Override public void motorInfo() { System.out.println("=====奧迪發動機====="); System.out.println("加速:⭐⭐⭐"); System.out.println("極速:⭐⭐⭐⭐"); } }
奔馳發動機
/** * 奔馳發動機【具體產品】 */ public class BenzMotor extends Motor { @Override public void motorInfo() { System.out.println("=====奔馳發動機====="); System.out.println("加速:⭐⭐⭐⭐"); System.out.println("極速:⭐⭐⭐"); } }
寶馬發動機
/** * 寶馬發動機【具體產品】 */ public class BmwMotor extends Motor { @Override public void motorInfo() { System.out.println("=====寶馬發動機====="); System.out.println("加速:⭐⭐⭐⭐⭐"); System.out.println("極速:⭐⭐⭐⭐"); } }
固特異輪胎
/** * 固特異輪胎【具體產品】 */ public class GTYTyre extends Tyre { @Override public void tyreInfo() { System.out.println("=====固特異輪胎====="); System.out.println("耐用指數:⭐⭐⭐⭐"); System.out.println("抓地力:⭐⭐⭐"); } }
米其林輪胎
/** * 米其林輪胎【具體產品】 */ public class MQLTyre extends Tyre { @Override public void tyreInfo() { System.out.println("=====米其林輪胎====="); System.out.println("耐用指數:⭐⭐⭐⭐⭐"); System.out.println("抓地力:⭐⭐⭐⭐"); } }
客戶下單
/** * 抽象工廠模式測試類【模擬下單】 */ public class AbstractFactoryTest { public static void main(String[] args) throws Exception { /*需求:客戶要買一輛寶馬車*/ //1、獲取寶馬工廠 CarAbstractFactory carFactory = new BmwFactory(); //2、組裝發動機 carFactory.packageMotor(); //3、組裝輪胎 carFactory.packageTyre(); //4、輸出車車配置信息 ((BmwFactory) carFactory).carInfo(); } }