摘要:基于模式的程序設計教學方法是有益的嘗試。本文分析客觀存在于程序設計教學中的模式,并以算法實現(xiàn)級模式、程序構(gòu)建級模式為例,探討模式在程序設計教學中的應用,從思維工具、知識關聯(lián)、教學效用三個方面總結(jié)這種教學新思維對于提高教學效率的作用。
關鍵詞:程序設計;模式;算法實現(xiàn)級模式;程序構(gòu)建級模式
程序設計是思維的藝術,而思維是沒有定式的。對于程序設計的初學者來說,他們顯然對這種無定式的思維呈現(xiàn)出不同程度的不適應。尤其是程序設計的初學者,他們的知識結(jié)構(gòu)、能力構(gòu)成、學習興趣等客觀因素都限制了程序設計課程教學的效果。同樣一個循環(huán)累加求和問題,既可用while、do/while來實現(xiàn),也可以用for循環(huán)來求解,而后者的應用形式更是千姿百態(tài)。因此,學生不能準確把握問題的本質(zhì),也不能集中精力于一種思路并加以熟練應用,無法迅速建立起一個成功的普適性經(jīng)驗以應對類似問題。
從人工智能中知識表達的觀點來看,學生還沒有用程序語言建立起關于某類問題解法的知識框架。這些知識框架對程序設計初學者顯得尤為重要,有了框架,就有了依靠,簡單修改現(xiàn)有知識框架,就能夠把它們應用到具體問題,并得到滿意解答,從而逐漸積累必要的自信心和成就感,這對于保持學生積極學習的興趣具有重要的意義。從數(shù)學教學來看,人們有這樣的共識,即只要對數(shù)學公式理解得好、應用得好,沒有什么難題解決不了。
上述問題對于程序設計教學具有啟示意義,即從特定類型問題中抽象出一些普適的“公式”,或者確立一些實用的框架,讓學生利用這些“公式”和框架來解決程序設計問題。這就是客觀存在于程序設計中的模式(Pattern)。
從具體問題中得來的模式反過來又能夠促進具體問題的解決,指導人們正確把握事物的本質(zhì)規(guī)律,并在實踐中正確應用規(guī)律。在模式的基礎上,人們反復修改以往的認識,積累正確的經(jīng)驗,堅定他們對正確模式的自信心,并逐漸形成對于特定問題的解決方案,從而成為領域中的行家里手。因此,好的模式有助于人們對成功經(jīng)驗的復用。而對程序設計初學者來說,其重要意義則在于:有了模式這樣一種助步器,他們能夠更快地學會走路、走得更穩(wěn),即使是新手也能夠較快寫出漂亮的程序。
本文針對計算機程序設計類課程教學中存在的問題,以C/C++程序設計、面向?qū)ο蟪绦蛟O計為對象,探討以模式為主要工具和手段,改革程序設計類課程教學方法和方式,構(gòu)建程序設計類課程教學的新思維。
1程序設計教學中的模式
程序設計領域中關于模式的研究由來已久,且成果豐富[1]。本文并沒打算象GOF著作那樣討論23種經(jīng)典設計模式的應用,而只是從教學的角度為學生建立簡單易行的程序設計模式。這些在程序設計教學中總結(jié)、抽象出來的模式可能不具備GOF模式般的高度抽象和精煉,但是它對課程教學具有良好的效果。
基于模式的程序設計教學是基于新的教育學思想的一種重要嘗試[2],教師與學生需要用一種新的思維方式探討程序設計這門課程,其橋梁就是模式。多年來,在教授C/C++程序設計、面向?qū)ο蟪绦蛟O計等課程中,我們體會到引入基于模式的程序設計教學方法,對于培養(yǎng)初學者的抽象、設計能力具有非常重要的作用,這是值得嘗試的新教學思維。
本文探討的模式主要針對計算機程序設計類課程,如C/C++程序設計、面向?qū)ο蟪绦蛟O計、算法與數(shù)據(jù)結(jié)構(gòu)等。根據(jù)不同課程對于程序設計能力培養(yǎng)的目標,作者在教學中構(gòu)建了許多不同層級的模式,其涵蓋范圍、抽象程度和應用場合各不相同,典型者有如算法實現(xiàn)級模式、程序構(gòu)建級模式。算法實現(xiàn)級模式側(cè)重于函數(shù)功能和算法過程的實現(xiàn),主要是對動作序列的描述。程序構(gòu)建級模式側(cè)重于程序的功能結(jié)構(gòu)和組織方式。
本文對模式的構(gòu)成要素作了適當定制,以簡明易用的原則來設計其構(gòu)成,學生自行設計的模式也大致遵守這些構(gòu)成要素以相互交流。對不同模式的描述各不相同,但都包括模式名稱和模式概要兩個基本要素。
2典型模式及其在教學中的應用
下面以順序遍歷模式和類職責模式分別作為算法實現(xiàn)級模式和程序構(gòu)建級模式的典型代表,說明模式的構(gòu)成及其在程序設計教學中的應用。
2.1順序遍歷模式
順序遍歷模式是一個應用較為廣泛的算法實現(xiàn)級模式,其構(gòu)成如圖1所示。這類算法在遍歷數(shù)據(jù)序列中每個元素的同時,對數(shù)據(jù)元素施行某個操作。
模式名稱:順序遍歷模式(Sequential Traverse Pattern, STP)
問題特征:遍歷數(shù)據(jù)序列,同時對每個元素施行某個操作
模式概要:對于數(shù)據(jù)序列E,①確定起始元素start;②判斷是否到達終止元素end;③對數(shù)據(jù)元素應用操作模式op;④應用遍歷模式T獲得下一元素;⑤重復步驟②。
偽代碼描述:e表示序列中某位置上的元素
E e(start);
while (e != end) {
op(e);
T(e);
}
圖1順序遍歷模式STP的構(gòu)成
在學生掌握上述模式后,應用模式求解問題的步驟為:(1)理解待求解問題的需求;(2)根據(jù)問題特征匹配模式;(3)分析并確定算法中的各個要素,如上述start、end、op、T;(4)按照偽代碼組織程序。
應用STP可以解決的問題有如對數(shù)據(jù)累加求和、逆序輸出數(shù)據(jù)元素、求序列中元素的個數(shù)、求序列中最大或最小的元素、求序列中重復的元素、統(tǒng)計某個元素出現(xiàn)的次數(shù)、復制數(shù)據(jù)序列,等等,只需設置不同的操作模式op和遍歷模式T即可。
以“從1到n累加求和”為例,參照STP,學生能夠確定:數(shù)據(jù)序列起始元素為1,終止元素為100,遍歷序列元素的模式T為++,對元素操作的模式op為+=,改成具體的語句為sum+=e,即對每個元素e,都把它累加到變量sum中。
同樣典型的應用還有基于數(shù)組的線性查找算法,其代碼如下所示,數(shù)據(jù)元素的起始位置和終止位置分別是start和end,其操作模式op是==,即對序列中的每個元素進行比較,遍歷模式T則是++,從當前位置遞增訪問到下一個位置。
template
T* find(T* start, T* end, const T key)
{
while (start < end) {
if (*start == key)break;
++start;
}
return start;
}
此外,通過設置遍歷模式T使得STP能夠適用于數(shù)組、鏈表、甚至二叉樹和圖等各種存儲方式的數(shù)據(jù)結(jié)構(gòu)。上述數(shù)組應用中是通過++模式(對元素位置start實施++操作)訪問每個元素。若存儲結(jié)構(gòu)為鏈表,則通過結(jié)點指針p和結(jié)點的指針域link,把遍歷模式設置成p=p->link,如下所示即為應用STP計算鏈表長度的代碼。而對于二叉樹,其遍歷模式T可以設置成前序Tpreorder、中序Tinorder、后序Tpostorder和層次序Tlevel等方式,對于圖可以設置成深度優(yōu)先Tdfs和廣度優(yōu)先Tbfs等方式。
template
int Length(ListNode
{
ListNode
int size = 0;
while (p != NULL) {
size++;
p = p->link;
}
return size;
}
從對STP的分析和應用可知,一個適度抽象且組織良好的模式具有應用的無限可能性,它能夠讓學生抓住同類問題的本質(zhì)并持續(xù)受益。更重要的是,現(xiàn)在面對問題,學生能夠快速組織一段程序求解該問題,而不是面對散亂的程序語句無所適從。
2.2類職責模式
設計一個類時,需要規(guī)劃它的職責和功能,例如需要提供構(gòu)造函數(shù)、析構(gòu)函數(shù)、Get/Set函數(shù)、復制構(gòu)造函數(shù)、賦值運算符函數(shù)、標準流插入/提取運算符函數(shù),等等。類的這些職責都有著比較共性的實現(xiàn)方式,它們又可以實現(xiàn)為一個個算法級模式,把這些算法級模式組合起來,可以實現(xiàn)類職責模式,其模式結(jié)構(gòu)如圖2所示。
模式名稱:類職責模式(Class’ Responsibilities Pattern, CRP)
問題特征:規(guī)劃并定義一個類需要提供的功能及承擔的職責
模式概要:
class MyClass {
private:
數(shù)據(jù)成員
public:
構(gòu)造模式
析構(gòu)模式
Get模式
Set模式
復制構(gòu)造模式
賦值運算模式
流插入運算模式
流提取運算模式
};
圖2類職責模式CRP的構(gòu)成
應用CRP實現(xiàn)不同的類功能,關鍵在于各算法級模式的實現(xiàn),構(gòu)成不同類的各子模式實現(xiàn)可謂豐富多彩。例如,構(gòu)造模式的實現(xiàn)可以歸結(jié)為三類變量的三種操作:普通變量只需直接復制/賦值;數(shù)組型變量需用通過循環(huán)逐個復制/賦值(字符數(shù)組則直接用字符處理庫函數(shù)復制/賦值);指針變量則需要首先動態(tài)申請和釋放內(nèi)存資源,然后復制/賦值。因此,構(gòu)造模式可以分為三種算法級模式而分別實現(xiàn)。更值得一提的是,前/后增量運算模式可以用近似公式化的形式描述,尤其是后增量運算模式,幾乎可以不加修改的移植到任何類中,只要前增量運算已經(jīng)正確定義了。如下所示是前/后增量運算模式的偽代碼描述,其中T表示自定義數(shù)據(jù)類型,Inc是對該類的數(shù)據(jù)成員執(zhí)行增量的操作模式。
T operator ++ () {
Inc(dataMember);
return *this;
}
T operator ++ (int) {
T t(*this);
++(*this);
return t;
}
2.3綜合應用
學習“數(shù)據(jù)結(jié)構(gòu)”課程通常需要應用不同的存儲結(jié)構(gòu)來解決實際問題。以模擬電梯運行的應用程序設計為例,某學生在對該問題分析之后,需要定義棧Stack來模擬電梯Elevator,定義隊列Queue來容納對電梯上行/下行的請求Request,同時還需定義其他數(shù)據(jù)類型。因此,他首先基于范型思想設計Stack類和Queue類;接下來定義建筑物類Building,來控制程序的運行,該類中需要用到電梯類Elevator的對象以及請求類Request的對象作為數(shù)據(jù)成員,通常Elevator類和Request類與Building類之間是復合關系;最后在main函數(shù)中驅(qū)動模擬電梯運行過程。在整個過程中,該學生按照基于對象設計結(jié)構(gòu)模式組織程序項目,應用類職責模式來設計類及其功能,并應用算法實現(xiàn)級模式實現(xiàn)類中各成員函數(shù)的功能。
因此,對于這一類有著固定應用模式問題的解決,也可以固化為一種模式,如應用框架級模式,其結(jié)構(gòu)如圖3所示。該模式能夠幫助學生在深入考慮問題實現(xiàn)的具體細節(jié)之前,很快搭起整個應用程序的框架。
模式名稱:應用框架級模式
模式概要:
①設計基于范型思想的容器和算法;
②構(gòu)建面向問題的應用程序類;
③實現(xiàn)程序之間的驅(qū)動和關聯(lián)。
圖3應用框架級模式的構(gòu)成
3模式在程序設計教學中的重要意義
基于模式的程序設計教學方法的新穎之處體現(xiàn)在思維工具的層級、多種知識的關聯(lián)、教學效用的增強三個方面。
3.1提升學生賴以思考和表達的語言工具的層級
傳統(tǒng)的計算機程序設計教學一直沒能擺脫“熟于語法,疏于應用”的尷尬,學生能夠就具體的語法點進行熟稔的分析和解釋,但是在面臨實際問題時,不能搭建關于解決方案的“積木”。造成這種“只見樹木,不見森林”困境的原因之一,在于傳統(tǒng)教學方式以程序語言的語句為教學單元,重視其語法構(gòu)建和語義解釋,而忽視了在具體語境中整體功用的表達,從而使得學生不能針對具體應用而快速組合有效代碼[3]。
基于模式的程序設計教學方法革新了學生思維表達的語言工具,這個語言工具不再是分散而單純的語句,而是提升、凝煉為一組擁有明確界限和功能定義的代碼集合,即模式。這種教學新思維在明確的語境中強化了對基本概念、語法、結(jié)構(gòu)的理解和應用。
3.2融合算法設計和實現(xiàn)的思想、軟件工程思想
模式的抽象和構(gòu)建通常是針對一些具有良好結(jié)構(gòu)、定義比較規(guī)范的問題,這些問題的解法也有著較為規(guī)范的結(jié)構(gòu),這就為定義準確、精煉的算法提供了有利條件。這些已經(jīng)初步抽象、具有良好模型的實際問題,為訓練學生的算法設計和實現(xiàn)能力提供了極佳的鍛煉環(huán)境,因此,構(gòu)建模式的過程,就是鍛煉學生的算法設計和實現(xiàn)能力的重要過程。
模式在教學中的應用體現(xiàn)了多種知識的相互關聯(lián),第一,體現(xiàn)了軟件工程中代碼重用的思想。面對本質(zhì)相同的問題,學生只要參考模式的偽代碼,就能夠快速給出有著較高質(zhì)量的實現(xiàn)代碼。第二,體現(xiàn)了軟件工程中抽象和建模的方法。模式是對現(xiàn)實世界建模和抽象的有力工具。一個定義良好的模式,有著適當程度的抽象、能夠刻畫本質(zhì)的模型,就能夠在解決各種問題時煥發(fā)出蓬勃的生機,得到各種意想不到的應用效果。
3.3提供分析、設計、實現(xiàn)的一體化解決方案
模式的應用提供了從問題空間到解空間的快速映射。針對特定問題的模式刻畫了該類問題的本質(zhì),一旦待解決的問題匹配上某種模式,該模式就能夠為學生提供從問題分析、算法設計到編碼實現(xiàn)的全過程解決方案。因此,學生只要進行正確的模式特征匹配、實現(xiàn)要素分析等前提工作,就能夠快速的獲得對問題的解決方案。
這種有指導的自主學習活動帶給學生的是一種全新的體驗和感受,這種教學方式不僅把具體問題作為案例,還給出具體案例的標準化解法,程序設計的學習不再是構(gòu)建基本單元,而是搭配已具規(guī)模的各種組件。在這種學習活動中,學生會感覺非常愉快,老師則不會產(chǎn)生挫折感,程序設計教與學的效率都會得到提高。
4結(jié)語
傳統(tǒng)程序設計教學中教師和學生交流的平臺是晦澀難懂的程序語言,而應用模式的教學方法將溝通平臺變成更易理解和應用的模式。通過改革程序設計課程教學的思維和方式,引入并嘗試基于模式的教學方法,我們構(gòu)建新穎而有效的程序設計課程教學理念。在多年的教學中,作者設計、構(gòu)建了不同層級的模式,這些模式既輔助了教師的講授,把抽象、無定式的思維形式化、實物化,又幫助學生迅速建立起可以依賴的程序設計經(jīng)驗。
在軟件工程的方面,模式的引入有利于代碼的重用,它能夠幫助初學者組織性能較高的程序,這種成功的體驗能夠幫助他們積累程序設計的自信心,對于培養(yǎng)學生的抽象能力、建模能力、設計能力甚至表達能力都有著不可估量的重要作用,與此同時,它也進一步促進了師生的積極互動,并使教學形成良性循環(huán)。
實踐證明,基于模式實施程序設計教學對于教與學效率的提高不無裨益,模式能夠把學生從最初無所適從的困境中解脫出來,只要準確分析問題,正確選用模式,活學活用并逐漸積累足夠多的模式,學生的學習興趣就會逐漸高漲,設計和分析能力日益扎實。
參考文獻:
[1]Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides.Design Patterns:Elements of Object-oriented Software[M].
Boston:Addison-wesley,1995.
[2]Eugene Wallingford.Toward a First Course Based on Object-oriented Pattern[J].ACM SIGCSE Bulletin,1996,28(1): 27-31.
[3] 劉建華.計算機語言類課程教學模式初探[J].高教論壇,2005(2):91-93.
Applications of Patterns in Programming Teaching
ZHANG Jun, ZHANG Yan-duo
(School of Computer Science and Engineering, Wuhan Institute of Technology, Wuhan 430073, China)
Abstract: Pattern based programming teaching method is an advantageous experience for promoting programming teaching efficiency. This paper studies patterns actually existing in present programming teaching. Taking implement pattern of algorithm and constructive pattern of program as example, the paper investigates applications of patterns in programming teaching. Important roles of this new method in assisting teaching are summarized from tools as thinking, knowledge associativity and teaching efficiency.
Key words: programming; patterns; implement pattern of algorithm; constructive pattern of program
(編輯:郭小明)