JAVA設(shè)計(jì)范式一單子
發(fā)布時(shí)間:2008-08-06 閱讀數(shù): 次 來源:網(wǎng)樂原科技
1 單子
或許最簡單的設(shè)計(jì)范式就是“單子”(Singleton),它能提供對(duì)象的一個(gè)(而且只有一個(gè))實(shí)例。單子在Java庫中得到了應(yīng)用,但下面這個(gè)例子顯得更直接一些:
//: SingletonPattern.java
// The Singleton design pattern: you can
// never instantiate more than one.
package c16;
// Since this isn't inherited from a Cloneable
// base class and cloneability isn't added,
// making it final prevents cloneability from
// being added in any derived classes:
final class Singleton {
private static Singleton s = new Singleton(47);
private int i;
private Singleton(int x) { i = x; }
public static Singleton getHandle() {
return s;
}
public int getValue() { return i; }
public void setValue(int x) { i = x; }
}
public class SingletonPattern {
public static void main(String[] args) {
Singleton s = Singleton.getHandle();
System.out.println(s.getValue());
Singleton s2 = Singleton.getHandle();
s2.setValue(9);
System.out.println(s.getValue());
try {
// Can't do this: compile-time error.
// Singleton s3 = (Singleton)s2.clone();
} catch(Exception e) {}
}
} ///:~
創(chuàng)建單子的關(guān)鍵就是防止客戶程序員采用除由我們提供的之外的任何一種方式來創(chuàng)建一個(gè)對(duì)象。必須將所有構(gòu)建器都設(shè)為private(私有),而且至少要?jiǎng)?chuàng)建一個(gè)構(gòu)建器,以防止編譯器幫我們自動(dòng)同步一個(gè)默認(rèn)構(gòu)建器(它會(huì)自做聰明地創(chuàng)建成為“友好的”——friendly,而非private)。
此時(shí)應(yīng)決定如何創(chuàng)建自己的對(duì)象。在這兒,我們選擇了靜態(tài)創(chuàng)建的方式。但亦可選擇等候客戶程序員發(fā)出一個(gè)創(chuàng)建請(qǐng)求,然后根據(jù)他們的要求動(dòng)態(tài)創(chuàng)建。不管在哪種情況下,對(duì)象都應(yīng)該保存為“私有”屬性。我們通過公用方法提供訪問途徑。在這里,getHandle()會(huì)產(chǎn)生指向Singleton的一個(gè)句柄。剩下的接口(getValue()和setValue())屬于普通的類接口。
Java也允許通過克?。–lone)方式來創(chuàng)建一個(gè)對(duì)象。在這個(gè)例子中,將類設(shè)為final可禁止克隆的發(fā)生。由于Singleton是從Object直接繼承的,所以clone()方法會(huì)保持protected(受保護(hù))屬性,不能夠使用它(強(qiáng)行使用會(huì)造成編譯期錯(cuò)誤)。然而,假如我們是從一個(gè)類結(jié)構(gòu)中繼承,那個(gè)結(jié)構(gòu)已經(jīng)過載了clone()方法,使其具有public屬性,并實(shí)現(xiàn)了Cloneable,那么為了禁止克隆,需要過載clone(),并擲出一個(gè)CloneNotSupportedException(不支持克隆違例),就象第12章介紹的那樣。亦可過載clone(),并簡單地返回this。那樣做會(huì)造成一定的混淆,因?yàn)榭蛻舫绦騿T可能錯(cuò)誤地認(rèn)為對(duì)象尚未克隆,仍然操縱的是原來的那個(gè)。
注意我們并不限于只能創(chuàng)建一個(gè)對(duì)象。亦可利用該技術(shù)創(chuàng)建一個(gè)有限的對(duì)象池。但在那種情況下,可能需要解決池內(nèi)對(duì)象的共享問題。如果不幸真的遇到這個(gè)問題,可以自己設(shè)計(jì)一套方案,實(shí)現(xiàn)共享對(duì)象的登記與撤消登記。