在面向?qū)ο缶幊讨校魏未a都圍繞著類和對象宏赘;一個類在使用之前必須要實例化一個對象呻疹,然后對這個對象進(jìn)行操作;正如我在“對象導(dǎo)論”中所說的佛析,類是組成問題空間的基本單位,若干個類將問題空間抽象出來彪蓬,而對象便是類在解空間中的投影寸莫;因為類是抽象的,所以類沒有任何具象的意義寞焙,只有在解空間中储狭,給對象賦值之后,這個對象被數(shù)據(jù)具象化成一個有數(shù)據(jù)意義的實體捣郊,并且問題空間中的類的對象聚合之后才能形成具體的辽狈,能表達(dá)實體意義的解空間;在java中呛牲,生成對象的方法很多刮萌,相應(yīng)的,生成了對象就必須適時的銷毀對象娘扩,因為存儲空間總是有限的着茸,我們不可能放任對象無止境的去占用我們的存儲空間,這對軟件以及硬件都不是一個好消息琐旁;
每一個類都需要有構(gòu)造方法來構(gòu)造一個對象涮阔,當(dāng)沒有編寫具體的構(gòu)造方法時,java會自動給出一個無參的構(gòu)造函數(shù)public Object(); ?這個構(gòu)造方法會返回一個所有屬性都為默認(rèn)值的對象灰殴;所以有必要自己編寫構(gòu)造函數(shù)來更加高效的生成對象敬特;
1.使用靜態(tài)工廠來替代構(gòu)造器
典型例子:
這是Boolean類中的一個靜態(tài)方法,他通過入?yún)順?gòu)造一個Boolean類牺陶;
使用靜態(tài)方法來構(gòu)造對象不會在每次調(diào)用他們的時候都創(chuàng)建一個新的對象伟阔,這使得不可變類可以使用預(yù)先構(gòu)造好的實例或者將構(gòu)建好的實例緩存起來,而不是反復(fù)的去構(gòu)建一模一樣的實例然后再銷毀掰伸;靜態(tài)構(gòu)造方法從來不創(chuàng)建對象皱炉,如果程序經(jīng)常請求創(chuàng)建一模一樣的對象,使用靜態(tài)構(gòu)造方法將大大提升性能狮鸭;
靜態(tài)構(gòu)造方法有確切的名字合搅,這使得客戶端開發(fā)者在調(diào)用時可以很明確的知道他將要調(diào)用的方法會生成一個什么樣的結(jié)果多搀;
同時,靜態(tài)構(gòu)造方法可以返回原返回類型的任何子類灾部,這使程序有更大的靈活性酗昼;
靜態(tài)工廠的第四個優(yōu)勢在于,所返回的對象的類可以對著每次調(diào)用而發(fā)生變化梳猪,這取決于靜態(tài)方法的入?yún)⒙橄鳎晃覀冇袝r候會根據(jù)參數(shù)的不同來構(gòu)造不同的對象,這時候靜態(tài)構(gòu)造方法可以靈活的幫助我們自動構(gòu)造我們需要的對象春弥;
第五點(diǎn)呛哟,方法返回的對象所屬的類,在編寫包含該靜態(tài)方法的類時可以不存在匿沛;這使得代碼可擴(kuò)展性很高扫责,客戶端程序猿可以很方便的去擴(kuò)展服務(wù)端提供的框架;這就是 服務(wù)提供者框架 在這個框架中逃呼,服務(wù)提供者編寫若干個api鳖孤,而開發(fā)者可以通過不斷去編寫新的類去是現(xiàn)在這個api,從而不斷的擴(kuò)充這個api的功能抡笼;
靜態(tài)方法的缺點(diǎn)主要在于苏揣,如果這個類沒有共有或者受保護(hù)的構(gòu)造起,則不能被實例化推姻;還有一點(diǎn)平匈,開發(fā)者很難去發(fā)現(xiàn)這些靜態(tài)構(gòu)造方法;
常見的構(gòu)造方法命名:
from:類型轉(zhuǎn)換藏古;
Of:聚合增炭;
valueOf:將入?yún)⑥D(zhuǎn)換為該類;
instance/getInstance:返回的實例是通過方法的參數(shù)來描述的拧晕,如果可以的話隙姿;
getType:蕾絲getInstance,type表示工廠方法所返回的對象類型厂捞;
create/newInstance:類似于getInstance输玷,但是這兩個關(guān)鍵詞表示的方法一般都會確保每次調(diào)用都返回一個新的實例;
2.當(dāng)構(gòu)造器參數(shù)較多時蔫敲,使用構(gòu)建器
靜態(tài)工廠和構(gòu)造器都有個共同的缺點(diǎn)饲嗽,無法很好的多個可選參數(shù)進(jìn)行擴(kuò)展炭玫;
首先奈嘿,重疊構(gòu)造器:
開發(fā)者在實例化對象時,可以對具體的需求選擇需要的構(gòu)造器吞加;
在編寫類時我們并不知道今后在構(gòu)造實例時到底需要多少個屬性裙犹,所以多寫幾個構(gòu)造器總是好的尽狠,調(diào)用不同的構(gòu)造器會生成不同的類;
當(dāng)你想要構(gòu)造實例的時候叶圃,就調(diào)用對應(yīng)你想要的構(gòu)造器就可以了袄膏;
但是這么寫的話,當(dāng)參數(shù)很多很多的時候掺冠,客戶端的代碼就會很麻煩沉馆,一大串而且難以閱讀;其實java本身已經(jīng)幫助我們解決了這個問題(javaBean方法)德崭,大不了就new一個無參的實例斥黑,然后一個一個調(diào)用set方法弄進(jìn)去;但是這個方法并不是線程安全的眉厨,也就是說javaBean在構(gòu)造過程中可能處于不一致的狀態(tài)锌奴,這使得無法構(gòu)造不可變類,除非開發(fā)者自己保證線程安全憾股;
當(dāng)然了鹿蜀,還有更好的方法 建造者模式(builder):
話不多說先上代碼
建造者模式模擬了具名的可選參數(shù),這使得客戶端開發(fā)代碼十分易于閱讀服球;
而且茴恰,建造者模式也適用于類層次結(jié)構(gòu),類似于抽象工廠中的概念斩熊;