工廠模式



💛原文地址為https://www.cnblogs.com/haixiang/p/12058894.html,轉載請注明出處!

工廠模式

簡單工廠模式

簡介

簡單工廠模式(Simple Factory Pattern)屬於類的創新型模式,又叫靜態工廠方法模式(Static FactoryMethod Pattern),是通過專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。

將“類實例化的操作”與“使用對象的操作”分開,讓使用者不用知道具體參數就可以實例化出所需要的“產品”類,從而避免了在客戶端代碼中顯式指定,實現了解耦。

即使用者可直接消費產品而不需要知道其生產的細節

優缺點

優點:實現解耦,不用關注如何生產,將使用和生產分離,如果生產的產品只有一種這種方式可以滿足使用。

缺點:如果新增產品,例如新增vivo手機,需要在SimpleFac中修改源碼,不符合設計模式的開閉原則——對修改關閉,對擴展開放,因此簡單工廠模式不屬於23種設計模式中的一種。

示例

我們通過手機的生產過程來演示簡單工廠模式。

手機產品的接口及其實現類

/** 
 * 手機接口
 */
public interface Phone {
    /** 打電話 */
    void call();
}
public class Iphone implements Phone{
    @Override
    public void call() {
        System.out.println("iphone撥打電話");
    }
}
public class Xiaomi8 implements Phone {
    @Override
    public void call() {
        System.out.println("小米8撥打電話");
    }
}

用來表示手機名稱的枚舉類

/**
 * 手機名稱 enum
 */
public enum PhoneNameEnum {
    /** iphone */
    IPHONE11("iphone"),
    /** 小米8 */
    XIAOMI8("xiaomi8"),

    ;

    String name;

    PhoneNameEnum(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

生產手機產品的工廠類

public class SimplePhoneFac {
    public Phone producePhone(String phoneName) {
        if (null == phoneName || 0 == phoneName.length()) {
            return  null;
        }
        if (phoneName.equals(PhoneNameEnum.IPHONE11.getName())) {
            return new Iphone();
        } else if (phoneName.equals(PhoneNameEnum.XIAOMI8.getName())) {
            return new Xiaomi8();
        } else {
            return null;
        }
    }
}

測試結果

public class SimpleFacTest {
    public static void main(String[] args) {
        SimplePhoneFac simplePhoneFac = new SimplePhoneFac();
        Iphone iphone = (Iphone) simplePhoneFac.producePhone(PhoneNameEnum.IPHONE11.getName());
        if (null == iphone) {
            System.out.println("iphone 生產失敗");
        } else {
            iphone.call();
        }

        Xiaomi8 xiaomi8 = (Xiaomi8) simplePhoneFac.producePhone(PhoneNameEnum.XIAOMI8.getName());
        if (null == xiaomi8) {
            System.out.println("xiaomi8 生產失敗");
        } else {
            xiaomi8.call();
        }
    }
}
iphone撥打電話
小米8撥打電話

工廠方法模式

簡介

工廠方法模式,又稱工廠模式,定義一個創建產品對象的工廠接口,將產品對象的實際創建工作推遲到具體子工廠類當中。這滿足創建型模式中所要求的“創建與使用相分離”的特點。

將類的實例化(具體產品的創建)延遲到工廠類的子類(具體工廠)中完成,即由子類來決定應該實例化(創建)哪一個類。

本節介紹的工廠方法模式是對簡單工廠模式的進一步抽象化,其好處是可以使系統在不修改原來代碼的情況下引進新的產品,即滿足開閉原則。

模式的結構

工廠方法模式的主要角色如下。

  1. 抽象工廠(Abstract Factory):提供了創建產品的接口,調用者通過它訪問具體工廠的工廠方法 newProduct() 來創建產品。
  2. 具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的創建。
  3. 抽象產品(Product):定義了產品的規范,描述了產品的主要特性和功能。
  4. 具體產品(ConcreteProduct):實現了抽象產品角色所定義的接口,由具體工廠來創建,它同具體工廠之間一一對應。

優缺點

工廠方法模式的主要優點有:

  • 用戶只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體創建過程;
  • 在系統增加新的產品時只需要添加具體產品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;

其缺點是:每增加一個產品就要增加一個具體產品類和一個對應的具體工廠類,這增加了系統的復雜度。

示例

我們通過手機工廠分別生成iphone和小米8兩種機型來說明工廠方法模式。后續如果新增產品例如Vivo手機只需要實現Phone接口,創建VivoFac工廠類進行生產即可。

手機產品接口及其具體實現類

/** 
 * 手機接口
 */
public interface Phone {
    /** 打電話 */
    void call();
}
public class Iphone implements Phone{
    @Override
    public void call() {
        System.out.println("iphone撥打電話");
    }
}
public class Xiaomi8 implements Phone {
    @Override
    public void call() {
        System.out.println("小米8撥打電話");
    }
}

抽象工廠及其具體工廠

/**
 * phone 的抽象工廠
 */
public abstract class AbstractPhoneFac {
    /** 生產 phone */
    public abstract Phone producePhone();
}
/**
 * iphone 生產工廠
 */
public class IphoneFac extends AbstractPhoneFac {
    @Override
    public Phone producePhone() {
        return new Iphone();
    }
}
/**
 * 小米生產工廠
 */
public class XiaomiFac extends AbstractPhoneFac {
    @Override
    public Phone producePhone() {
        return new Xiaomi8();
    }
}

測試結果

public class FacMethodTest {
    public static void main(String[] args) {
        XiaomiFac xiaomiFac = new XiaomiFac();
        Xiaomi8 xiaomi8 = (Xiaomi8) xiaomiFac.producePhone();
        xiaomi8.call();

        IphoneFac iphoneFac = new IphoneFac();
        Iphone iphone = (Iphone) iphoneFac.producePhone();
        iphone.call();
    }
}
小米8撥打電話
iphone撥打電話


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM