使用場景
一個對象族有相同的約束時可以使用此模式嘱巾。
例如:Android嘴纺、iOS 都有短信軟件和撥號軟件,但是具體代碼的實現(xiàn)邏輯不不一樣浓冒,這個時候可以考慮使用抽象工廠模式來生產(chǎn) Android栽渴、iOS 下的短信軟件和撥號軟件。
主要角色
AbstractFactory:抽象工廠角色稳懒。對應(yīng) AbstractFactory闲擦。
ConcreteFactory:具體工廠角色。對應(yīng) ConcreteFactory1 和 ConcreteFactory2场梆。
AbstractProduct:抽象產(chǎn)品角色墅冷。對應(yīng) AbstractProductA 和 AbstractProductB。
ConcreteProduct:具體產(chǎn)品角色或油。對應(yīng) ConcreteProductA1寞忿、ConcreteProductA2、 ConcreteProductB1顶岸、ConcreteProductB2腔彰。
示例代碼:
抽象產(chǎn)品類A
public abstract class AbstractProductA {
/**
* 每個具體的產(chǎn)品子類需要實現(xiàn)的方法
*/
public abstract void method();
}
抽象產(chǎn)品類B
public abstract class AbstractProductB {
/**
* 每個具體的產(chǎn)品子類需要實現(xiàn)的方法
*/
public abstract void method();
}
具體產(chǎn)品類A1
public class ConcreteProductA1 extends AbstractProductA {
@Override
public void method() {
System.out.println("具體產(chǎn)品A1的方法");
}
}
具體產(chǎn)品類A2
public class ConcreteProductA2 extends AbstractProductA {
@Override
public void method() {
System.out.println("具體產(chǎn)品A2的方法");
}
}
具體產(chǎn)品類B1
public class ConcreteProductB1 extends AbstractProductB {
@Override
public void method() {
System.out.println("具體產(chǎn)品B1的方法");
}
}
具體產(chǎn)品類B2
public class ConcreteProductB2 extends AbstractProductB {
@Override
public void method() {
System.out.println("具體產(chǎn)品B2的方法");
}
}
抽象工廠類
public abstract class AbstractFactory {
/**
* 創(chuàng)建產(chǎn)品A的方法
*/
public abstract AbstractProductA createProductA();
/**
* 創(chuàng)建產(chǎn)品B的方法
*/
public abstract AbstractProductB createProductB();
}
具體工廠1
public class ConcreteFactory1 extends AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB1();
}
}
具體工廠2
public class ConcreteFactory2 extends AbstractFactory {
@Override
public AbstractProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ConcreteProductB2();
}
}
簡單實現(xiàn)
需求:小明的車廠需要生產(chǎn)Q3叫编、Q7兩種類型的汽車,但是它們的零部件差別比較大霹抛。比如輪胎搓逾、發(fā)動機、制動系統(tǒng)杯拐。
-
輪胎相關(guān)類
public interface ITire { /** * 輪胎 */ void tire(); } public class NormalTire implements ITire { @Override public void tire() { System.out.println("普通輪胎"); } } public class SUVTire implements ITire { @Override public void tire() { System.out.println("越野輪胎"); } }
-
發(fā)動機相關(guān)類
public interface IEngine { /** * 發(fā)動機 */ void engine(); } public class DomesticEngine implements IEngine { @Override public void engine() { System.out.println("國產(chǎn)發(fā)動機"); } } public class ImportEngine implements IEngine { @Override public void engine() { System.out.println("進口發(fā)動機"); } }
-
制動系統(tǒng)相關(guān)類
public interface IBrake { void brake(); } public class NormalBrake implements IBrake { @Override public void brake() { System.out.println("普通制動"); } } public class SeniorBrake implements IBrake { @Override public void brake() { System.out.println("高級制動"); } }
-
抽象車廠類
public abstract class CarFactory { /** * 生產(chǎn)輪胎 */ public abstract ITire createTire(); /** * 生產(chǎn)發(fā)動機 */ public abstract IEngine createEngine(); /** * 生產(chǎn)制動系統(tǒng) */ public abstract IBrake createBrake(); }
-
Q3 工廠類
public class Q3Factory extends CarFactory { @Override public ITire createTire() { return new NormalTire(); } @Override public IEngine createEngine() { return new DomesticEngine(); } @Override public IBrake createBrake() { return new NormalBrake(); } }
-
Q7 工廠類
public class Q7Factory extends CarFactory { @Override public ITire createTire() { return new SUVTire(); } @Override public IEngine createEngine() { return new ImportEngine(); } @Override public IBrake createBrake() { return new SeniorBrake(); } }
-
測試
public class Client { public static void main(String[] args) { Q3Factory factoryQ3 = new Q3Factory(); factoryQ3.createTire().tire(); factoryQ3.createEngine().engine(); factoryQ3.createBrake().brake(); System.out.println("-----------------"); Q7Factory factoryQ7 = new Q7Factory(); factoryQ7.createTire().tire(); factoryQ7.createEngine().engine(); factoryQ7.createBrake().brake(); } }
輸出結(jié)果如下:
普通輪胎 國產(chǎn)發(fā)動機 普通制動 ----------------- 越野輪胎 進口發(fā)動機 高級制動
這里只有Q3 和Q7 的工廠霞篡,如果需要增加Q5的工廠,那么需要增加響應(yīng)的類文件端逼,這樣會造成類文件非常多朗兵。因此,在開發(fā)中需要權(quán)衡慎用顶滩。
Android 源碼中的實現(xiàn)
相對較少余掖。Android 底層 MediaPlayer 的創(chuàng)建。
總結(jié)
-
優(yōu)點:
分離接口與實現(xiàn)诲祸,客戶端使用抽象工廠來創(chuàng)建需要的對象浊吏,而客戶端無需知道具體的實現(xiàn)類是哪個而昨,使其實現(xiàn)面向接口編程救氯,使得該模式在切換產(chǎn)品類時更加靈活、容易歌憨。
-
缺點:
- 類文件陡增着憨;
- 不太容易擴展新的產(chǎn)品類,因為每當(dāng)增加一個產(chǎn)品類就需要修改工廠务嫡,那么所有的具體工廠類均會被修改甲抖。
所以其在實際開發(fā)中使用較少,了解即可心铃。