摘要:?jiǎn)螒B(tài)設(shè)計(jì)模式在Java課程中很少涉及,本文講述了怎樣將此內(nèi)容巧妙地引入到課堂中去,并通過(guò)教學(xué)過(guò)程的合理設(shè)計(jì),使得學(xué)生不但能夠輕松掌握此內(nèi)容,還可以深入理解其它的相關(guān)內(nèi)容。
關(guān)鍵詞:?jiǎn)螒B(tài)設(shè)計(jì)模式;Java;教學(xué)
中圖分類(lèi)號(hào):G642文獻(xiàn)標(biāo)識(shí)碼:A
1引言
設(shè)計(jì)模式是在大量的實(shí)踐中總結(jié)和理論化之后優(yōu)選的代碼結(jié)構(gòu)、編程風(fēng)格以及解決問(wèn)題的思考方式。要成為一名優(yōu)秀的Java程序員,一般都需要掌握J(rèn)ava中的幾種設(shè)計(jì)模式,單態(tài)設(shè)計(jì)模式就是其中之一。但能否把此作為Java程序設(shè)計(jì)這門(mén)課的教學(xué)內(nèi)容的一部分,仍是一個(gè)值得商榷的問(wèn)題。因?yàn)樵诒姸鄬W(xué)者看來(lái),此內(nèi)容復(fù)雜而難懂,因此在目前的教材中,尚未發(fā)現(xiàn)涉及此內(nèi)容的。本文作者在教學(xué)中引入了單態(tài)設(shè)計(jì)模式的教學(xué)內(nèi)容,結(jié)果證明只要對(duì)此內(nèi)容的教學(xué)過(guò)程進(jìn)行合理設(shè)計(jì),學(xué)生不但可以掌握它,還可以深入理解掌握其它幾方面的知識(shí)。
2單態(tài)設(shè)計(jì)模式的含義及作用
所謂類(lèi)的單態(tài)設(shè)計(jì)模式,就是采取一定的方法保證在整個(gè)的軟件系統(tǒng)中,對(duì)某個(gè)類(lèi)只能存在一個(gè)對(duì)象實(shí)例,并且其它類(lèi)可以通過(guò)某種方法訪問(wèn)該實(shí)例。其主要作用是保證在Java應(yīng)用程序中,一個(gè)類(lèi)Class只有一個(gè)實(shí)例存在。生活中很多方面我們都要用到此設(shè)計(jì)模式,例如建立目錄、數(shù)據(jù)庫(kù)連接、資源管理器等。
3單態(tài)設(shè)計(jì)模式的教學(xué)過(guò)程設(shè)計(jì)
3.1單態(tài)設(shè)計(jì)模式的提出
在教學(xué)中我們沒(méi)有直接講解怎么設(shè)計(jì)單態(tài)程序,而是采取循序漸進(jìn)的方法,不但讓學(xué)生輕松掌握該知識(shí),還對(duì)Java面向?qū)ο蟮奶匦杂懈畹恼J(rèn)識(shí)。因此我們?cè)O(shè)計(jì)了如下的例1。
例1:
class Singleton
{
private int value; //注釋1
public Singleton() //注釋2
{
System.out.println(\"正在執(zhí)行構(gòu)造器....\");
}
//注釋3
public int getValue()
{
return value;
}
public void setValue(int value)
{
this.value = value;
}
}
class TestSingleton
{
public static void main(String args[])
{int v1,v2;
Singleton t1=new Singleton();
Singleton t2=new Singleton();
t1.setValue(3);
t2.setValue(5);
v1=t1.getValue();
v2=t2.getValue();
System.out.println(\"對(duì)象1的值為:\"+v1+\"\對(duì)象2的值為:\"+v2);
}
}
通過(guò)此例可以讓學(xué)生了解我們?cè)谠O(shè)計(jì)一個(gè)類(lèi)時(shí),往往把其成員屬性設(shè)置成private訪問(wèn)權(quán)限,使得其它類(lèi)不能直接訪問(wèn)該成員屬性,同時(shí)對(duì)外提供修改成員屬性的方法setXXX和讀取成員的方法getXXX,這些方法的訪問(wèn)權(quán)限是public的,可被所有其它類(lèi)訪問(wèn)。這樣做的目的是我們可以在修改成員的方法中加入更具體的更合理的控制邏輯,例如我們可以在修改人的年齡的方法setAge中限定只能將年齡設(shè)置為0到150之間的數(shù),否則不允許修改。
讓學(xué)生掌握以上知識(shí)后,教師可提出在上例中創(chuàng)建了類(lèi)Singleton的兩個(gè)實(shí)例,運(yùn)行結(jié)果如圖1所示。我們也可以創(chuàng)建更多該類(lèi)的實(shí)例,但某些情況下若只能產(chǎn)生某個(gè)類(lèi)的一個(gè)實(shí)例,那么能否做到呢?在提出該問(wèn)題后,可列舉生活中的例子,說(shuō)明思考此問(wèn)題的必要性,進(jìn)而提出單態(tài)設(shè)計(jì)模式的概念。接下來(lái)就引導(dǎo)學(xué)生對(duì)上面的程序進(jìn)行改進(jìn),來(lái)設(shè)計(jì)理解單態(tài)設(shè)計(jì)模式。
3.2單態(tài)設(shè)計(jì)模式的設(shè)計(jì)
產(chǎn)生某類(lèi)的實(shí)例時(shí)需要調(diào)用該類(lèi)的構(gòu)造方法,若該構(gòu)造方法可以被其他類(lèi)直接訪問(wèn),就不能限制在其他類(lèi)中只產(chǎn)生一個(gè)實(shí)例。因此,我們首先必須將類(lèi)的構(gòu)造方法的訪問(wèn)權(quán)限設(shè)置為private,這樣,此構(gòu)造方法就只能在本類(lèi)中使用來(lái)創(chuàng)建對(duì)象,而不能用new 操作符在類(lèi)的外部產(chǎn)生類(lèi)的對(duì)象了,但在類(lèi)內(nèi)部仍可以產(chǎn)生該類(lèi)的對(duì)象。因此,應(yīng)將例1中的注釋2所在的行修改為private Singleton();,同時(shí)在注釋1所在的行創(chuàng)建一個(gè)對(duì)象,即private static Singleton instance=new Singleton();。
經(jīng)過(guò)以上的改進(jìn),在類(lèi)的外部無(wú)法創(chuàng)建Singleton類(lèi)的對(duì)象,但也無(wú)法得到類(lèi)的對(duì)象。因此,我們需要在Singleton類(lèi)的內(nèi)部對(duì)外提供一個(gè)可以訪問(wèn)到對(duì)象的方法,并且該方法還必須是靜態(tài)的,因?yàn)檎{(diào)用該方法時(shí)外部類(lèi)中還沒(méi)有對(duì)象,只能通過(guò)類(lèi)名來(lái)訪問(wèn)。又因?yàn)殪o態(tài)方法不能直接訪問(wèn)類(lèi)中的非靜態(tài)成員變量,所以,該類(lèi)內(nèi)部產(chǎn)生的那個(gè)對(duì)象變量也必須定義成靜態(tài)的。由此,我們需要在例1中注釋3所在的位置加入下面的方法:
public static Singleton getInstance()
{
return instance;
}
3.3單態(tài)設(shè)計(jì)模式的測(cè)試
對(duì)例1經(jīng)過(guò)以上的改進(jìn)后,類(lèi)Singleton是否就只能產(chǎn)生一個(gè)實(shí)例呢?我們?cè)O(shè)計(jì)了如下的例2對(duì)其進(jìn)行測(cè)試。
例2:
class TestSingleton
{
public static void main(String args[])
{int v1,v2;
Singleton t1=Singleton.getInstance();
Singleton t2=Singleton.getInstance();
if(t1==t2) System.out.println(\"只能創(chuàng)建一個(gè)實(shí)例\"); //注釋4
t1.setValue(3);
t2.setValue(5);
v1=t1.getValue();
v2=t2.getValue();
System.out.println(\"對(duì)象1的值為:\"+v1+\"\對(duì)象2的值為:\"+v2); //注釋5
}
}
在此測(cè)試程序中,雖然聲明了兩個(gè)Singleton類(lèi)的對(duì)象名t1和t2,并通過(guò)類(lèi)Singleton的getInstance()方法得到了該類(lèi)的實(shí)例,但實(shí)際上無(wú)論在外部類(lèi)中調(diào)用幾次getInstance()方法,訪問(wèn)到的都是同一個(gè)對(duì)象。為了證明此結(jié)論,在測(cè)試程序例2中我們?cè)O(shè)計(jì)了兩個(gè)測(cè)試方法。第一個(gè)測(cè)試方法是在注釋4所在的行,我們對(duì)t1和t2進(jìn)行是否相等的比較,若相等則輸出“只能創(chuàng)建一個(gè)實(shí)例”這個(gè)字符串。大家都知道“==”運(yùn)算符比較的是兩個(gè)對(duì)象名的引用值是否相等,若相等說(shuō)明這兩個(gè)對(duì)象名指向的是同一個(gè)對(duì)象。第二個(gè)測(cè)試方法是在注釋5所在的行,分別輸出對(duì)象t1、t2的value成員的值。若二者相等并且都是5,則說(shuō)明t1和t2指向的是同一個(gè)對(duì)象,若v1的值為3,v2的值為5,則說(shuō)明t1和t2指向的是不同的實(shí)例對(duì)象。測(cè)試程序的運(yùn)行結(jié)果如圖2所示,驗(yàn)證了t1和t2是同一個(gè)對(duì)象,即對(duì)例1經(jīng)過(guò)改進(jìn)后的程序是一個(gè)單態(tài)程序,外部類(lèi)只能獲得Singleton類(lèi)的一個(gè)實(shí)例。
4結(jié)束語(yǔ)
筆者將上述設(shè)計(jì)過(guò)程應(yīng)用于兩屆學(xué)生,均取得了良好的效果。實(shí)踐證明,單態(tài)設(shè)計(jì)模式雖然難懂,但只要教師對(duì)其教學(xué)過(guò)程進(jìn)行合理設(shè)計(jì),學(xué)生不但能夠掌握該知識(shí),還可以從中加深對(duì)其他知識(shí)的理解。本文語(yǔ)言通俗,教學(xué)過(guò)程設(shè)計(jì)巧妙,可以為自學(xué)單態(tài)設(shè)計(jì)模式的學(xué)生提供良好的幫助,也可以為教師教學(xué)提供借鑒。
The Teaching Process Design of Singleton Design Pattern
WANG Shuang, ZHAO Hui-yang
(College of Computer Science and Technology, Xuchang University, Xuchang 461000, China)
Abstract: Singleton design pattern is very little involved in the Java cource. This paper tells us how to introduce it into classroom teaching ingeniously. And student can not only grasp this content easily but also understand other related contents deeply by teachers’ designing teaching process reasonably.
Keywords: Singleton Design Pattern, Java, teaching
參考文獻(xiàn):
[1] 耿祥義,張躍平. Java 2實(shí)用教程(第3版)[M]. 北京:清華大學(xué)出版社,2006.
[2] 朱喜福. Java程序設(shè)計(jì)(第2版)[M]. 北京:人民郵電出版社,2007.