設計模式之工廠模式

工廠模式

  • 實現建立者與調用者的分離編程

以化妝品爲例atom

  • 生產者:spa

    • 一個接口,提供了生產化妝品的方法設計

    public interface Cosmetics {
       void productCosmetics();
    }
  • 生產的對象:對象

    • 口紅blog

      public class Lipstick implements Cosmetics{

         public void productCosmetics() {
             System.out.println("口紅");
        }
      }
    • 眼影繼承

      public class EyeShadow implements Cosmetics{

         public void productCosmetics() {
             System.out.println("眼影");
        }
      }
     

 

一、傳統的方式

圖解接口

 

  • 消費者ip

    • 消費者要首先把 Lipstick 和 EyeShadow 實例化(new),才能實現對象的方法。get

    public class Consumer {
       public static void main(String[] args) {

           Cosmetics lipstick = new Lipstick();
           Cosmetics eyeShadow = new EyeShadow();

           lipstick.productCosmetics();
           eyeShadow.productCosmetics();
      }
    }

 

二、工廠模式(靜態工廠模式)

圖解

 

  • 化妝品工廠

    public class CosmeticsFactory {
       public static Cosmetics getCosmeticsFactory(String factory){
           if (factory.equals("口紅")){
               return new Lipstick();
          }else if (factory.equals("眼影")){
               return new EyeShadow();
          }else {
               return null;
          }
      }
    }
  • 消費者

    • 經過化妝品工廠來獲得對象的實例化,無需new,來實現對象的方法

    public class Consumer {
       public static void main(String[] args) {

           Cosmetics lipstick = CosmeticsFactory.getCosmeticsFactory("口紅");
           lipstick.productCosmetics();

           Cosmetics eyeShadow = CosmeticsFactory.getCosmeticsFactory("眼影");
           eyeShadow.productCosmetics();
      }
    }
  • 工廠模式缺點:

    OOP七大原則之開閉原則:一個軟件的實體應對擴展開放,對修改關閉

    工廠模式實現不了開閉原則,若是要擴展新的功能,必須修改CosmeticsFactory才能實現

 

三、工廠方法模式

  • 解決工廠模式沒法實現開閉原則的問題

圖解

 

  • 化妝品工廠

    public interface CosmeticsFactory {
       Cosmetics getCosmetics();
    }
  • 口紅工廠

    public class LipstickFactory implements CosmeticsFactory {
       public Cosmetics getCosmetics() {
           return new Lipstick();
      }
    }
  • 眼影工廠

    public class EyeShadowFactory implements CosmeticsFactory {
       public Cosmetics getCosmetics() {
           return new EyeShadow();
      }
    }
  • 消費者

    public class Consumer {
       public static void main(String[] args) {

           Cosmetics lipstick = new LipstickFactory().getCosmetics();
           lipstick.productCosmetics();

           Cosmetics eyeShadow = new EyeShadowFactory().getCosmetics();
           eyeShadow.productCosmetics();
      }
    }
  • 新增一個產品:

    只須要編寫一個產品類,例如眉筆,編寫一個眉筆工廠繼承化妝品工廠,

    可在不改動原有代碼的基礎上擴展功能,實現開閉原則。

 

四、抽象工廠模式

  • 簡單工廠模式 和 工廠方法模式 都是用來生產同一等級結構的任意產品

    抽象工廠模式 統一建立同一系列的產品,能夠建立多個產品家族的多個等級結構的產品

 

圖解

 

實現

  • 產品工廠:

    public interface ProductFactory {

       //生產手機
       Phone productPhone();
       //生產電腦
       Computer productComputer();
    }
  • 手機:

    public interface Phone {

       //生產手機屏
       void productMobileScreen();
       //生產手機外殼
       void productPhoneShell();
       //生產手機套
       void productPhoneSet();
    }
  • 電腦:

    public interface Computer {

       //生產電腦屏
       void productMobileScreen();
       //生產電腦外殼
       void productPhoneShell();
       //生產電腦套
       void productPhoneSet();
    }
  • HUAWEI產品工廠:

    public class HUAWEIProductFactory implements ProductFactory {
       //實例化HUAWEI手機
       public Phone productPhone() {
           return new HUAWEIPhone();
      }

       //實例化HUAWEI電腦
       public Computer productComputer() {
           return new HUAWEIComputer();
      }
    }
  • ASUS產品工廠:

    public class ASUSProductFactory implements ProductFactory {

       //實例化ASUS手機
       public Phone productPhone() {
           return new ASUSPhone();
      }

       //實例化ASUS電腦
       public Computer productComputer() {
           return new ASUSComputer();
      }
    }
  • HUAWEI手機:

    public class HUAWEIPhone implements Phone {
       public void productMobileScreen() {
           System.out.println("生產HUAWEI手機屏");
      }

       public void productPhoneShell() {
           System.out.println("生產HUAWEI手機外殼");
      }

       public void productPhoneSet() {
           System.out.println("生產HUAWEI手機套");
      }
    }
  • ASUS手機:

    public class ASUSPhone implements Phone {
       public void productMobileScreen() {
           System.out.println("生產ASUS手機屏");
      }

       public void productPhoneShell() {
           System.out.println("生產ASUS手機外殼");
      }

       public void productPhoneSet() {
           System.out.println("生產ASUS手機套");
      }
    }
  • HUAWEI電腦:

    public class HUAWEIComputer implements Computer {
       public void productMobileScreen() {
           System.out.println("生產HUAWEI電腦屏");
      }

       public void productPhoneShell() {
           System.out.println("生產HUAWEI電腦外殼");
      }

       public void productPhoneSet() {
           System.out.println("生產HUAWEI電腦套");
      }
    }
  • ASUS電腦:

    public class ASUSComputer implements Computer {
       public void productMobileScreen() {
           System.out.println("生產ASUS電腦屏");
      }

       public void productPhoneShell() {
           System.out.println("生產ASUS電腦外殼");
      }

       public void productPhoneSet() {
           System.out.println("生產ASUS電腦套");
      }
    }
  • 消費者:

    public class Consumer {
       public static void main(String[] args) {

           //消費者直接操做HUAWEI和ASUS的產品工廠
           HUAWEIProductFactory huaweiProductFactory = new HUAWEIProductFactory();
           ASUSProductFactory asusProductFactory = new ASUSProductFactory();
           
           //經過工廠生產手機和電腦
           //huawei電腦
           Computer huaweiComputer = huaweiProductFactory.productComputer();
           //asus手機
           Phone asusPhone = asusProductFactory.productPhone();
           
           //調用生產的手機和電腦中的方法,操做手機和電腦
           huaweiComputer.productMobileScreen();
           huaweiComputer.productPhoneShell();
           
           asusPhone.productPhoneShell();
           asusPhone.productPhoneSet();
      }
    }
  • 優勢:

    具體產品在應用層的代碼隔離,無需關心建立的細節

    將同一系列的產品統一到一塊兒建立

  • 缺點:

    產品簇中擴展新的產品困難

    增長了系統的抽象性和理解難度

 

五、小結

  • 簡單工廠模式

    • 雖然沒有實現開閉原則,但實際使用最多

  • 工廠方法模式

    • 不修改已有類的前提下,能夠增長新的工廠類進行擴展

  • 抽象工廠模式

    • 不能夠增長產品,能夠增長產品族

 

  • 三種模式對比

    • 代碼複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式

    • 結構複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式

    • 編程複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式

    • 管理複雜度:簡單工廠模式 < 工廠方法模式 < 抽象工廠模式

  • 根據設計原則,應使用工廠方法模式

    根據實際業務,工廠方法模式使用最多

 

  • 工廠模式應用場景:

    • JDK中的Calenda的getInstance()方法

    • JDBC中的Connection對象的獲取

    • Spring中IOC容器建立管理bean對象

    • 反射中Class對象的newInstance()方法

相關文章
相關標籤/搜索