Java---靜態(tài)工廠方法

Effective Java刷書筆記---靜態(tài)工廠方法

類實例獲取--“考慮”用靜態(tài)工廠方法代替構造器
對于一個類而言,為了讓調用者獲取它自身的一個實例,最常用的方法就是提供一個公有的構造器,比如:

    Fragment fragment = new MyFragment();
    Date date = new Date();
    byte[] buf = new byte[2048];
    File dir = new File(path);

而我們也要在日常開發(fā)中“考慮”靜態(tài)工廠方法,靜態(tài)工廠方法也是獲取這個類自身的一個實例,他的存在是為了更好的描述和處理這個類。比如:

    Calendar calendar = Calendar.getInstance();
    Boolean b=Boolean.valueOf(xxx);
  Calendar.java
    public static Calendar getInstance()
    {
      return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }
  Boolean.java
   public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

靜態(tài)工廠方法的優(yōu)勢:

1.靜態(tài)工廠方法有名字。

  • 構造函數(shù)的方式 需要名字和類名相同,當有多個重載,參數(shù)類型、返回值不同等多種情況下(比如Date函數(shù)重載),對于使用者來說可能閱讀要查閱每個參數(shù)的意義了才能不調用錯誤的構造器。
  • 靜態(tài)工廠方法可以使用不同的方法名字使得其構造的對象更加明晰。我們完全可以通過方法名明白構造了什么樣的對象,幫助客戶端能更好的準確的調用正確的實例。
  • 對于構造函數(shù)來說,只有參數(shù)有差異(類型、數(shù)量或者順序)才能夠重載
  • 靜態(tài)工廠方法允許我們有相同的參數(shù)類型,只要名字不同即可。
    即如果構造器的參數(shù)本身沒有確切的描述正被返回的對象,那么具有適當名稱的靜態(tài)工廠會更容易使用,代碼更容易閱讀。

2.不用每次被調用時都創(chuàng)建新對象。

這一點可能比較好理解,這樣做避免創(chuàng)建不必要的對象。
有時候外部調用者只需要拿到一個實例,而不關心是否是新的實例;又或者我們想對外提供一個單例時 ??梢杂渺o態(tài)工廠方式為重復的調用返回相同的對象。
然后順便重溫一下單例: Hi,我們再來聊一聊Java的單例吧

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

3.可以返回原返回類型的子類。

這一點符合設計模式中的基本的原則之一——『里氏替換』原則,就是說子類應該能替換父類。構造方法只能返回確切的自身類型,而靜態(tài)工廠方法則能夠更加靈活,可以根據(jù)需要方便地返回任何它的子類型的實例。
比如我們現(xiàn)在想根據(jù)消息類型返回不同的消息子類(比如文本消息、圖片消息、視頻消息等等)

 public static Message getMessage(TIMMessage message){
        switch (message.getElement(0).getType()){
            case Text:
            case Face:
                return new TextMessage(message);
            case Image:
                return new ImageMessage(message);
            case Sound:
                return new VoiceMessage(message);
            case Video:
                return new VideoMessage(message);
            case GroupTips:
                return new GroupTipMessage(message);
            case File:
                return new FileMessage(message);
            case Custom:
                return new CustomMessage(message);
            case UGC:
                return new UGCMessage(message);
            default:
                return null;
        }
    }

4.在創(chuàng)建帶泛型的實例時,能使代碼變得簡潔

這條主要是針對帶泛型類的繁瑣聲明而說的,構造器實例方式需要我們重復書寫兩次泛型參數(shù):
但如果我們通過靜態(tài)工廠方式,編譯器可以幫我們找到類型參數(shù)(類型推導),只寫一次泛型參數(shù)。


//常規(guī)實例化方式
Map<String, List<String>> m =
    new HashMap<String, List<String>>();

public static <K, V> HashMap<K, V> newInstance() {
    return new HashMap<K, V>();
}
//使用靜態(tài)工廠方法實例化,簡化繁瑣的聲明
Map<String, List<String>> m = HashMap.newInstance();

但是jdk1.7之后做了優(yōu)化,不用靜態(tài)方法也可以只寫一次類型參數(shù)了。

5.避免寫很多重復的代碼,集中管理,統(tǒng)一修改

這一點在業(yè)務中很常見,比如android開發(fā)中我們需要在MainActivity 中跳到DetailActivity中,最簡單我們會這樣寫

        String url="";
        Intent intent = new Intent(MainActivity.this,DetailActivity.class);
        intent.putExtra("url", url);
        context.startActivity(intent);

但當其他Activity 也要跳到DetailActivity中,我們還是會重復的寫這種代碼,以至于我們某天需要統(tǒng)一查看都哪些跳轉DetailActivity時我們需要全局搜索嗎??或者修改intent傳入?yún)?shù)時,也不方便查找。所以此時我們使用靜態(tài)工廠方式,在DetailActivity中加入這個一個方法:

      public static void jumpToDetail(Context context, String url){
        Intent intent = new Intent(context, DetailActivity.class);
        intent.putExtra("url", url);
        context.startActivity(intent);
    }

此時其他activity再調用時只需DetailActivity.jumpToDetail(context,url);即可,這樣做省去寫重復的代碼,也統(tǒng)一管理參數(shù),便于查看調用者。

靜態(tài)工廠方法的劣勢
  • 類如果不含公有的或受保護的構造器,就不能被實例化。

如果我們在類中將構造函數(shù)設為private,只提供靜態(tài)工廠方法來構建對象,那么我們將不能通過繼承擴展該類。
但是這也會鼓勵我們使用復合而不是繼承來擴展類。

  • 一般構造器在API文檔會被明確標識出來,方便閱讀查看。而靜態(tài)工廠方法我們主要是靠命名規(guī)范來彌補這一劣勢。

實際上公有構造器和靜態(tài)工廠各有用處,我們需要理解各自的長處,選擇合適的方式提供實例,要“考慮”靜態(tài)工廠,而不是第一反應就是提供公有的構造器,根本不考慮靜態(tài)工廠。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容