1. 程式人生 > >《設計模式之禪》-5.抽象工廠模式

《設計模式之禪》-5.抽象工廠模式

抽象工廠模式

定義:

為建立一組相關或相互依賴的物件提供一個介面,而且無需指定它們的具體類

抽象產品類

public abstract class AbstractProductA {
    //每個產品的共有方法
    public void shareMethod () {
    }
    //每個產品相同方法,不同實現
    public abstract void doSomething ();
}

具體產品類

public class ProductA1 extends Abstract  ProductA {
    public void doSomething () {
        System.out.print("產品類A的實現");
    }
}

public class ProductA2 extends AbstractProductA {
    public void doSomething (){
        System.out.print("產品類B的實現");
    }
}

 抽象工廠類

public abstract class AbstractCreator {
    //建立A產品家族
    public abstract AbstractProductA createProductA();
    //建立B產品家族
    public abstract AbstractProductB createProductB();
}

注意: 有N個產品族,在抽象工廠類中就應該有N個建立方法

 

產品等級1的實現類

public class Creator1 extends AbstractCreator {
    //只生產產品等級為1的A產品
    public AbstractProductA createProductA () {
        return new ProductA1();
    }
    //只生產產品等級為1的B產品
    public AbstractProductB createProductB () {
        return new ProductB1();
    }
}

產品等級2的實現類

public class Creator1 extends AbstractCreator {
    //只生產產品等級為2的A產品
    public AbstractProductA createProductA () {
        return new ProductA2();
    }
    //只生產產品等級為1的B產品
    public AbstractProductB createProductB () {
        return new ProductB2();
    }
}

注意: 有M個產品等級就應該有M個實現工廠類,在每個實現工廠中,實現不同產品族的生產任務

 

如何在場景類中產生一個與實現無關的物件

public class client {
    public static void main(String[] args) {
        //定義出兩個工廠
        AbstractCreator creator1 = new Creator1();
        AbstractCreator creator2 = new Creator2();
        //產生A1物件
        AbstractProductA a1 = creator1.creatorProductA();
        AbstractProductA a2 = creator2.creatorProductA();
        AbstractProductA b1 = creator1.creatorProductB();
        AbstractProductA b2 = creator2.creatorProductB();
    }
}

在場景類中,沒有任何一個方法與實現類有關係,對於一個產品來說,我們只需要知道它的工廠方法就可以直接產生一個產品對戲那個,而無需關心它的實現類、

抽象工廠模式的應用:

優點:

1.封裝性,高層模組不需要關心產品的實現,而只需要關心介面

2.產品族內的約束為非公開狀態,具體的產品族內約束在工廠內實現

 

缺點:

產品族的擴充套件非常困難,如果要增加一個產品C,則需要修改抽象工廠類,增加一個產品C的介面,然後實現類也需要修改,抽象類和介面是一個契約,改變契約,則與契約相關的程式碼都要修改,這樣是嚴重違反開閉原則

使用場景:

一個物件族(或者一組沒有任何關係的物件)都有相同的約束,則可以使用抽象工廠模式,比如一個應用需要在不同平臺上面執行時

注意事項:

抽象工廠類只是擴充套件產品族困難,而不是產品等級,在該模式下的產品等級非常容易擴充套件,比如要增加一個等級3的A和B產品,只要增加一個工廠類負責新增加出來的產品生產任務即可,也就是說 橫向擴充套件容易,縱向擴充套件困難

舉個栗子

//首先初始化一個產品類
public class Product3 {
    public void doSomething (){
        System.out.print("產品類3的實現");
    }
}
//增加一個工廠類 用於產品等級3的實現類
public class Creator3 extends AbstractCreator {
    //只生產產品等級為2的A產品
    public AbstractProductA createProductA () {
        return new ProductA3();
    }
    //只生產產品等級為1的B產品
    public AbstractProductB createProductB () {
        return new ProductB3();
    }
}