王金娟 彭浩
摘 要: 針對C++語言程序設計課程教學出現(xiàn)的問題,提出引入部分設計模式的思想講解面向對象的編程思想,給出在教學過程中講解抽象類與純虛函數(shù)概念引入狀態(tài)模式的案例。從教學實踐效果來看,這種教學方法提高了學生的學習積極性,提高了學生的實際編程能力和計算機思維能力。
關鍵詞: C++語言; 設計模式; 狀態(tài)模式; 面向對象
中圖分類號:G642 文獻標志碼:A 文章編號:1006-8228(2016)10-90-03
Application of state pattern in C++ language teaching
Wang Jinjuan, Peng Hao
(Hunan International Economics University, Changsha, Hunan 410205, China)
Abstract: According to the present problem of the C++ language course teaching, this paper puts forward an argument of introducing some ideas of design pattern to explain the programming thought of object-oriented, and gives an example case that the state pattern is introduced to explain the concepts of abstract class and pure virtual function in the teaching process. From the practical teaching effect, the teaching method has increased the students' learning enthusiasm, and improved the students' practical programming ability and computer thinking.
Key words: C++ language; design pattern; state pattern; object-oriented
0 引言
C++語言程序設計是大部分計算機學科的專業(yè)基礎課,它同時也是學習面向對象編程思想的重要課程。它的先導課程C語言是一種純粹面向過程的語言,側重算法的設計、功能的實現(xiàn),強調(diào)函數(shù)之間調(diào)用。由于C++語言完全兼容C語言面向過程特性,所以它涵蓋了面向過程與面向對象兩部分內(nèi)容[1],相較于純粹的面向對象語言,比如Java語言注重分析抽取類、建立模型設計類之間的關系,設計各個類的成員變量、成員函數(shù),通過類與類之間的相互協(xié)調(diào)完成任務,這與面向過程的思想大為不同。
在教學中發(fā)現(xiàn),大多數(shù)學生更習慣于用面向過程的設計思路,首先設計函數(shù)功能及相關算法,再把所有的函數(shù)放在一個類中,這些函數(shù)都是靜態(tài)的,雖然有一個類,但并沒有類的設計,也沒有體現(xiàn)面向對象的設計思想[2]。仔細分析發(fā)現(xiàn),由面向過程的編程轉為面向對象的編程,存在計算思維上的轉換和跳躍,這種跳躍無論對于學生還是教師都需要認真思索。面向對象編程思想更加抽象,理解起來更困難,而面向對象編程思想中又包含了面向過程的基本編程模式,如成員函數(shù)的定義、成員屬性的定義,這會使學生感覺面向對象編程就是把變量放在類里面,就是多了一個類的框架而已。在介紹封裝、繼承、多態(tài)這三個面向對象編程最重要的三大知識點時,教材上的實例顯得簡單,無法加深對于類和對象概念的深入理解,最終導致學生在糊里糊涂的狀態(tài)下采用C語言的代碼風格寫出了C++的類。
針對這樣的教學困境,我們嘗試將設計模式的部分思想如狀態(tài)模式,引入C++面向對象程序設計的教學中,設計模式是培養(yǎng)面向對象計算思維的一個良好途徑,是一套被反復使用、經(jīng)過分類編目的代碼設計經(jīng)驗的總結[3]。經(jīng)過幾學期的教學實踐表明,在C++面向對象程序設計的教學過程中引入部分設計模式相關內(nèi)容,能提高他們舉一反三的學習能力[4],非常有助于加深學生對面向對象程序設計思想的理解。
1 教學方案設計
軟件設計模式,經(jīng)過分類編目歸納為創(chuàng)建型、結構型和行為型共三大類23種模式,且還在不斷發(fā)展。它反應了面向對象設計思想在軟件設計過程中如何重復使用,并能以此構造出程序的良好結構,每個設計模式的說明有名稱、意圖、實用性、結構、效果、實現(xiàn)方法、代碼示例等[5],這些設計方法可以讓開發(fā)者深入了解面向對象思想的精華。
學習設計模式在C++教學過程中并不是教學核心,學生不需要學習和掌握全部設計模式,而是選擇適當?shù)哪J皆谶m當?shù)臅r候引入課堂教學,這需要遵循一定的教學方法。首先,將原先注重講解語法的教學模式,改變?yōu)榘咐寗有徒虒W模式。案例驅動模式,不再單一地講解一個知識點,而是改成提出一個主題,設計相關的類和功能,可以運用一些方法如設計模式中的一些適合這個主題的某一種模式,然后圍繞著這個模式討論可行的解決方法,此時可以介紹這種模式的基本思想,但是不用深入討論概念的描述,這對于初學者不太適合。其次,介紹區(qū)別于流程圖的UML類圖,畫圖是大多數(shù)學生比較感興趣的一項任務,引導學生把討論的方案用圖表達出來,在畫圖的過程中穿插講解類于類之間的關系,不理解的類或者關系應該多次討論再要求學生畫出來,盡量做到生動有趣,以幫助理解類和對象是動態(tài)的而非靜態(tài)的思想。最后,引導學生將前兩步的工作建立一個工程完成相應的代碼編寫,并讓學生自己做總結。教師對本次討論的主題進行講評。
2 狀態(tài)模式在教學中的案例運用
案例驅動型教學模式是這次教學改革的主要任務,教師在課堂上提出一個討論主題案例,講解基礎知識,學生回答問題并討論,在結合某種經(jīng)典設計模式講解,這樣不僅加深了學生對與繼承、多態(tài)、封裝、虛函數(shù)等概念的理解,也大大提高了學生自由思考,舉一反三的能力,對于編程的能力也上了一個新的臺階。
這里以講解面向對象中較難理解的抽象類和純虛函數(shù)的教學過程為例,本節(jié)教學目標是通過引入設計模式中的狀態(tài)模式讓學生了解抽象類的概念、純虛函數(shù)的用途。
⑴ 案例引入:某公司力排萬難終于獲得某個酒店的系統(tǒng)開發(fā)項目,最終交由你負責。圖1是系統(tǒng)的主要工作,每個框都代表了酒店房間當前狀態(tài),箭頭表示房間狀態(tài)的轉換。分析如下:房間有三個狀態(tài),即空閑、已預訂、已入?。粻顟B(tài)與狀態(tài)之間可以根據(jù)客戶的動作來進行轉換。
⑵ 提出問題:定義一個房間Room類,如何將房間的每個狀態(tài)整合起來?許多同學迅速反應,這個“最簡單”就是if…else if…else,先設置房間三個狀態(tài)的靜態(tài)變量:空閑狀態(tài)FREEMTIME_STATE=0、已預訂狀態(tài)BOOKED_STATE=1、已入住狀態(tài)CHECKIN_STATE=2,并給出四個動作對應的函數(shù):預訂、入住、退訂、退房。以下列出預訂函數(shù)的偽代碼,并如法炮制出了類似的其他三個功能函數(shù):
void Room::bookRoom() { /*預定*/
if(state==FREEMTIME_STATE) { //空閑可預訂
if(count>0) {
cout<<"房間空閑,完成預訂"< state=BOOKED_STATE; //改變房間狀態(tài):已預訂 count --; if(count==0) { cout<<"不好意思,房間已訂完,歡迎您的下次光臨!"< } } else { cout<<"不好意思,房間已訂完,歡迎您的下次光臨!"< } } else if(state==BOOKED_STATE) { cout<<"該房間已經(jīng)被預定了"< } else if(state==CHECKIN_STATE) { cout<<"該房間已經(jīng)有人住了"< } } ⑶ 狀態(tài)模式的引入:這個復雜的if…else if…else你是否滿意?這個不是C語言的代碼嗎?哪里體現(xiàn)了面向對象?如果客戶要求將某些房間保留下來以作為備用怎么辦?于是,悲劇就發(fā)生了,這就必須要在所有的操作里都要判斷該房間是否為備用房間,這對于代碼的改變量太大了,也體現(xiàn)出一開始的設計出現(xiàn)了嚴重了問題。這個時候需要換一個角度思考,以狀態(tài)為原子來改變它的行為,而不是通過行為來改變狀態(tài),這就是設計模式里的狀態(tài)模式。 狀態(tài)模式是允許對象在內(nèi)部狀態(tài)發(fā)生改變時改變它的行為,對象看起來好像修改了它的類。一個對象的行為取決于它的一個或多個變化的屬性,這些屬性我們稱之為狀態(tài),這個對象稱之為狀態(tài)對象。對于狀態(tài)對象,它的行為依賴于它的狀態(tài),比如現(xiàn)在這個案例中的預訂房間,只有當該房間為空閑時才能預訂,入住該房間的條件也只有預訂了該房間或者該房間為空閑時。對于這樣的一個對象,當它在與外部事件產(chǎn)生互動的時候,其內(nèi)部狀態(tài)就會發(fā)生改變,從而使得其行為也隨之發(fā)生改變,和學生一起設計類的UML如圖2。 ⑷ 抽象類和純虛函數(shù):如何完成這個工程,可以設計一個專門描述狀態(tài)的抽象類State,它包含了預訂房間bookRoom()、入住checkInRoom()、退房checkOutRoom()及取消預訂cancel()四個虛函數(shù);Room類里包含State類的三個對象空閑狀態(tài)State freeTimeState、入住狀態(tài)State checkInState、預訂狀態(tài)State bookedState;再具體實現(xiàn)三個空閑、預訂、入住狀態(tài)類,下面給出預訂狀態(tài)的部分偽代碼: class FreeTimeState:public State { Room hotelManagement; FreeTimeState(Room hotelManagement) { this.hotelManagement=hotelManagement; } void bookRoom() { cout<<"您已經(jīng)成功預定了!"< hotelManagement.setState(hotelManagement.getBookedState()); //狀態(tài)改為已預訂 } void checkInRoom() { cout<<"您已經(jīng)成功入住了!"< hotelManagement.setState(hotelManagement.getCheckInState()); //狀態(tài)改為已入住 } public void checkOutRoom() { } //為空,不需要實現(xiàn) } ⑸ 總結:明確抽象類和純虛函數(shù)的實際意義,與普通類于函數(shù)的區(qū)別在哪里。狀態(tài)模式可以讓多個環(huán)境對象共享一個狀態(tài)對象,從而減少系統(tǒng)中對象的個數(shù),特別適合代碼中包含大量與對象狀態(tài)有關的條件語句。這種方法讓多個環(huán)境對象共享一個狀態(tài)對象,從而減少系統(tǒng)中對象的個數(shù),極大提高了代碼編寫的質量。 3 結束語 在每一次的課程講授過程中,都努力引導學生結合已經(jīng)掌握的語法知識從多個角度進行面向對象的編程思維訓練。反復通過這樣的案例教學研究發(fā)現(xiàn),在C++語言程序設計課程中適當引人設計模式知識的教學模式,對于講解抽象的面向對象編程思想又很大幫助,它將設計模式知識與面向對象語法相結合,鍛煉了學生整合新舊知識的能力,鍛煉了他們的計算思維能力,逐步養(yǎng)成良好的編程規(guī)范。通過實踐證明,這種教學方式取得初步成功,也得到學生良好的評價,但是對于基礎薄弱,不能很好的連接新舊知識的學生,如何更好地設計案例,啟發(fā)他們的計算機思維能力,仍然需要繼續(xù)研究探索。 參考文獻(References): [1] 章品正,於文雪.設計模式在C++課程教學中的運用[J].計算 機教育,2014.14:41-45 [2] 楊瑞龍,朱征宇,朱慶生.引入軟件設計模式的面向對象程序 設計教學方法[J].計算機教育,2012.10:97-100 [3] Erich G,Richard H,Ralph 1,et al著.李英軍,馬曉星,蔡敏等 譯.設計模式:可復用面向對象軟件的基礎[M].機械工業(yè)出版社,2004. [4] 向華.如何在C++教學中引入初步的設計模式思想閉[J].長 江大學學報(自然科學版),2009.6(2):388-389 [5] 劉海巖,鎖志海,呂青等.設計模式及其在軟件設計中的應用 研究[J].西安交通大學學報,2005.39(10)1043-1047