陳榮鑫
(集美大學 計算機工程學院,福建 廈門 361021)
面向對象編程是目前高校計算機專業的一門重要學科基礎課程。面向對象設計思想在現代軟件開發實踐中非常重要,其指導作用體現在小至對程序功能的編程實現,大至項目開發層面的軟件工程,因此設計思想的培養成為面向對象編程教學中的一個關鍵點。傳統的面向對象編程的教學過程中,通常采用主流的面向對象編程語言,Java 或C++等作為授課載體。授課內容組織往往以介紹語言的語法及功能為主線,再加入面向對象的設計方法。教學的出發點基本上局限于對特定一門編程語言的介紹,而未能真正凸顯其中的設計思想[1]。由于在現有的教學課程體系中,面向對象課程往往不是首門編程課程,學生通常已經完成一門高級程序語言設計的系統學習,比如大多數學完了C 語言,具備了一些自學新語言的基礎,如果該門課的教學定位僅限于對另一門新的高級語言的學習,將難以體現課堂教學的必要性。少數經典教材[2]在內容闡述中注重強調設計思想,但包含的內容較為龐雜,因課時所限,教學中需要加以選擇。
在編程開發的相關課程體系中,面向對象編程課程發揮著承上啟下的關鍵作用,如圖1 所示,本門課的前導課程是低年級開設的C 語言程序設計,其面向過程的基本語法和模塊化編程方式為學習面向對象的高級語言提供了編程基礎,而數據結構課程則為解決實際問題提供了算法設計基礎。后續直接相關的課程有JavaEE 架構技術和Android 應用開發。由于.Net 應用開發采用面向對象的C#作為授課載體,因此與本門課有較強相關性。在后續的軟件工程課程中,面向對象的軟件工程方法是一個重要組成內容,而面向高年級開設的創新創業類課程是培養學生解決復雜工程問題的必修綜合實踐類課程,面向對象設計與編程技術在很多軟件開發類選題中不可或缺。畢業設計作為最后一個實踐環節,同樣有大量軟件類選題采用面向對象技術完成設計與開發。
在當前廣泛開展的工程教育認證中,如何培養學生解決復雜工程問題的能力是一個十分關鍵的議題[3]。面向對象的思想本質是要求盡可能按照人類認識世界的方法和思維方式分析和解決問題,而面向對象編程能夠培養學生面向對象的設計思想和軟件開發技能,因此可以成為培養學生解決復雜工程問題的一個重要途徑。本門課的教學除了向學生提供面向對象語言工具的編程技能訓練,還可以通過設計思想的系統訓練向學生提供更高層次的指導。

圖1 編程開發主要相關課程
教學內容組織綱要見表1。將面向對象編程的教學內容劃分為5 個模塊,同時對應3 種層級,其中基礎篇用于介紹Java 語言的基本語法,包括數據類型、數組、字符串、運算符、表達式和語句等內容。鑒于學生已經學過C語言程序設計,這部分內容與C 語言有很大交集,采用的是面向過程的設計方法,基本上簡要介紹就可以。學完這部分后,學生基本上就可以使用Java 進行面向過程的軟件開發。接下來講授的是面向對象篇,這部分是面向對象編程語言特有的內容,也是本課程的核心部分之一,該篇要引入面向對象設計的基本思想和設計方法。學完該篇后,學生基本上可以使用Java 進行面向對象的編程。功能篇展示了作為一門完整編程語言所能提供的解決常見實際問題的基本設施,這些功能包括異常處理、泛型、GUI 界面設計、數據庫操作、多線程編程等方面。有了前面面向對象的基礎和Java實現功能支持,接下來講授設計模式篇。該篇是面向對象設計思想的延伸和提升部分,也是本課程的另一個核心部分,其內容包括經典設計模式和其他擴展設計模式等。最后一篇是綜合應用,通過較為完整地解析一個應用案例,把語言工具和設計思想加以融合應用,該案例以重構的方式逐步完善,把學過的關鍵知識點串聯起來。

表1 教學內容組織綱要
考慮對設計思想系統化解析支撐度不夠顯著的教學內容壓縮課時,主要涉及一些利用編程語言實現軟件具體功能的內容部分,如界面開發、數據庫應用開發和多線程編程等,而一些對案例講解沒有直接支撐的獨立專題,則可根據實際情況作為選講內容,或作為附錄安排學生課后自學,如文件IO、網絡編程等部分。偏重設計思想層級的教學內容包括面向對象篇和設計模式篇。
面向對象技術能有效用于描述現實世界中各種對象及其相互之間的關系,包括抽象、封裝、繼承、多態等基本特征,因此,面向對象的程序中包含各種表示事物概念的類,表示具體事物的對象,表示消息操作規范的接口,體現不同抽象層次的繼承關系,體現不同操作方式和結果的多態現象等。這些面向對象編程技術的核心內容需要逐一解析清楚,同時要闡明各部分知識點之間的聯系。內容構建時需要精心編制案例以配合理論講解,案例的特點是簡明扼要,能反映基本設計思想,最好有一定的實際意義和趣味性。展示案例時應當在類、對象、方法等面向對象的基本元素的合理應用和組織上重點強調,而不能在算法和功能具體實現上著墨過多。在介紹綜合設計較復雜的內容時,為了直觀地展示設計意圖,引入UML 描述手段。在銜接和綜合這兩個關鍵環節中教學內容的組織如下。
(1)與面向過程編程方式的銜接。通過一個銀行賬戶處理的案例,演示把面向過程的實現方式改造為面向對象的實現方式的過程。應用場景中存在不同類型的銀行賬戶,要實現存取款、轉賬等業務。先用C 語言實現該案例,采用結構體描述賬戶信息,增加一個結構體成員描述賬戶類型以避免一個結構體僅對應一種賬戶;業務功能采用函數實現,但數據和函數無法獲得訪問保護;業務操作需要直接調用函數,邏輯上顯得凌亂。而用Java 語言實現時,采用類描述賬戶信息,把業務功能以方法形式封裝在類里;同時通過訪問權限設置提供了數據域和方法域的保護;不同類型賬戶則優雅地通過繼承方式表示;業務處理時通過對象的方法調用實現消息傳遞。由于學生剛要接觸面向對象編程,這個案例盡可能做到簡潔,但需完整可運行以便做對比。通過對比,學生對面向對象的特點有了初步認識,體會到面向對象設計的優勢。
(2)小綜合。小綜合是介紹完面向對象基本設施后的一次綜合應用講解,同時對面向對象設計思想進行階段總結。舉一個經典游戲“星際爭霸”的應用場景。場景中有常規的人族(Terran)和蟲族(Zerg),它們既有共同的技能也有各自獨特的技能;此外要求新增一種新種族(XRace),該族同時具備人族和蟲族的特殊技能。授課時展示設計和開發的思路,先根據需求定義各種概念,通過類和接口進行描述,理順各個概念之間的關系,然后寫出代碼框架,此框架中的類和接口描述都是描述體為空的情況,但之間的繼承或實現關系已經用Java 關鍵字寫好了。接下來在該代碼框架上補充功能方法,逐步完善功能的代碼實現。在測試場景時,通過對上轉型對象的操作來驗證多態效果,以功能規范的視角測試接口回調。講解過程中需要強調基本設計原則,比如面向抽象原則、單一責任原則等。
設計模式是人們在解決特定問題時總結出來的可復用的設計方案。軟件領域中,影響最為深遠堪稱經典的是由Erich Gamma 等人總結出的面向對象軟件開發的23 種設計模式[4]。此外,人們在各種軟件架構的開發過程中,也發展出很多實用框架級設計模式,這些模式在經典的23 種設計模式之外。現代軟件系統的開發離不開設計模式的有效應用,比如JavaEE 框架體系中就用到各種設計模式,Andriod 系統亦是如此。如果沒有設計模式的預備知識,對這些框架的理解和應用將難以深入。由于設計模式源于面向對象設計思想,然而又超越了面向對象語言的語法設施層面,這部分內容應當適當融入課程教學中[5],以豐富面向對象設計思想的內涵。鑒于設計模式內容龐雜而課時有限,有必要選擇較為常用的模式進行講解。這部分教學內容構建如下。
(1)經典設計模式。根據設計模式的目的,經典設計模式分為3 類,即主要用于創建對象的創建型模式,主要用于處理類或對象的組合的結構型模式,以及主要用于描述對類或對象的交互和職責分配的行為型模式。為了便于對比,從這3 類模式中,每類分別選取兩種常用模式進行講解。創建型選擇單例(Singleton)模式和工廠方法(Factory Method)模式。學生學完這類模式后,將體會到對象的生成不再局限于new 操作,還可以根據實際需求選擇更強大的生成方式。行為型選擇命令(Command)模式和觀察者(Observer)模式。命令模式展示了如何進行調用功能的封裝。觀察者模式是JDK 中高頻使用的模式,JDK已提供相應的類和接口可以快捷地實現該模式。命令模式對于新增命令很容易擴展;而觀察者模式則實現了主題和觀察者之間的解耦,二者均體現了開-閉設計原則的優勢。結構型選擇適配器(Adapter)模式和代理(Proxy)模式。適配器模式提供了一種轉換機制,使得接口不兼容的事物可以一起工作,提高了復用的可能性。代理模式能為其他對象提供一種代理以控制對這個對象的訪問,分布式計算架構中的RMI 和Corba 即采用了這種機制,應用場景十分廣泛。學完這類模式后,將體會到構建事物之間的關系不再局限于簡單的繼承和組合,還可以通過巧妙的設計去滿足特定的需求。選用于解析設計模式的實例應盡量有實際意義,讓學生理解設計模式在解決實際問題中的作用,體會到設計之美,進而在軟件開發實踐中考慮加以靈活應用。
(2)擴展設計模式。在當前很多面向對象軟件構建中非常流行的設計方案,然而又在經典23 種設計模式之外,我們稱之為擴展設計模式,如MVC(模型—視圖—控制器)、DAO(數據訪問對象)、DI(依賴注入)等模式。由于這些設計模式在企業級軟件框架如JavaEE 中應用廣泛,且能很好地展示面向對象的設計思想,有必要加以介紹。MVC 模式實現了業務邏輯、數據和界面顯示的解耦,為軟件系統分層可擴展提供了可能性。DAO 模式實現數據訪問邏輯與業務邏輯的分離,能簡化代碼量并提高程序的可移植性。DI 模式則提高了軟件組件的可復用性,便于搭建一個可靈活配置、易擴展的平臺。這些實用的擴展模式進一步充實了教學內容。
1)理論課教學方法。
在面向對象內容的教學中,強調面向對象設計思想在分析和設計過程中的作用,以實際例子和應用場景的引入,讓學生理解面向對象程序設計語言所提供的各種語法設施的必要性和優越性。比如隨著應用系統類別的增加,通過共性提煉引入了抽象類,并改造應用場景中的調用方式,以面向抽象的風格進行重構;而對于語言設施的關鍵技術細節需要解析到位,讓學生知其然同時也知其所以然。比如在對象初始化和清理的講解時,深入解析在復雜的繼承條件下,以及各種訪問權限下,靜態與非靜態對象的生命周期,可結合演示在集成開發環境里設置斷點進行跟蹤調試。對于設計模式內容的教學,原則是簡明扼要,突出設計思想的應用。通過對精選的幾個重要的設計模式的深入解析,以點帶面,引導學生去自學其他模式。使用簡潔而有趣味性的案例,增強授課效果。強調設計的規范性,但不強調算法的設計與實現,以免分散學習注意力。在綜合類例子的講解時,突出重構設計思想。舉同一個應用場景案例,根據需求的變化,設計與實現逐步迭代,適時引入設計模式進行重構。讓學生在學習過程中體會到軟件開發過程是從無到有、從簡單到復雜的迭代過程,符合事物發展的一般規律。
此外,積極采用教學輔助手段幫助學生理解設計思想。自主開發一款面向對象程序可視化與評分系統(OOPVS 系統),能實現程序的可視化處理,并提供對程序的評分功能。該軟件的可視化功能采用標準UML 類圖方式顯示,用戶可以在系統里直觀地查看面向對象程序的結構,有助于理解較為復雜的設計思路,尤其是帶有各種設計模式的情況。程序評分功能可對指定的程序進行比照處理,給出相應的相似度評分值,以便為改進設計提供參考。
2)實驗課教學方法。
配套理論課的實驗設計題目有驗證型實驗和設計型實驗。驗證型實驗要求對章節主要案例進行調試并分析,促進基本知識點的掌握。對于綜合類的驗證題要求對較多相關知識融會貫通,比如要求對某個開源框架軟件進行分析,發現并總結其中涉及的設計模式。設計型題目既要緊扣教學知識點,給出具體的要求,又要讓學生有自由發揮的余地,鼓勵具有個性化的設計方案。綜合類的設計題目應該覆蓋主要的知識點,給出的要求需有層次性,比如基本要求是設計某些指定的類和接口,完成特定的功能,以及應用指定的設計模式完成重構;進階要求是嘗試采用某幾種設計模式的組合進行重構,分析重構的效果。此外,我們嘗試通過OOPVS 系統對學生完成的作品與參考實現進行對比,通過積極反饋評分的結果給學生成就感,進而激發學生的學習興趣,形成教與學的良性互動。
學習效果的檢驗需要通過合理的考核機制來完成。在本門課教學實踐中,對應各個教學階段設置了平時、中期和期末這3 種考核。
平時考核是對理論課后布置的思考題和實驗課布置的實驗作業的完成情況進行考查。實驗作業的題目內容緊扣章節內容,每次作業一般包括驗證型和設計型兩類題目。
中期考核安排在課程中期進行,這時已完成面向對象篇的教學。通過對平時考核情況進行甄別,按一定比例抽取好、中、差三類學生進行口試。口試的內容采用隨機抽取做過的實驗作業題目進行問答,可根據實際情況臨場提新問題。中期考核的重要性在于可根據考核結果對存在的問題進行總結,為下一步的教學調整提供依據。
期末考核在課程結束后進行。考慮到本門課程的教學目標是培養學生的設計思想和編程技能,考核形式不采用傳統的試卷方式,而是完成一個系統的設計與實現并參加答辯。學習完最后的綜合應用篇后,學生對面向對象編程知識體系和開發技能有了整體的把握,初步具備解決較為復雜工程問題的能力。考核要求學生全面應用面向對象的設計思想完成一個完整系統的分析與設計,采用面向對象的語言進行編碼實現。給出個性化的不同選題以降低抄襲的可能性;題目要求條目具有層次性,有必做要求和選做要求。口試前一周公布選題,要求全員口試,未參加口試的學生期末考核成績記零分。口試之前同樣需要根據學生的平時學習情況進行區分,以便提問有的放矢,節省時間并提高實效。本門課的課程成績根據平時成績占40%、期末考核成績占60%的比例綜合給出。
根據面向對象編程課程的定位,把設計思想的培養作為教學的核心,克服了傳統講授一門編程語言的局限性,促進了學生設計思維的拓展。為了系統化把設計思想的解析融入教學中,改革的教學內容包含面向對象設計和設計模式應用這兩個有遞進關系的不同層面的內容,既兼顧了面向對象編程的語言工具內容,又突出了面向對象設計思想。設計思想雖然以Java 語言作為載體進行教學,但對C++、C#等其他主流的面向對象語言仍然適用。在教學實施過程中,根據教學內容發展與之相適應的課堂教學方法和考核方法,使得操作可行且有實效。筆者在最近一屆實施教改后的學生學習情況中看到了較好的教學成效。比如在筆者講授的JavaEE 架構技術課程中發現,學生對軟件框架的理解程度和應用掌握情況普遍好于往屆;而在后續創新創業這門綜合實踐課程中,涉及面向對象軟件開發時,不少學生能自覺應用面向對象設計思想,結合采用合適的設計模式完成系統實現,獲得較為理想的效果。