溫小寧
摘 要:本文從面向?qū)ο蟪绦虻姆治鲈O計入手,簡要分析了面向?qū)ο蟪绦虻脑O計方法,借助C++語言提出了面向?qū)ο蟪绦蛟O計的若干思維方式,對面向?qū)ο蟪绦蛟O計的一體化教學實踐開展了一些實踐探索和思考。
關鍵詞:面向?qū)ο?;分析設計;思維方法
中圖分類號:G712 文獻標識碼:A 文章編號:1005-1422(2015)05-0065-02
面向?qū)ο蟮南到y(tǒng)分析設計,就是將面向?qū)ο蟮姆椒ㄟ\用到解決實際問題中去,完成對某個特定領用領域的分析和建模的過程。要解決系統(tǒng)的對象、對象的屬性和操作、對象的動態(tài)特性、對象間的構造關系及通信關系等。系統(tǒng)設計階段最重要的任務是確定系統(tǒng)結(jié)構,包括將系統(tǒng)劃分成若干個子系統(tǒng),確定子系統(tǒng)的本質(zhì)特征,擬定數(shù)據(jù)管理策略、協(xié)調(diào)子系統(tǒng)軟硬件和全局性資源分配,決定軟件控制的實現(xiàn)方法、系統(tǒng)的邊界條件和交替使用優(yōu)先權等。在設計階段,要通過建立一些類以及它們之間的關系來解決問題,要求設計語言必須具有抽象、封裝、繼承和多態(tài)性等關鍵性要素。C++語言不是一種純面向?qū)ο蟮恼Z言,但C++語言的可靠性、可重用性、可擴充性和良好的可維護性使它在面向?qū)ο蟪绦蛟O計中具有得天獨厚的優(yōu)越性。筆者在多年的程序設計教學中,結(jié)合學生實際,實施一體化教學,取得了一些初步成效。
一、巧用設計方法,解決程序的“先天缺陷”
1.單一設計方法的局限性
設計是程序的基礎和前提,關乎系統(tǒng)的全局性,如果設計出了問題,對整個體系的影響將是災難性的。傳統(tǒng)的自頂向下的設計方法,從問題大的方面入手來尋找解決辦法,依次類推逐步深入,再用同樣的方法來解決剩下的相對較小的問題。運用自頂向下設計方法掌握結(jié)構層次的關鍵技術是恰當?shù)?、有選擇地忽略某些細節(jié)方面的問題,集中精力“找主干、搭框架”。其精髓是把難度大的問題被分解成一系列難度小的技術問題,先解決大問題,然后再依次解決小問題。但是,實際運作過程中往往并無規(guī)律可循,什么是大問題,什么是小問題,哪些問題應先解決,哪些問題可以后解決,往往很難界定,因問題有時很難表述清楚。一旦劃分有誤,又要折返,重新排查,陷入麻煩。這對設計者的前瞻性和敏銳的洞察力具有很高的要求。
與之相對,自底向上的設計方法是從解決基本的、簡單的問題入手,在此基礎上逐步建立解決復雜問題的機制,直到整個問題得以圓滿解決。它的優(yōu)點是根基扎實,無需反復。但是,設計者面對紛繁復雜的系統(tǒng),要逐個思考每一個基本簡單問題的解決方法,就會陷入了一個相當復雜而尷尬盲目的境地:東一榔頭西一棒子;顧了這頭,忘了那頭,漫無目的,耗時太多,也不理想。
2.取長補短,兼容并蓄
面向?qū)ο蟮脑O計方法落腳點是“對象”,著眼點是“面向”,因此,在教學中可以將自頂向下和自底向上的設計的優(yōu)點兼而用之。比如類樹的設計,自頂向下的方法是從最頂端的基類開始,一級一級派生出新類,添加新的成員,直到產(chǎn)生的源生類滿足程序設計的要求為止。單純使用自頂向下法,如果高層一旦要進行修改,下層的工作就會白做。這時,如果同時考慮自底向下的設計方法,情況就大為不同:在設計類樹工作中,從最基層的派生類開始,提取派生類中共同的本質(zhì)特征創(chuàng)建一個基類,這樣一層一層地堆上去,最后形成合理的類族。自底向上的方法考慮的是基層的問題,大大降低了“工作到一半發(fā)現(xiàn)還有不可解決問題的”風險。綜合運用自頂向下和自底向上兩種設計方法,使建立的類樹具有合理的并都能得到順利解決的層次結(jié)構,使系統(tǒng)的可行性、安全性和穩(wěn)定性大大增強。
二、大膽創(chuàng)新思維方法,提高程序的運行質(zhì)量
在教學過程中,要引導學生用最簡單最直接最有效的辦法實現(xiàn)程序效率的最優(yōu)化。
1.改頭換面靈活運用“自由全程變量”
“自由全程”是指變量不屬于任何類的成員。如Main()、標準C庫的所有過程以及所有用C語言寫的過程都屬于“自由全程”的范疇。在C++語言產(chǎn)生以前,要減少或者取消自由全程的使用幾乎是不可能做到的。自由全程變量的引入增強了程序設計的自由度和開放性,為廣大設計者所推崇。但在實踐過程中,自由全程變量的過度使用會帶來很多問題,特別是對初次接觸的學生來說,甚至會造成一定程度的混亂,造成很大的麻煩。靈活運用C++語言提供的相應機制可以巧妙地解決這一問題。具體分兩步走:第一步,將這些全程變量的所有權劃歸給一些指定類的對象,并將這些全程變量確定為靜態(tài)類成員,明確全程變量的使用權,把這些全程變量的管理集中在一個地方。第二步,將這些全程變量放入類中并給它取名,使全程變量和所在的類名緊緊地聯(lián)系在一起。通過轉(zhuǎn)換,全程變量仍然可以自由地被訪問,但它的名字變成了兩部分,一個是類名,一個是它本身的名字,這就杜絕了全程變量在使用過程中引起名字沖突的可能性。
2.借助內(nèi)存管理系統(tǒng)防止“類”型的誤用
在面向?qū)ο笙到y(tǒng)中,多數(shù)程序的運行行為都依賴于對象的類型。比如,一個總的表示圖形形狀的類,從中可以派生出各種各樣特殊的圖形類。在這個類族中,每個類型都必須執(zhí)行各自特殊的draw()函數(shù)以便畫出各自代表的圖形。每次調(diào)用draw()函數(shù)時,畫出的圖形形狀將依賴于程序?qū)嶋H運行時所控制的對象類型。如果制造一個陷阱謊報了類型,程序就會畫出錯誤的圖形。又比如,指向整型的指針類和指向一個具有10個整型單元的數(shù)組的指針類是完全不一樣的兩碼事。故此,重視類型問題是有效防止錯誤發(fā)生的第一道防線。
借助C++語言提供的新的內(nèi)存管理系統(tǒng),可以使問題迎刃而解。C++語言在分配內(nèi)存時,如果由于某種原因分配不成功,則返回空指針0x0000 0000。當用戶繼續(xù)使用比如改寫數(shù)據(jù)時,系統(tǒng)將因為發(fā)生訪問違規(guī)而退出。當然,面向?qū)ο笤O計方法本身,還可通過設計合理的類的層次結(jié)構,創(chuàng)建一組相互兼容的類型,避免發(fā)生相似的錯誤。
3.充分發(fā)揮“繼承”在面向?qū)ο蟪绦蛑械奶厥夤π?/p>
繼承提供了很多手段。類的層次設計和實現(xiàn)是屬于繼承的面向?qū)ο笤O計的范疇,C++語言提供了眾多的構件模塊,包括公有的,保護的和私有的基類以及虛和非虛的基類,還有虛和非虛的成員函數(shù)等。用好“繼承”這項工具,充分發(fā)揮“繼承”在程序設計中穿針引線的特殊作用,能收到事半功倍的效果。
①把握繼承的唯一性和方向性。公有繼承指的“就是一個”。比如,類B公有繼承于類A,就是在告訴C++編繹器類型B的每一個對象也是類型A的對象,反之則不然。如果說對于一個類型A的對象是正確的一件事,則對于一個類型B的對象同樣也是真實的,反之也不行。
②盡量使用單一繼承。如設計一個活動卡通人物的類屬。一般來說,任何卡通人物都要跳舞或唱歌,但是每種類型的卡通人物表演這些動作的方式也是不同的。虛函數(shù)可以把所有的卡通對象的跳舞唱歌和缺省的行為動作表示成該類中的空函數(shù)。但是當要表示一個具體的卡通人物如蝴蝶或蜻蜓時,往往會陷入一些不必要的重復或繼承。因為蝴蝶和蜻蜓兩個類中具有很多共同的東西。并不是說讓其中一個類繼承于另一個類。這時不妨建立一個基類,讓兩個類同時繼承于這個共同的基類,如定義為insect(昆蟲),問題就變得簡單了。
③“繼承”的分層技術實現(xiàn)。利用分層技術“has-a(有一個)” 和“ia-implemented-in-terms-of(按·····方式實現(xiàn))” 實現(xiàn)繼承。從C++程序的執(zhí)行效率來看,使用繼承從base類派生一個derived類,和在derived中將base類作為它的一個對象成員是一樣的。分層是一個處理過程,也可稱為包含或嵌入,它通過讓分層的類型包含被分層的類的對象作為其數(shù)據(jù)成員,以便把一個類建立在另一個類的上面。如:
這里,Person類被分層到String、Address和PersonNumber等幾個類上面,使它繼承了String、Address和PersonNumber的相關特性,因為它里面含有這些類型的數(shù)據(jù)成員,同時,又保持了Person類的相對完整。
面向?qū)ο蟪绦蛟O計語言的關鍵不在于它的語法特征,而是其所提供的對自然問題求解的機制和結(jié)構,它給用戶提供的支持程序設計的窗口環(huán)境和管理工具。它是一種開放性的設計平臺,要求設計者要面向?qū)嶋H問題,創(chuàng)新思維,以便更好地解決問題。
參考文獻:
[1]吳煒煜.面向?qū)ο蠓治鲈O計與編程[M].北京:清華大學出版社,2000.
[2]張基溫.C++程序設計基礎[M].北京:高等教育出版社,1996.
[3]譚浩強.C++面向?qū)ο蟪绦蛟O計[M].北京:清華大學出版社,2006.
[4]鄭阿奇.C++面向?qū)ο髮嵱媒坛蘙M].北京:電子工業(yè)出版社,2009.
責任編輯 賴俊辰