設計模式之 工廠模式

      工廠模式是創建型模式之一。簡單的說,工廠模式就是爲了減少代碼的工作量,方便測試和擴展。在工廠模式中,創建對象時不會對客戶端暴露創建邏輯,並且是通過使用一個共同的接口來指向新創建的對象。創建工廠類,接收不同的參數生成不同的對象的過程。由於簡單工廠模式,抽象工廠模式,工廠方法模式依次遞進且很相似,所以放在一起總結。

一、定義

        工廠模式定義一個用於創建對象的接口,這個接口由子類決定實例話哪一個類。該模式是一個類的實例話延遲到了子類。而子類可以重寫接口方法便於創建不同類型的對像

二、分類

       簡單工廠模式

       簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,它屬於類創建型模式。在簡單 工廠模式中,可以根據參數的不同返回不同類的實例。簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。

        優點

            1、簡單工廠模式實現了責任分離

            2、工廠類中包含了對象生成的必要邏輯判斷,根據客戶端的選擇條件實例化不同的對象,所以客戶端沒有創建對象所需要的條件

            3、客戶端不直接創建產品類的對象,客戶端只作爲消費者,具體邏輯代碼交由工廠類處理

        缺點

            1、工廠類必須知道怎麼樣創建每一個對象,當增加一個對象時必須改動工廠類的邏輯代碼,所以簡單工廠模式不符合開閉原則。

            2、因爲工廠類中的工廠方法是靜態的,所以工廠類中的方法不能被重寫,工廠類只是一個單獨的類,它不能成爲一個層次的類

       抽象工廠模式

     抽象工廠模式(Abstract Factory Pattern):提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象創建型模式。

        優點:

            1、更符合開閉原則,增加創建對象時只需要修改相應的產品類和工廠子類

            2、符合單一職責原則,每個產品都有相應的工廠負責

            3、不使用靜態工廠方法,可以形成基於繼承的等級結構。

        缺點:

            1、沒有完全符合開閉原則,這是因爲在抽象工廠角色中規定了所有可能被創建的產品集合,要支持新種類的產品就意味着要對該接口進行擴 展,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。

       工廠方法模式(工廠模式)

        優點:

        缺點:

三、基本結構

       簡單工廠模式

        簡單工廠模式定義三個角色:

         · 工廠角色(Factory): 負責創建實例的具體邏輯。

      · 抽象產品角色(Product):是所有創建對象的的父類,擁有所有創建對象的公共接口。

      · 具體產品角色(CreateProduct)具體產品角色是創建目標,所有創建的對象都充當這個角色的某個具體類的實例。

        

       抽象工廠模式

        AbstractFactory:抽象工廠
        ConcreteFactory:具體工廠
        AbstractProduct:抽象產品
        Product:具體產品

         

       工廠方法模式

        Product:抽象產品

        ConcreteProduct:具體產品

        Factory:抽象工廠

        ConcreteProduct:具體工廠

        

四、時序圖

       簡單工廠模式

        

       抽象工廠模

      工廠方法模式
     

五、代碼實現

       簡單工廠模式

            1.工廠角色

public class FruitFactory {
    public static Fruit newInstance(String name) throws BadFruitException {
        if ("apple".equalsIgnoreCase(name)) {
            return new Apple();       
        } else if ("grape".equalsIgnoreCase(name)) {
            return new Grape();
        } else if ("strawberry".equalsIgnoreCase(name)) {
            return new Strawberry();
        // 其它情況,則拋出異常。
        } else {
            throw new BadFruitException("Bad fruit request!");
        }
    }
}

         2.抽象產品角色

public abstract class Fruit { 
    //公共屬性
    abstract void grow();    // 生長
    abstract void harvest(); // 收穫
    abstract void plant();   // 種植
 }

        3.具體產品角色

               由三個角色 apple、grape、strawberry都繼承抽象產品角色,重寫其中的方法表現出每個產品不一樣的行爲

        4.客戶端代碼

public class Client {

    public static void main(String[] args) {
        try {
            Fruit apple = FruitFactory.newInstance("Apple");
            apple.plant();
            apple.grow();
            apple.harvest();

            Fruit grape = FruitFactory.newInstance("Grape");
            grape.plant();
            grape.grow();
            grape.harvest();

            Fruit strawberry = FruitFactory.newInstance("strawberry");
            strawberry.plant();
            strawberry.grow();
            strawberry.harvest();

            Fruit error = FruitFactory.newInstance("error");
            error.plant();
            error.grow();
            error.harvest();
        } catch (BadFruitException e) {
            e.printStackTrace();
        }
    }
}

        抽象工廠模式     

           1、抽象工廠            

abstract class Factory{
   public abstract Product ManufactureContainer();
    public abstract Product ManufactureMould();
}

            2、具體工廠

//A廠 - 生產模具+容器產品
class FactoryA extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductA();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductA();
    }
}

//B廠 - 生產模具+容器產品
class FactoryB extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductB();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductB();
    }
}

            3、抽象產品族   

abstract class AbstractProduct{
    public abstract void Show();
}

            4、抽象產品  

//容器產品抽象類
abstract class ContainerProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

//模具產品抽象類
abstract class MouldProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

            5、具體產品

//容器產品A類
class ContainerProductA extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生產出了容器產品A");
    }
}

//容器產品B類
class ContainerProductB extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生產出了容器產品B");
    }
}

//模具產品A類
class MouldProductA extends MouldProduct{

    @Override
    public void Show() {
        System.out.println("生產出了模具產品A");
    }
}

//模具產品B類
class MouldProductB extends MouldProduct{

    @Override
    public void Show() {
        System.out.println("生產出了模具產品B");
    }
}

            6、客戶端

//生產工作流程
public class AbstractFactoryPattern {
    public static void main(String[] args){
        FactoryA mFactoryA = new FactoryA();
        FactoryB mFactoryB = new FactoryB();
        //A廠當地客戶需要容器產品A
        mFactoryA.ManufactureContainer().Show();
        //A廠當地客戶需要模具產品A
        mFactoryA.ManufactureMould().Show();

        //B廠當地客戶需要容器產品B
        mFactoryB.ManufactureContainer().Show();
        //B廠當地客戶需要模具產品B
        mFactoryB.ManufactureMould().Show();

    }
}

六、應用

       簡單工廠模式    

        1、工廠類負責創建的對象比較少:由於創建的對象較少,不會造成工廠方法中的業務邏輯太過複雜。

         2、客戶端只知道傳入工廠類的參數,對於如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,只需要知道類型所對應的參數。

        抽象工廠模式

      1、一個系統不要求依賴產品類實例如何被創建、組合和表達的表達,這點也是所有工廠模式應用的前提。

       2、這個系統有多個系列產品,而系統中只消費其中某一系列產品

       3、系統要求提供一個產品類的庫,所有產品以同樣的接口出現,客戶端不需要依賴具體實現。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章