1. 程式人生 > >設計模式之建立型(2)——工廠模式

設計模式之建立型(2)——工廠模式

工廠模式的三種變種:簡單工廠模式(也稱靜態工廠模式),工廠方法模式,抽象工廠模式

一,靜態工廠模式

定義:通過專門定義一個工廠類負責建立其他類的例項,被建立的例項具有共同的父類。

三種角色:

  1. 工廠角色(SimpleFactory),負責建立所有類的內部邏輯。
  2. 抽象產品角色(IProduct),工廠角色所建立的所有物件的父類,這裡所說的父類可以時介面也可以是抽象類,它負責描述所有例項所共有的公共介面。
  3. 具體產品角色(Concrete Product),工廠角色所建立的具體例項物件,這些具體的產品具有共同的父類。

示例程式碼:

抽象產品角色:

public interface IFood {
    void eat();
}

具體產品角色: 

public class McChiken implements IFood {
    @Override
    public void eat() {
        System.out.println("Eating McChiken");
    }
}

public class Chips implements IFood {
    @Override
    public void eat() {
        System.out.println("Eating chips");
    }
}

工廠角色:

public class Mcdonlad {
    public static IFood getFood(String name) {
        switch (name) {
            case "chip":
                return new Chips();
            case "mcChiken":
                return new McChiken();
                default:
                    System.out.println("Food cannot be provided");
                    return null;
        }
    }
}

測試類:

public class McClient {
    public static void main(String[] args) {
        IFood chip = Mcdonlad.getFood("chip");
        IFood mcChiken = Mcdonlad.getFood("mcChiken");
        IFood kfcChiken = Mcdonlad.getFood("kfcChiken");
        if (chip != null) chip.eat();
        if (mcChiken != null) mcChiken.eat();
        if (kfcChiken != null) kfcChiken.eat();
    }
}

缺點:

工廠類集中所有例項的建立邏輯,當需要增加同一個產品類的產品時,就要修改工廠類,這違背了“開放封閉原則”,即違背了“對擴充套件開放,對修改關閉”的原則。

另外,當需要增加不同產品類的產品時,工廠類就無法做到,因為抽象產品角色已經確定了所生產的產品類。例如,當前的抽象產品類是生產Food型別的產品,當需要生產Drink型別的產品時,就做不到了。

實際應用

JDBC,資料庫程式設計介面API,它是Java應用程式與各類關係型資料庫進行對話的一種機制,用JDBC進行資料庫訪問時,要使用資料庫廠商提供的驅動程式介面與資料庫管理系統進行資料互動。

二,工廠方法模式

四種角色:

工廠介面,工廠介面時工廠方法的核心,與呼叫者直接互動用來提供產品。

工廠實現,工廠實現決定如何例項化產品,是實現擴充套件的途徑,需要有多少種產品,就需要有多少個具體的工廠類實現。

產品介面,是定義產品的規範,所有的產品都必須遵循產品介面定義的規範。

產品實現,實現產品介面的具體類,決定了產品在客戶端中的具體行為。

例項程式碼:

工廠介面

public interface IStore {
    IChip getChips();
}

產品介面

public interface IChip {
    void eat();
}

產品實現

public class KfcChip implements IChip {
    @Override
    public void eat() {
        System.out.println("Eating KFC Chips");
    }
}

public class McChip implements IChip {
    @Override
    public void eat() {
        System.out.println("Eating McdonladStore Chips");
    }
}

 工廠實現

public class KfcStore implements IStore {
    @Override
    public IChip getChips() {
        return new KfcChip();
    }
}

public class McdonladStore implements IStore {
    @Override
    public IChip getChips() {
        return new McChip();
    }
}

測試類

public class FactoryMethodClient {
    public static void main(String[] args) {
        IStore mcStore = new McdonladStore();
        mcStore.getChips().eat();

        IStore kfcStore = new KfcStore();
        kfcStore.getChips().eat();
    }
}

優點:

在工廠方法中,使用者只需要知道所要產品的具體工廠,無須關心具體的建立過程。

增加新產品時,只需要新增一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,符合“開閉原則”。

缺點:

每次增加一個產品時,都要新增一個具體產品類和對應的實現工廠,類的個數成倍增加。

與簡單工廠模式的對比

核心工廠類不再負責具體產品的建立,而是將具體的建立工作交給子類去完成。

 

三,抽象工廠模式

抽象工廠模式可以描述針對N種產品,M家公司各自有自己的產品線。

比如,作為手機廠商,華為和小米都可以生產手機和平板。

示例程式碼:

抽象工廠類

public interface IPhoneCorp {
    IPhone productPhone();
    IPad productPad();
}

具體工廠類

public class XiaomiCorp implements IPhoneCorp {

    @Override
    public IPhone productPhone() {
        return new XiaomiPhone();
    }

    @Override
    public IPad productPad() {
        return new XiaomiPad();
    }
}

public class HuaweiCorp implements IPhoneCorp {

    @Override
    public IPhone productPhone() {
        return new HuaweiPhone();
    }

    @Override
    public IPad productPad() {
        return new HuaweiPad();
    }
}

 抽象產品類

public interface IPad {
    void getPadDescription();
}

public interface IPhone {
    void getPhoneDescription();
}

具體產品類 

public class XiaomiPad implements IPad {
    @Override
    public void getPadDescription() {
        System.out.println("This is XiaomiPad 8");
    }
}

public class XiaomiPhone implements IPhone {
    @Override
    public void getPhoneDescription() {
        System.out.println("This is Xiaomi 8s");
    }
}

public class HuaweiPad implements IPad {
    @Override
    public void getPadDescription() {
        System.out.println("This is Huawei Pad 10");
    }
}

public class HuaweiPhone implements IPhone {
    @Override
    public void getPhoneDescription() {
        System.out.println("This is Huawei P20");
    }
}

總結:

抽象工廠模式時工廠方法模式的升級版,它用來建立一組相關或相互依賴的物件。與工廠方法模式的區別在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則是針對多個產品等級結構。換句話說,工廠方法模式提供的所有產品都是衍生自同一個介面或抽象類,而抽象工廠模式所提供的產品則是衍生自不同的介面或抽象類。