【淺析】靜態工廠方法


  第一次看到這個名詞是在Effective的第一條中,書中先是數落了一番構造器之后提出靜態工廠方法的好處如何如何。看完后覺得,雖然這個名詞之前沒聽過,其實在開發途中用的不少,入類型轉換valueOf(),單例模式中的getInstance()均有靜態工廠模式的痕跡。首先是不太認可書中所說的好處,於是上網尋找資料。總結如下:

一、什么是靜態工廠方法

  其又叫簡單工廠模式,與工廠模式不同,其是通過專門定義一個類來負責創建其他類的實例,其實例通常擁有共同父類,其普遍實現主要依靠Java的反射機制。

二、好處怎么體現

  Effective Java中共提到好處四點:

  1、它們有名稱

  2、它們可以返回原返回類型任意子類型的對象。

  針對於第一點,相比較於與類名相同的構造函數,靜態工廠方法是通過靜態方法進行對象的初始化,其方法名字自然可以自定義,從而幫助開發人員的理解,這是容易理解的。例如,重載而來的構造函數,很難在不看源碼的情況下知道他們的區別。

  第二點,其在Java中的集合類Collections用的頗多,主要利用Java的多態的特性,使得工廠可以產生基類的同時注入子類實現。

  如:

1 public interface Food {
2 
3     /**
4      * 使得所有食物都有一個共有的introduce方法
5      */
6     public void introduce();
7 }
 1 /**
 2  * 定義食物的子類:魚
 3  */
 4 public class Fish implements Food{
 5 
 6     @Override
 7     public void introduce() {
 8         System.out.println("i am a fish");
 9     }
10 }
1 /**
2  * 食物的子類,水果
3  */
4 public class Fruit implements Food {
5     @Override
6     public void introduce() {
7         System.out.println("i am the fruit");
8     }
9 }
 1 /**
 2  * 通過反射機制實現的工廠
 3  */
 4 public class FoodFactory {
 5 
 6     public static Food getFood(String type) {
 7         Food food = null;
 8         try {
 9             food = (Food) Class.forName("info.zhw." + type).newInstance();
10         } catch (ClassNotFoundException e) {
11             e.printStackTrace();
12         } catch (InstantiationException e) {
13             e.printStackTrace();
14         } catch (IllegalAccessException e) {
15             e.printStackTrace();
16         }
17         return food;
18     }
19 }

  FoodFactory就利用了基類,返回了該類型的子類型。

 

  3、不必在每次調用他們的時候都創建一次對象。

  使用構造函數,調用其中的方法,則實例化一個類是必不可少的步奏,而是使用靜態工廠方法,則可以對對象進行重復利用,這個特點在單例模式中使用頗多。

public class SingletonClass{
    private static SingletonClass instance=null;
    public static SingletonClass getInstance()
    {
        if(instance==null)
        {
            synchronized(SingletonClass.class)
            {
                if(instance==null)
                    instance=new SingletonClass();
            }
        }
        return instance;
    }
    private SingletonClass(){
    }
}

其將構造方法私有,只能通過getInstance()獲取實例,從而達到實例重復利用的目的。

  

  4、使代碼簡潔

  與第一點有點雷同,主要也是在方便理解的基礎上作出的改進。

 

三、缺點從何體現

  1、如果類不含有公有或受保護構造器,就不能被子類化。

  2、和靜態方法實際上沒有任何區別。其無法在API文檔中明確標出,推薦使用管用名稱管理。

  以上是Effective Java中提到的缺點,不疼不癢的樣子,也許是我理解不深入的緣故。

  3、網上摘錄的一段(http://blog.163.com/zhuowh2006@126/blog/static/10182372420133220511247/)

  由於工廠類集中了所有實例的創建邏輯,這就直接導致一旦這個工廠出了問題,所有的客戶端都會受到牽連;而且由於簡單工廠模式的產品室基於一個共同的抽象類或者接口,這樣一來,但產品的種類增加的時候,即有不同的產品接口或者抽象類的時候,工廠類就需要判斷何時創建何種種類的產品,這就和創建何種種類產品的產品相互混淆在了一起,違背了單一職責,導致系統喪失靈活性和可維護性。而且更重要的是,簡單工廠模式違背了“開放封閉原則”,就是違背了“系統對擴展開放,對修改關閉”的原則,因為當我新增加一個產品的時候必須修改工廠類,相應的工廠類就需要重新編譯一遍。

 

四、總結

  廢話一句,需要根據實際情況選擇合適的解決方案,實現時多了一種考慮,在使用構造器之前,考慮下靜態工廠方法吧。


免責聲明!

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



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