1. 程式人生 > >設計模式學習(二)-簡單工廠模式

設計模式學習(二)-簡單工廠模式

---恢復內容開始---

簡單工廠設計模式

  1. 簡單工廠模式定義:

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

  1. 簡單工廠主要分為如下幾個角色

    1. 抽象產品(abstract product):為所有具體產品的抽象表現,一般為抽象類

    2. 具體產品(product):為抽象產品的具體實現

    3. 生成產品工廠(factory):負責實現建立所有例項的內部邏輯

  2. 具體類圖

    1. Book 抽象產品

    2. ChineseBook,EnglishBook具體產品

    3. BookFactory:工廠類

     

  3. 具體Java實現

    package cn.lonecloud.pattern.creational.simplefactory;

    /**
    * @author lonecloud
    * @version v1.0
    * @Package cn.lonecloud.pattern.creational.simplefactory
    * @Description: TODO
    * @date 2018/12/2下午12:09
    */
    public class BookFactory {

       public static Book getBook(String name){
           if ("english".equals(name)){
               return new EnglishBook();
          }else {
               return new ChineseBook();
          }
      }
    }
  4. 該模式的優點:

    1. 將類的建立縮小到factory類中進行,免除呼叫方對建立類時候的一個責任,

    2. 客戶端無需知道類名,只需要知道對應的引數即可

    3. 可以在引入配置檔案的基礎上,可以無需改變程式碼即可更換產品,實現靈活

  5. 該模式的缺點

    1. 所有類建立都建立在factory中進行,一旦該類出現了問題,則其他的所依賴的類都無法進行

    2. 系統擴充套件複雜,如果產品型別比較多的話,會導致factory中邏輯判斷會非常多,不利於系統維護和擴充套件

    3. 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構

  6. 使用場景

    1. 負責建立的類的數量相對較少,由於建立類的數量相對比較少,類的複雜性也就不會這麼高

    2. 客戶端建立類的時候,既不需要關心建立細節,甚至連類名都不需要記住,只需要知道型別所對應的引數。

  7. 應用

    1. Calendar中的使用

        private static Calendar createCalendar(TimeZone zone,
                                              Locale aLocale)
      {
           CalendarProvider provider =
               LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                                    .getCalendarProvider();
           if (provider != null) {
               try {
                   return provider.getInstance(zone, aLocale);
              } catch (IllegalArgumentException iae) {
                   // fall back to the default instantiation
              }
          }

           Calendar cal = null;

           if (aLocale.hasExtensions()) {
               String caltype = aLocale.getUnicodeLocaleType("ca");
               if (caltype != null) {
                   switch (caltype) {
                   case "buddhist":
                   cal = new BuddhistCalendar(zone, aLocale);
                       break;
                   case "japanese":
                       cal = new JapaneseImperialCalendar(zone, aLocale);
                       break;
                   case "gregory":
                       cal = new GregorianCalendar(zone, aLocale);
                       break;
                  }
              }
          }
           if (cal == null) {
               if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                   cal = new BuddhistCalendar(zone, aLocale);
              } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                          && aLocale.getCountry() == "JP") {
                   cal = new JapaneseImperialCalendar(zone, aLocale);
              } else {
                   cal = new GregorianCalendar(zone, aLocale);
              }
          }
           return cal;
      }

---恢復內容結束---