張渤
程序設計教學(編程教育)已經成為信息技術教學的核心內容之一。在以信息經濟、低碳經濟等經濟形態為主導的當代社會背景下,從人的全面發展出發,人才的培養核心是核心素養。程序設計教學成為信息技術學科核心素養——計算思維培養的重要途徑。而在中學程序設計教學中,還存在一些不足甚至錯誤做法,嚴重影響著信息技術教學效果,無法達到預期的育人目標。無論是從宏觀課程設計,還是從微觀教學內容來看,借助軟件工程思維有利于擺脫純粹的理論教學,重構課堂,培養學生統籌規劃、綜合設計、分析推理等關鍵能力。
軟件工程學是一門研究用工程化方法構建和維護有效、實用、高質量的軟件的學科。它涉及程序設計語言、數據庫、軟件開發工具、系統平臺、標準、設計模式等方面。軟件工程學借鑒傳統工程的原則、方法,以提高質量、降低成本和改進算法。其中,數學用于構建模型,計算機科學用于設計算法,工程科學用于制定規范、設計范型、評估成本及確定權衡,管理科學用于計劃、資源、質量、成本等管理。軟件工程學定義的軟件開發過程,通常包括需求分析、概要設計、詳細設計、編碼、測試、交付維護等階段。
下面以一個簡單的程序案例為例,詳細分析軟件工程思維與傳統程序教學的差異。案例背景:學校舉行一個“1分鐘投籃班級對抗賽”,每班參賽選手5人,每人1次投籃機會且限時1分鐘,共有10個班級參加比賽。比賽成績以班級所有選手投中總數進行計算。請設計一個小程序,實現成績統計和排序工作。
軟件工程思維更關注需求分析和概要設計
傳統的教學方式,教師往往將上述案例問題簡化為“每組5個數求和,10項求和結果排序”,然后就直接進入程序語法教學環節了。而對于軟件工程思維來說,需求分析要解決做什么和怎么做的問題。學生要自己分析這個案例,找出解決方案,得出設計思路。通過分析,學生可以發現需要設計哪些功能,如輸入、求和、排序等。然后,要明晰這些功能可能涉及的編程語言知識。
第一,通過具體問題的分析,學生發現所學內容能夠解決實際問題,是有實際意義的,從而避免了傳統教學中用編程解決純粹的數學問題的情況。需求分析能夠激發學生學習興趣,使得程序設計不再是單純的語法練習。從核心素養角度來看,有利于培養學生開發或運用技術來解決問題的能力(技術素養),引導學生研究問題,并找到創新、有效的問題解決之道(創造性)。前期的需求分析可以有效解決程序設計的盲目性和“無從下手”之感,便于學生對整個程序的理解,其實也能夠為后續教學節約時間。也許,這個案例過于簡單,尚不能體現需求分析的重要性。若將案例擴展為運動會成績統計程序這樣的大案例,則會超出學生的設計能力,反而不利于學生學習。在小案例學習過程中,可以引導學生類比、類推,達到舉一反三的目的,彰顯小案例的典型性和代表性特點。
第二,概要設計是一名設計師根據用戶交互過程和用戶需求來形成交互框架和視覺框架的過程。簡單來說,就是將軟件模塊、功能、層次關系用視覺化的方式展示出來。一般情況下,概要設計不需要使用編程語言,常見如流程圖。對應傳統教學,流程圖設計往往只是算法解析描述的工具,很少用來展示整個程序的功能設計。如果引導學生運用流程圖進行功能的模塊化劃分,有助于培養模塊化程序設計思維。通過概要設計可以進一步明確程序的模塊構成和功能,便于確立各部分的實現方法(算法選擇)。在設計環節還要決定程序設計使用的變量名稱、類型甚至取值范圍等細節問題。為便于后續閱讀程序,變量命名不僅僅要“見名知意”,還要系統規劃變量名稱的分類以及大小寫規范等,這能夠鍛煉學生良好的規范表達意識。這與平時教學中變量名使用無意義的單字母等對學生習慣的影響有很大不同。
軟件工程思維更突出編碼的模塊化設計和軟件測試
軟件工程對程序教學的一個很大的意義是形成良好的程序設計的代碼文化與素養,形成日漸深厚的計算思維。其中,程序的模塊化設計是良好的程序設計過程技能,而編碼測試則是良好性工程人員的代碼文化素養。
第一,編碼的模塊化設計,是指在進行程序設計時按照功能將一個復雜程序劃分為若干程序模塊,每個程序模塊完成一個確定的功能,模塊之間通過必要的聯系和互相協作完成整個功能的程序設計方法。與通常的簡單程序設計要求不同之處在于,模塊化設計主要體現在兩個方面,一是程序設計盡量使用函數、子過程、子程序,少使用全局變量;另一方面,盡量將代碼按照模塊劃分并做好注釋。
以“1分鐘投籃班級對抗賽”為例,可以將輸入、求和、排序分作三個小部分。與平時相比,代碼書寫不一定減少,但會讓編程作者和閱讀者都能清晰了解整個程序的架構,有利于錯誤排查和分工協作。如果遇到諸如“運動會成績統計”這樣有一定復雜度的程序設計,通過調用某個功能模塊(如函數、子程序等),則能較好地解決不同比賽項目的人員分組、成績輸入、排序打印等問題。而沒有模塊化的程序設計,可能要重復設計相應功能,存在大量的重復代碼,會降低運行效率,且在遇到問題時不容易檢查。
第二,軟件測試是對編碼程序的正確性、效率、容錯能力等的測試。程序設計很可能遇到代碼錯誤甚至算法錯誤,在教學中應該注意培養學生觀察分析程序運行結果、錯誤提示的能力,對不同的數據結構、算法選擇進行優劣評估等。在常規教學過程中,我們多數使用驗證性實驗進行教學。
如前面投籃的案例,程序設計完成后,一般會要求學生輸入3到5組的“正常”數據進行驗證。驗證僅僅限于證明語法結構可能沒有錯誤。這種知識鞏固式的教學模式,使得不少學生養成一看到出現預計結果就終止實驗的習慣,其實是不利于培養學生的程序測試意識的。參考軟件工程思維中的程序測試,我們在要求學生進行數據驗證時,一方面要提高驗證的數據量和運行次數,另一方面要盡量使用“邊界值”或“異常值”進行驗證。仍以投籃案例為例,如果程序設計時限定了數組(或列表)上下限值,則在驗證時要在上下限的邊界選擇數據進行驗證。例如,根據生活實際經驗,我們設置了1分鐘投籃的上限為100次,那就可以使用三位數(如127)作為測試數據驗證我們的設定是否有效。除此之外,驗證數據還應包含負數、小數等,以避免程序運行時錯誤輸入帶來的錯誤結果。從軟件工程視角來看,程序設計要關注編程安全問題,如分母為0、超出數組界限、變量取值超出范圍等情況。而在程序設計教學中,這些也恰恰是不易被發現的“易錯點”。可見,測試數據的作用是非常大的,設計有效的檢驗數據,既能檢驗程序設計的規范性和算法的合理性,同時能夠讓學生強化測試意識,避免測試的隨意性,為以后解決復雜的具體問題奠定基礎。
通過引入符合實際情況的測試數據,可以有效檢驗程序的健壯性。而要提高健壯性,就要進行容錯設計,從而使得程序設計從簡單功能向復雜功能過渡,拓展學生的思維強度和廣度,激發學生的學習興趣。在上述案例中,負數或小數作為無效輸入,如何解決因此類輸入所導致的程序結果錯誤呢?學生很容易想到,在輸入錯誤時進行提示并要求重新輸入。由此,再講解相關程序語法,學生就更容易接受。同樣,在大量數據輸入時,不僅僅會出現錯誤輸入,還可能會出現漏掉數據等情況。這就要求我們不僅僅要檢驗輸入數據的合法性,還要跟蹤數據的數量。必要的時候,還可以在程序關鍵步驟設置“斷點”,以隨時跟蹤數據的變化。遇到錯誤不容易判斷時,可以靈活運用數據跟蹤,更容易發現問題根源。根據現實中可能遇到的問題,學生思考解決方案的過程中,不知不覺地拓展了程序功能,很多知識的學習也變得順理成章。
綜上所述,我們可以看出,在程序設計教學中運用軟件工程思維,并不是只有復雜程序才需要,也不是只有專業人士才可以做到的事情。在任何程序設計中,都可以滲透軟件工程思維。而這樣的思維方式,不僅僅有利于加深學生對程序設計的理解,強化應用技術解決實際問題的能力,也將大大提升我們的程序教學效率。我們相信,程序設計對于學生來講不再是枯燥乏味的學習體驗。
蒼山點題
如果我們說一線教師的專業水平與學術水準在新一輪課標下已初見端倪并不準確,如果說已經碩果累累也為時過早。怎樣評價才合適呢?透過本期解碼推薦的這兩篇重磅文章,我們不妨去用心感受這“新星閃爍”般的思維光芒。
第一篇文章,一句泛“計算思維”時代,把我們對計算思維的認識的局限一下就打開了。首先是尋根溯源,提出計算思維是什么、要培養什么的問題。內容不再復述,只提那一個視頻折半瀏覽找水杯的例子,就見其精彩絕倫。然后是高屋建瓴,問:計算思維就是算法嗎?就是編程嗎?尤其是,以實例說明在數據與計算模塊之外的模塊中也可以深入培養計算思維。例如,信息系統與社會中同樣可以培養計算思維;又如,網絡基礎選修里面的網絡安全部分也可以深化培養計算思維。這對我們是一種怎樣的啟示?
第二篇文章,給我們一種暫時離開計算思維去軟件工程學尋找程序教學的深邃。在程序設計教學中如何應用軟件工程學呢?軟件開發過程包括需求分析、概要設計、詳細設計、編碼、測試、交付維護等階段。其中,軟件工程思維更關注需求分析和概要設計,軟件工程思維更突出編碼的模塊化設計和軟件測試,只這兩點就夠我們把程序設計教學提高到一個比較專業、比較深邃的境地,這不是一個巨大的驚喜嗎?
信息技術教育滄海茫茫,必有新的浪花;信息技術教育天空遼闊,必有新的星辰。我們一起前行、一起探索,藍調解碼期待您的浪花與光芒一起造就新的信息技術教育風景。