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

工廠方法模式

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


模式定義

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


模式結構

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

  1. Product(抽象產品)工具

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

  2. ConcreteProduct(具體產品)ui

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

  3. Facory(抽象工廠)xml

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

  4. ConcreteFactory(具體工廠)blog

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


模式分析

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

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


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

  1. 實例說明

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

  2. 實例類圖

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

  3. 實例代碼及解釋

    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,則輸出結果以下:
      在這裏插入圖片描述 若是須要增長新的類型的手機,則首先要增長一個新的具體產品類,再增長對於的具體工廠類。

相關文章
相關標籤/搜索