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