軟件設計模式學習(五)工廠方法模式

工廠方法模式

工廠方法模式是簡單工廠模式的延伸,它繼承了簡單工廠模式的優點,同時彌補了簡單工廠的缺陷,更好地符合開閉原則的要求,增加新的具體產品對象不需要對已有系統作任何修改。


模式定義

工廠方法模式又稱爲工廠模式,也叫虛擬構造器模式或者多態工廠模式,屬於類創建模式。在工廠模式中,工廠父類負責定義產品對象的公共接口,而子工廠模式負責生成具體的產品對象,這樣做的目的是將產品類實例化操作延遲到工廠子類中完成,即通過工廠子類來確定實例化哪一個對象。


模式結構

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YE7m8YT1-1583502341631)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20200306175830923.png)]

  1. Product(抽象產品)

    抽象產品是定義產品的接口,是工廠方法模式所創建對象的超類型,也就是產品對象的共同父類接口

  2. ConcreteProduct(具體產品)

    具體產品實現抽象產品接口,某種類型的具體產品由專門具體創建

  3. Facory(抽象工廠)

    在抽象工廠類中,聲明工廠方法,用於返回一個產品。抽象工廠是工廠方法模式的核心,任何在模式中創建對象的工廠類都必須實現該接口。

  4. ConcreteFactory(具體工廠)

    具體工廠是抽象工廠類的子類,實現了抽象工廠定義的工廠方法,返回一個具體產品類的實例。


模式分析

在工廠方法模式中,核心的工廠類不再負責所有產品的創建,而是將具體創建的工作交給了子類。核心類僅僅給出具體工廠實現的接口,而不負責哪一個產品被實例化的細節,使得工廠方法模式允許系統在不修改工廠角色的情況下引進新產品。

實際的開發應用中,不直接使用new關鍵字來創建對象,而是將具體類的類名寫入配置文件,在通過java反射機制,讀取XML格式的配置文件,根據存儲在XML文件的類名字符串生成對象。


工廠方法模式實例之手機工廠

  1. 實例說明

    之前的簡單工廠模式時我們也創建過一個類似實例,但卻是違反了開閉原則的。通過工廠方法模式進行一次重構,將原有工廠進行分割,爲每種品牌的手機提供一個子工廠,使整個系統具有更好的靈活性和可擴展性。

  2. 實例類圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CJwdRjod-1583502341633)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20200306203608380.png)]

  1. 實例代碼及解釋

    1. 抽象產品類Phone

      public abstract class Phone {
      
          public abstract void use();
      }
      
    2. 具體產品類HuaweiPhone

      public class HuaweiPhone extends Phone {
      
          @Override
          public void use() {
      
              System.out.println("華爲手機使用中....");
          }
      }
      
    3. 具體產品類XiaomiPhone

      public class XiaomiPhone extends Phone {
      
          @Override
          public void use() {
      
              System.out.println("小米手機使用中....");
          }
      }
      
    4. 抽象工廠類PhoneFactory

      public interface PhoneFactory {
      
          Phone producePhone();
      }
      
    5. 具體工廠類HuaweiPFactory

      public class HuaweiPFactory implements PhoneFactory {
          @Override
          public Phone producePhone() {
              System.out.println("華爲工廠生產華爲手機......");
              return new HuaweiPhone();
          }
      }
      
    6. 具體工廠類XiaomiPFactory

      public class XiaomiPFactory implements PhoneFactory {
      
          @Override
          public Phone producePhone() {
      
              System.out.println("小米工廠生產小米手機......");
              return new XiaomiPhone();
          }
      
      }
      
    7. XML操作工具類

      public class XMLUtilPhone {
      
          public static Object getBean() throws Exception {
      
              //創建解析器工廠
              DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
              //創建解析器
              DocumentBuilder builder = builderFactory.newDocumentBuilder();
              //得到document
              Document document = builder.parse("configPhone.xml");
              //獲取包含品牌名稱的文本節點
              NodeList brandNameList = document.getElementsByTagName("factoryName");
              Node classNode = brandNameList.item(0).getFirstChild();
              String factoryName = classNode.getNodeValue().trim();
      
      //        System.out.println(factoryName);
      
              Class c = Class.forName("com.factoryMethod." + factoryName);
              Object o = c.newInstance();
              return o;
          }
      }
      
    8. 配置文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <configuration>
         <factoryName>XiaomiPFactory</factoryName>
      </configuration>
      
    9. 測試類

      public class Test {
      
          public static void main(String[] args) throws Exception {
      
              PhoneFactory phoneFactory = (PhoneFactory) XMLUtilPhone.getBean();
      
              Phone phone = phoneFactory.producePhone();
      
              phone.use();
          }
      }
      
    10. 結果分析

      如果在配置文件將節點中內容設置爲 XiaomiPFactory,則輸出結果如下:
      在這裏插入圖片描述
      如果在配置文件將節點中內容設置爲 XiaomiPFactory,則輸出結果如下:
      在這裏插入圖片描述
      如果需要增加新的類型的手機,則首先要增加一個新的具體產品類,再增加對於的具體工廠類。

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