面向?qū)ο蟪绦蛟O(shè)計(jì)重要概念
面向?qū)ο缶幊淌蔷幊谭妒剑╬rogramming paradigm)的一種,是目前應(yīng)用最為普遍的一種編程方式,但并不是說面向?qū)ο缶幊檀砹司幊谭妒降淖睢跋冗M(jìn)”形式,它僅僅是眾多編程范式中的一種。
經(jīng)常用于對比的過程化編程,與面向?qū)ο缶幊桃粯?,同屬于結(jié)構(gòu)化的程序范式。面向?qū)ο蟮某绦蛟O(shè)計(jì)對比同等的過程化設(shè)計(jì)有相對的優(yōu)勢,但這并不代表面向?qū)ο蟮某绦蛟O(shè)計(jì)就超越了其他所有的編程模式,其他的編程模式在特定的要求下也具有不可替代的優(yōu)勢。
這里列舉幾種常用的編程方式和代表語言,如Haskell和Scheme所代表的函數(shù)式編程,Smalltalk和Java支持的純面向?qū)ο缶幊?,C++、Ruby、Python代表的多種范型編程,等等。
然而編程語言與編程范式并不能畫等號(hào),不同的人在不同的需求下,可以用一種語言編寫出不同的范式代碼,如C++可以支持過程化編程、面向?qū)ο缶幊毯头盒停0澹┚幊獭?br>
而混合兩種泛型的程序也很常見,如ABAP程序就支持過程化的傳統(tǒng)ABAP和面向?qū)ο蟮腁BAP混合在同一個(gè)程序中。
面向?qū)ο蟮腁BAP可以替代傳統(tǒng)ABAP的大多數(shù)功能,ABAP和ABAP OOP的混編情況與C和C++混編一樣并不會(huì)讓人感到意外。
如果比較面向過程和面向?qū)ο髢煞N程序范式,那么面向過程的程序設(shè)計(jì)是以功能設(shè)計(jì)為核心的,其首先關(guān)注的是需求功能的實(shí)現(xiàn),采用結(jié)構(gòu)化、自頂向下、逐步細(xì)化的設(shè)計(jì)過程;用函數(shù)來實(shí)現(xiàn)功能,用常量、變量來存儲(chǔ)數(shù)據(jù),所形成的軟件系統(tǒng)是函數(shù)和過程的集合。打個(gè)不太確切的比方,就像是歷史里面的“編年體”史書,“以天時(shí)記人事”,以時(shí)間為中心,按年、月順序記述史實(shí)。
如表5-1所示,面向?qū)ο蟮姆椒ㄊ菍?shù)據(jù)和行為進(jìn)行封裝,用屬性來存儲(chǔ)數(shù)據(jù),用行為來實(shí)現(xiàn)功能,同時(shí)也引入繼承、多態(tài)等機(jī)制,為可重用的軟件設(shè)計(jì)以及降低軟件的復(fù)雜度提供一種有效的方法。同樣打個(gè)不太確切的比方,就像是歷史里面的“紀(jì)傳體”史書,“為人物立傳記”,以人物對象作為傳記的中心敘述史實(shí)。
特性
面向過程的方法 面向?qū)ο蟮姆椒?/p>
關(guān)注的重點(diǎn)
強(qiáng)調(diào)任務(wù)(task)強(qiáng)調(diào)做這些任務(wù)的對象(object)
設(shè)計(jì)方式
將程序分成不同的部分,成為函數(shù) 程序山類和對象組成,功能被嵌入到類的方法中實(shí)現(xiàn)
數(shù)據(jù)安全
大多數(shù)的函數(shù)能夠并享全局?jǐn)?shù)裾 數(shù)據(jù)可以被隱藏,不被外部資源訪問
可擴(kuò)展性
擴(kuò)展或修改現(xiàn)有的功能可能會(huì)消粍更多的時(shí)間
基下以好的設(shè)計(jì),必要的新的數(shù)倨和方法可以較為容易地添加到程序
5.2.1 封裝的概述
首先介紹封裝(Encapsulation)的概念。
封裝是面向?qū)ο蟪绦虻牡谝惶卣?,封裝看起來很簡單,其實(shí)卻是面向?qū)ο笤O(shè)計(jì)中最為重要的一個(gè)特征。
封裝是一個(gè)過程,是對要在程序中處理的業(yè)務(wù)對象進(jìn)行抽象,定義成類(Class),隱藏?cái)?shù)據(jù)和實(shí)現(xiàn)細(xì)節(jié),公開調(diào)用接口。并且,封裝過程可以對類的屬性和方法的可見度進(jìn)行限制,將類內(nèi)的數(shù)據(jù)和方法授權(quán)給需要操作的類或者對象來操作,對不需要操作或者不可信的類或?qū)ο筮M(jìn)行信息隱藏。
現(xiàn)實(shí)世界中很多東西是我們會(huì)用但不會(huì)制造的,有的東西我們不僅不會(huì)制造,甚至連它的工作原理都不知道。
如果我問大家:“誰會(huì)用空調(diào)?”人人都能做到。
而如果我問大家:“誰能夠設(shè)計(jì)并裝配一臺(tái)空調(diào)?”不僅能做到的人不多,甚至了解空調(diào)制冷原理的人也不會(huì)很多。
封裝過程就好比你是一名電器設(shè)計(jì)師,需要考慮如何設(shè)計(jì)并制作一臺(tái)空調(diào),你不僅需要了解空調(diào)的原理,并且還要設(shè)計(jì)出簡單易用的方式,提供給普通用戶。
空調(diào)的工作原理是“逆卡諾循環(huán)”(液體氣化吸熱),即高壓的液態(tài)制冷劑進(jìn)入蒸發(fā)器中蒸發(fā)為低壓的氣體,從空氣中吸收熱量而制冷。
空調(diào)的室外機(jī)里面封閉了壓縮機(jī)、冷凝器、毛細(xì)管等部件,室內(nèi)機(jī)封閉了控制電路、蒸發(fā)器等部件,這些組件對用戶是不可見的。
用戶不必知道里面的電路和壓縮機(jī)是如何工作的,只要用戶會(huì)用遙控器,就能讓空調(diào)正常工作。
如果我們不為空調(diào)提供遙控器,而是直接把空調(diào)的電線和電路都暴露在外殼外面,使用時(shí)需要用戶直接對裸露的電線手工對接通電,然后再調(diào)整壓縮機(jī)來設(shè)定溫度,這不僅不是簡單的操作,實(shí)際上還是十分危險(xiǎn)的操作。
類的封裝與上述關(guān)于空調(diào)的使用比較類似,類封裝了一些數(shù)據(jù)和方法(比如空調(diào)的三個(gè)方法:開啟空調(diào),關(guān)閉空調(diào),調(diào)節(jié)溫度);類的方法的具體實(shí)現(xiàn)也很復(fù)雜(比如空調(diào)這些方法的實(shí)現(xiàn)都涉及了電路操作、壓縮機(jī)調(diào)節(jié)等對于普通用戶來說有相當(dāng)難度的細(xì)節(jié))。而我們沒有必要讓用戶了解如此復(fù)雜的細(xì)節(jié),用戶只需要正確地按照說明書使用,即可讓空調(diào)正常工作。
封裝就是為了隱藏細(xì)節(jié)和數(shù)據(jù),隔離復(fù)雜度,如果要調(diào)用類執(zhí)行業(yè)務(wù),那么只需要正確調(diào)用類的方法即可,不需要了解被調(diào)用類內(nèi)部的具體實(shí)現(xiàn)。
封裝同時(shí)也是對數(shù)據(jù)安全的一種保障,我們可以為類的屬性或方法添加控制權(quán)限,用私有聲明來隱藏和隔離數(shù)據(jù),這在一定程度上還可以保證業(yè)務(wù)和封裝數(shù)據(jù)的安全性。
也有一些理解,認(rèn)為封裝就是為了保障數(shù)據(jù)安全,這樣才能防止一些經(jīng)驗(yàn)不足的程序員的代碼誤操作,甚至還可以防止經(jīng)驗(yàn)太足而“節(jié)操”不足的程序員預(yù)留漏洞,供以后隨意獲取數(shù)據(jù)和篡改邏輯,其實(shí)這并不是封裝的主要目的。
對于封裝這一術(shù)語,我們還是查一下字典,體會(huì)一下其原意。我們用《牛津詞典》查看原詞(Encapsulation)的解釋:
Encapsulation~sth(in sth)(formal)to express the most important parts of sth in a few words,a small space or a single object——簡述;概括;壓縮。
可見“封裝”的原意就是“用幾句話描述一個(gè)事物最重要的部分”,是簡述和概括的意思,從英語的原意中可見封裝的根本目的是簡要地描述清楚一個(gè)事物,由此可以說數(shù)據(jù)隱藏和保護(hù)數(shù)據(jù)安全并不是封裝的主要目的,僅是附加功能而已。
面向?qū)ο笾蟹庋b的主要目的具體如下。
1)在數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)階段:封裝是業(yè)務(wù)邏輯抽象的軟件實(shí)現(xiàn)過程,封裝是以業(yè)務(wù)抽象設(shè)計(jì)為輸入,經(jīng)過數(shù)據(jù)結(jié)果的封裝而產(chǎn)出的一組類和實(shí)現(xiàn)代碼。封裝是為了實(shí)現(xiàn)良好的業(yè)務(wù)邏輯的抽象設(shè)計(jì),能夠讓類之間可以良好地表現(xiàn)業(yè)務(wù)邏輯,同時(shí)也是為了應(yīng)對未來的業(yè)務(wù)需求變化和產(chǎn)品升級(jí),能夠經(jīng)得起需求變化而最大限度地保持代碼重用,這是面向?qū)ο缶幊痰淖詈诵牡乃枷胫弧?br>
2)在開發(fā)階段:封裝是為了能夠進(jìn)行良好的模塊化分工,隱藏其他團(tuán)隊(duì)或人員不需要了解的屬性和實(shí)現(xiàn)細(xì)節(jié),僅公開完整且必要的接口方法,簡化工作,提高協(xié)作效率,同時(shí)用較小的成本來防止在編程過程中產(chǎn)生易對數(shù)據(jù)進(jìn)行誤操作的代碼邏輯的可能性,從而提高軟件的穩(wěn)健性。
3)在系統(tǒng)運(yùn)行階段:可以按預(yù)定的業(yè)務(wù)要求去控制屬性讀寫的訪問等級(jí),按特定的訪問權(quán)限來使用類的屬性,防止業(yè)務(wù)中的不可信邏輯對類對象的隨意訪問和修改,從而防止相應(yīng)的誤操作。
如表5-2所示,類可以將數(shù)據(jù)和方法分裝成3個(gè)不同的可見度,在ABAP OOP中,這些可見度可用以下語句進(jìn)行定義。
·公共可見部分(PUBLIC SECTION):在此部分聲明的數(shù)據(jù)和方法在任何類(包括友元類)和程序中都可以訪問。
·受保護(hù)的可見部分(PROTECTED SECTION):在此部分聲明的數(shù)據(jù)和方法在類本身和類的子類或者友元類中可見。
·私有可見部分(PRIVATE SECTION):在此部分聲明的數(shù)據(jù)和方法在類本身及其友元類內(nèi)可見。