天天看點

軟體的一些概念解釋

有關程式的概念

1程式:程式就是要計算機完成某項工作的代名詞,是對計算機完成某項工作所涉及的對象(注意這裡的對象并不是指代碼中的對象,這裡的對象是指現實世界中真實存在的事物)和動作規則(對應代碼中的方法)的描述。這裡的“程式”是人們普遍使用的一個樸素的概念,并非指代碼級别的程式。

2計算機程式:運用計算機來解決一個實際問題,首先需要把問題處理的對象搞清楚,處理的具體步驟和方法事先要設計好,然後再利用計算機能夠了解的語言(是指程式設計語言,如彙編,C,C++,C#,Java等等)寫出具體的操作步驟,用程式設計語言針對實際問題寫出來的代碼就是計算機程式。計算機按照程式運作就可以自動執行程式指令,解決相應的問題,完成相應的任務。

3算法:算法被公認為是計算機科學的基石。通俗地講,算法是解決問題的方法,現實生活中關于算法的執行個體不勝枚舉,如一道菜單、一個安裝轉椅的操作指南等等。嚴格地說,算法是對特定問題求解步驟的一種描述,是指令的有限序列。算法展現在對動作規則的描述,它描述解決一個問題所采取的方法和步驟。通常一個問題可以有多種算法,一個算法可以解決某個特定的問題。算法有五個特征:一、有窮性,指算法是有限的操作序列;二、确定性,指每個操作有确定的含義,無二義性;三、可執行性,指每個操作都是可以執行的;四、有序性,指執行步驟嚴格按邏輯順序進行;五、可輸入/輸出資訊,輸入的資訊時算法加工的對象,而算法解決問題的結果應當輸出。好的算法具備下列特征:一、正确性,算法能滿足具體問題的需求,即對任何合法的輸入,算法都會得出正确的結果;二、魯棒性,也稱健壯性,算法對非法輸入的抵抗能力,即對錯誤的輸入,算法應能識别出并做出處理,而不是産生錯誤動作或陷入癱瘓;三、簡單性,算法容易了解和實作;四、抽象分級,算法一旦建立,必須由人來閱讀、了解、使用和修改。而大多數人的認識度是7+-2(即人類的短期記憶能力一般限于一次記憶5至9個對象),如果算法設計的想法太多,人就會糊塗,是以,必須用抽象分級來組織算法表達的思想。換言之,算法中的每一個邏輯步驟可以是一條簡單的指令,也可以是一個子產品,通過子產品調用完成相應功能。每個子產品表示一種抽象,子產品的内部描述了怎樣實作抽象,而子產品的名稱描述了子產品的功能。;五、高效性,算法的效率包括時間效率和空間效率,時間效率顯示了算法運作得有多快,而空間效率則顯示了算法需要多少額外的存儲空間(記憶體)。不言而喻,一個好的算法應該具有較短的執行時間并占用較少的輔助空間。

4資料結構:資料結構展現在對對象(或資料)的描述,它描述問題所涉及的對象的組織結構以及對象之間的聯系。數值計算問題可以用數學方程來描述,但更多的非數值問題無法用數學方程加以描述,而是通過表、樹和圖之類的資料結構來建立數學模型。

程式 = 算法 +資料結構

也就是說程式設計主要包括兩方面的内容:行為特性的設計和資料結構特性的設計。行為特性的設計是指完整地描述問題求解的全過程,并精确地定義每個解題步驟,這一過程即是算法的設計;而資料結構特性的設計是指在問題求解過程中,計算機所處理的資料以及資料之間的聯系的表示方法。程式設計的關鍵是構造程式的資料結構,并描述問題所需要的、施加在這些資料結構上的算法。

5程式設計語言:程式最終需要使用計算機能夠了解的語言具體寫出來,這就是計算機程式設計語言。所謂“語言”就是一套具有文法、詞法規則的系統。語言是思維的工具,思維是通過語言來表述的。計算機程式設計語言是計算機可以識别的語言,是程式實作的工具。任何一門計算機程式設計語言都需要通過資料類型、運算符與表達式以及控制語句等來定義和實作程式中的資料結構和算法。

軟體開發方法

1一個大型軟體系統的開發,必須經曆這樣一個過程:

需求分析-——>系統設計——>程式編碼以及編輯、編譯和連接配接——>系統測試——>運作維護。

在軟體開發過程的每一個階段,都要有明确的任務和要求,必須産生一定規格的文檔資料。

2軟體開發過程中最關鍵的是需求分析和系統設計,然後再通過具體程式編碼去實作。

而系統設計中的一個關鍵内容是選擇合适的軟體開發方法——即面向過程的結構化程式設計方法和面向對象的程式設計方法,也許以後還會出現一些新的軟體開發方法,比如今年來的面向服務的程式設計方法。

3結構化程式設計的基本思想是:自頂向下,逐漸求精,将一個複雜的問題分解為若幹個易于處理的子問題,進而将整個程式劃分成若幹個功能相對獨立的子子產品或過程。子子產品又可繼續劃分,直至最簡。每個子產品都隻有一個入口和一個出口,整個程式則全部可以用順序、選擇、循環着三種基本結構及其組合來實作了。結構化程式設計是以解決問題的整個過程作為程式的基礎和重點,是一種面向過程的程式設計方法。

4:面向過程的結構化程式的特點:程式過程是子產品化的,子產品是分層次的,層與層之間是一種從上往下的調用關系。面向過程程式的基本構成機關是過程(或者函數)

5面向過程的結構化程式設計方法有許多優點:第一、各子產品可以分别編寫,使得程式更易于閱讀、了解、測試和修改,即友善分工合作。這樣不管編寫多大的程式,不管有多少人參加編寫,都可以把他們的子產品有效地連接配接起來。第二、友善增加新的功能子產品,即友善擴充。第三、功能獨立的子產品可以組成子程式庫,有利于實作軟體的複用。

6面向過程的結構化程式方法的缺點:由于結構化程式設計方法強調的是子產品的功能,是面向過程的,是以資料與處理這些資料的過程是分離的(這正是它和面向對象最大的差別,因為面向對象資料與處理這些資料的過程是集中到一個類裡面的)。這樣的系統設計方法會帶來如下一些問題:第一、對不同格式的資料作相同的處理,或是對相同資料作不同的處理,都需要編寫不同的程式子產品來實作,這使得程式的可複用性大打折扣。第二、由于過程和資料相分離,資料可能被多個子產品所使用和修改,這樣很難保證資料的安全性和一緻性。第三、當資料處理的方法或是資料類型有改變時,會導緻整個系統的重新設計和編碼。由于上述問題,面向過程的結構化程式設計方法難以适應大型軟體的設計開發。

7面向對象的程式設計:在面向對象的程式中,作為計算機模拟真實世界的軟體實體——對象是一個屬性(資料)集及其行為(操作)的封裝體(這裡的封裝體就是将資料和處理這些資料的過程封裝到一起的意思,恰巧和面向過程的資料與處理這些資料的過程是分離的是相對的,這即是它們思想上的最大差別)。對象與對象之間的聯系是通過消息傳遞的機制來實作的。對象對消息的響應,就是對象調用自身的方法(成員方法或成員函數)去完成相應的任務。簡單地說,面向對象程式的程式結構可以表示如下:                                        對象=算法+資料結構

程式 = 對象 + 消息

這裡程式是由一個個封裝的對象組成,而對象是由緊密聯系的算法和資料結構組成,它封裝了資料和對資料的操作。

8面向對象方法和面向過程方法的關系:面向對象程式設計在技術方法上是對傳統軟體開發方法的繼承和發展,它汲取了面向過程的結構化程式設計中最為精華的部分,即以順序、選擇、循環三種結構實作對功能或過程的封裝,再通過引入類的資料結構(即類是一種資料結構),進一步實作對對象的封裝。與功能(過程)相比,一個應用系統中的對象一般總能保持相對穩定性,因而以面向對象構造的軟體系統的主體結構也具有較好的穩定性和可重用性。深入到系統内部要實作的具體功能或對象的行為,都要以算法設計為基礎,算法和資料結構仍然是各種系統建立的根本。從面向對象的視角來看,過程是局部的算法問題,對象才是系統架建構立的基礎。

面向對象的一些概念

1對象:一切事物皆為對象,即所有的東西都是對象,對象就是可以看到、感覺到、聽到、觸摸到、嘗到、或聞到的東西。準确地說,對象是一個相對自包含(元件不依賴其他元件,能夠以獨立的方式供外部使用)的實體,用一組可識别的特性和行為來辨別。

2類:類就是具有相同屬性和功能的對象的抽象的集合。

3抽象類:抽象類通常代表一個抽象概念,它提供一個繼承的出發點,當設計一個新的抽象類時,一定是用來繼承的,是以,在一個繼承關系形成的等級結構裡面,樹葉節點應當是具體類,而樹枝節點均應當是抽象類。,第一、抽象類不能被執行個體化;第二、抽象方法必須被子類重寫實作。第三、如果類包含抽象方法,則類必須定義為抽象類,不論它是否還包含其他的一般方法。

4接口:接口是把隐式公共方法和屬性組合起來,以封裝特定功能的一個集合。一旦類實作了接口,類就可以支援接口所指定的所有屬性和成員。

5抽象:所謂抽象就是從被研究對象中舍棄個别的、非本質的或與研究主旨無關的次要特征,抽取共同性質、實質特征以後形成概念的過程,即抽象是概念設計的過程。面向對象方法就是通過類的機制實作其抽象性:類是具體具體對象的抽象,對象是類的一個執行個體。

6封裝:封裝也稱為資訊隐藏,是指将對象内部屬性和行為實作的代碼封裝在對象的内部,從外面無法看見對象的内部資訊,更不能随意進行修改(即都有一些public方法控制通路和修改),封裝的過程将設計好的概念編碼成具體的類,并通過程式設計語言的一些修飾符(private proctected)針對這個類選擇隐藏(private)哪些方法,而(public)暴露哪些方法的過程。另一種簡單的解釋是:每個對象都包含它能夠進行操作所需要的所有資訊(這個所有資訊包括它依賴的其他類),這個特性稱為封裝。封裝有很多好處:第一、良好的封裝能夠減少耦合。第二、類内部的實作可以自由地修改。第三、類具有清晰的對外接口(即public函數)。我們編寫代碼都是力求将可變部分封裝到一個地方(這個地方就是類,這個類可以沒有任何屬性,隻有一個方法封裝了 變化),目的就是為了改變時隻需改變一處即可。對對象進行抽象,将可變化的部分(屬性或者行為)封裝到一個類,簡單點說就是将對象抽象封裝成類,可以統一改變(即隻改一個地方)這個類的屬性和行為。比如當提到馬這個概念時,我們都會有個馬的形象,即有四條腿,一個馬頭(其實馬頭還是一個概念的東西),能跑,這就是馬這個概念給我們的一些基本資訊。馬是有很多對象個體的,我們對馬進行抽象(相當于概念設計,就是要讓“馬”這個概念能給于人們什麼資訊),并封裝成類(封裝成類,其實就是将設計好的概念編碼成具體的類啦,比如馬這個概念,我設定給予人們的資訊就是四條腿、一個馬頭,能跑,我編碼時就要寫一個馬類,并給這個類加上這些屬性,和能跑的這個方法)。對于這個馬的概念呢,其實是筆者自己對馬的概念設計,由我設計它有什麼屬性(或者說部件),有什麼行為,這就是抽象的過程。有一天,我覺得我的馬還要  加上一雙翅膀而且能飛(這就是變化),我就可以隻改我這個馬類給它加上一雙翅膀的屬性和飛的行為(方法),然後我這個類生産出來的馬就是一匹有翅膀可以飛的馬了,而不出現某個地方調用我的這個馬類生産出來的馬沒有翅膀或者不能飛,這就是類的好處(或者說封裝變化到類的好處),因為類把變化的部分封裝到了一處,這樣改一處即可。

7抽象和封裝的關系:抽象和封裝是互補的。面向對象程式設計的主體是類,類時具有相同屬性和行為的一類對象的封裝體,是對具有相同屬性和行為的對象的抽象描述.好的抽象有利于封裝,封裝的實體則幫助維護抽象的完整性。抽象是概念設計過程,封裝是将設計好的概念編寫成類的過程。

8繼承:對象的繼承代表了一種“is-a”的關系,如果兩個對象A和B,可以描述為B是A,則表明B可以繼承A。繼承者還可以了解為是對呗繼承者的特殊化,因為它除了具備被繼承者的特性外,還具備自己獨特的個性。繼承的優點:使 得所有子類公共的部分都放在父類,使得代碼得到了共享,這就避免了重複,這就使得修改或者擴充繼承而來的實作都較為容易。繼承的缺點:父類變則子類不得不變。繼承會破壞封裝,父類的實作細節暴露給了子類,這其實是增大了兩個類之間的耦合性。繼承顯然是一種類與類之間強耦合的關系。使用場景:當兩個類之間具備“is-a”的關系時,就可以考慮使用繼承了,因為這表示一個類似另一個類的特殊種類,而當兩個類之間是“has-a”的關系時,表示某個角色具有某一項責任,此時不适用繼承。比如人有兩隻手,但手不能繼承人;再比如飛機場有飛機,但飛機不能繼承飛機場。

9多态:表示不同的對象可以執行相同的動作,但要通過它們自己的實作代碼來執行。多态要注意幾點:第一、子類以父類的身份出現;第二、子類在工作時以自己的方式來實作;第三、子類以父類的身份出現時,子類特有的屬性和方法不可以使用。多态性是指不同類型的對象或相同類型的對象在不同的環境中接收同一個消息時會産生不同的行為。例如:不同類型的電話卡,其撥号方式相同,但連接配接的是不同的網絡;同一個電話卡在本地通話和在外地通話時,采用的是不同的計費方式。也就是說,同樣的外部接口(方法名),但具體的實作機制卻不同。多态性對“同一接口,多種方法”機制的支援,還可以使高層代碼(算法)隻寫一次而在低層可以多次複用。面向對象方法通過引入多态機制可以統一一個類族的對外接口,提高了類的抽象度和封閉性,進一步提高了代碼的複用率。

10對象、類、抽象類、接口的關系:第一、類是對對象的抽象,抽象類似對類的抽象,接口則是對行為的抽象,不管是什麼,其實都是在不同層次、不同角度進行抽象的結果,它們的共性就是抽象。接口是對類的局部(行為)進行的抽象,而抽象類是對類整體(屬性、方法)的抽象。第二、如果行為跨越不同類的對象,可使用接口。對于一些相似的類對象,用繼承抽象類。第三、從設計角度講,抽象類是從子類發現公共的東西,泛化出父類,然後子類繼承父類,而接口根本不知道子類的存在,方法如何實作還不确認,預先定義。這裡其實說明的是抽象類和接口設計的思維過程。抽象類往往是通過重構得來的,當然如果事先意識到多種分類的可能,那麼事先設計好抽象類也是完全可以的。抽象類時自底而上抽象出來的,而接口則是自頂而下設計出來的。

軟體開發思想的發展曆史

軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋

設計原則

遵循設計原則的目的:在需求變動(新增功能、原功能修改)時,将我們改動的地方降低到最少,花最少的時間、代價來在原有的代碼基礎上實作變動了的需求,提高可維護性、可擴充性、可複用性、靈活性。如果遵循某個原則違反了這個目的,則不需遵循這個原則。也就是說不一定要遵循設計原則,隻有在遵循設計原則對我們的代碼有利時,我們才有必要去遵循。

開放-封閉原則:軟體實體(類、子產品、函數)可擴充(即對擴充開放),但是不可修改(即對修改封閉),目的就是為了添加一個功能時,不影響原有的功能。

1、 絕對的對修改關閉是不可能的,無論子產品是多麼的“封閉”,都會存在一些無法對之封閉的變化。既然不可能完全封閉,設計人員就必須對于他設計的子產品應該對那種變化進行封閉做出選擇。是以,他必須先猜測出最有肯能發生的變化種類,然後構造抽象來隔離那些變化。對這種最有肯能發生的變化種類的猜測是很難的,是以等到變化發生時立即采取行動,建立抽象來隔離以後發生的同類變化,正所謂同一個地方不能摔跤兩次。

2、 面對新需求,對程式的變動是通過增加新代碼進行的,而不是更改現有的代碼,這就是“開放-封閉原則”的精神所在。

3、 當然,并不是什麼時候應對變化都是容易的。我們希望的是開發工作展開不久就知道可能的變化。查明可能發生的變化所等待的時間越長,要建立正确的抽象就越困難。

4、 修改用戶端程式類不算違反開閉原則,因為它不影響原有功能,而修改功能程式類則算是違反了開閉原則,因為它在原有的類上修改,是以會影響原有的功能。

5、 開放-封閉原則是面向對象設計的核心所在。遵循這個原則可以帶來面向對象技術所聲稱的巨大好處,也就是可維護、可擴充、可複用、靈活性好。開發人員應該僅對程式中頻繁變化的那些部分做出抽象,然而,對于應用程式中每個部分都刻意進行抽象同樣不是一個好主意。拒絕不成熟的抽象和使用必要的抽象一樣重要。

單一職責原則:就一個類而言,應該僅有一個引起它變化的原因。因為如果一個類承擔的職責過多,就等于把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成其他職責的能力。這種耦合會導緻脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。軟體設計真正要做的許多内容,就是發現職責并把這些職責互相分離。如果你能夠想到多于一個的動機去改變一個類,那麼這個類就具有多于一個的職責,就應該考慮類的職責分離。

裡氏替換原則(裡氏代換原則):一個軟體實體如果使用的是一個父類的話,那麼一定适用于其子類,而且它察覺不出父類對象和子類對象的差別。也就是說,在軟體裡面,把父類都換它的子類,程式的行為沒有變化。簡單地說,子類型必須能夠替換掉它們的父類型。隻有當子類可以替換掉父類,軟體機關的功能不受到影響時,父類才能真正被複用,而子類也能在父類的基礎上添加新的行為。正式由于子類型的可替換性才使得使用付父類型的子產品在無需修改的情況下就可以擴充。

依賴倒轉原則(依賴倒置原則):抽象不應該依賴細節,細節應該依賴抽象,即要面向接口程式設計,不要面向實作程式設計。依賴倒轉其實就是誰也不要依靠誰,除了約定的接口,大家都可以靈活自如。依賴倒轉其實可以說是面向對象設計的标志,用哪種語言來編寫程式不重要,如果編寫時都是考慮如何面向抽象程式設計而不是面向細節程式設計,即程式中所有的依賴關系都是終止于抽象類或者接口,那就是面向對象的設計,反之那就是過程化的設計了。高層子產品不應該依賴底層子產品,兩個都應該依賴抽象,示意圖如下:

軟體的一些概念解釋
軟體的一些概念解釋

迪米特法則:如果兩個類不必彼此直接通信,那麼這兩個類就不應當發生直接的互相作用。如果其中一個類要調用另一個類的某一個方法,可以通過第三方轉發這個調用。迪米特法則首先強調的前提是在類的結構設計上,每一個類都應當盡量降低成員的通路權限,也就是說,一個類包裝好自己的private狀态,不需要讓别的類知道的字段或行為就不要公開。迪米特法則其根本思想,是強調了類之間的松耦合。類之間的耦合越弱,越有利于複用,一個處在弱耦合的類被修改,不會對有關系的類造成搏擊。也就是說資訊的隐藏促進了軟體的複用。

合成/聚合複用原則:盡量使用合成/聚合,盡量不要使用類繼承。因為對象的繼承關系是在編譯時就定義好了,是以無法在運作時改變從父類繼承的實作。子類的實作與它的父類有非常緊密的依賴關系,以至于父類中的任何變化必然會導緻子類發生變化。當你需要複用子類時,如果繼承下來的實作不适合解決新的問題,則父類必須重寫或者被其他更适合的類替換。這種依賴關系限制了靈活性并最終限制了複用性。優先使用對象的合成/聚合有助于你保持每個類被封裝,并被擊中在單個任務上。這樣類和類的繼承層次會保持較小的規模,并且不太可能增長為不可控制的龐然大物。我們應該學會用對象的職責考慮問題,而不是結構。繼承是一種強耦合的結構,父類變了,子類就必須要變。是以我們在用繼承時,一定要在是“is-a”的關系時再考慮使用,而不是任何時候都去使用。

靈活開發原則:不要為代碼添加基于猜測的,實際不需要的功能。如果不清楚一個系統是否需要指令模式,一般就不要急着去實作它,事實上,在需要的時候通過重構實作這個模式并不困難,隻有在真正需要撤銷/恢複操作功能時,把原來的代碼重構為指令模式才有意義。

接口隔離原則:用戶端不應該依賴它不需要的接口;一個類對另一個類的依賴應該建立在最小的接口上。

用戶端程式類:調用功能程式類來獲得某種功能的類。一個整體的應用程式需要調用相同的功能程式類的地方會不止一個,意思是說存在多個調用相同的功能程式類的用戶端程式類。

功能程式類:被用戶端程式類或其他功能程式類調用的類,它封裝了業務邏輯,提供現某種特定的功能(或者說服務)。

可維護性: 需求變動時,隻需修改需要修改的地方,需要修改的地方越少,就表明可維護性越好。

可複用性:寫好的功能程式類并非隻能在一個應用程式裡使用,所有需要該功能程式類所提供的功能的地方都可以友善地調用該功能程式類,這就是可複用性。

可擴充性:當需要新增功能時,隻需另外編寫好新的功能類,然後在需要該功能的地方調用它就行了。

靈活性(多态性):能夠靈活地切換底層實作的技術,通過繼承和多态來實作,變量的聲明類型是抽象類或者接口,即面向抽象程式設計(面向接口程式設計)。

我們寫的代碼,應具有良好的可維護性、可複用性、可擴充性以及靈活性,要想編寫出擁有這些特性,就要求針對不同的應用情景靈活使用  面向對象的抽象、封裝、繼承、多态四大特性的最佳展現者——設計模式來編寫代碼。這一切的目的就是——在需求變動時,将我們改動的地方降低到最少,花最少的時間、代價來在原有的代碼基礎上實作變動了的需求。

關于為什麼對類的屬性加private修飾符,然後再提供對應的public get、set方法來通路和修改它。原因是:對于對外界公開的資料,我們通常希望能做更多的控制,即我們可以在通路或者修改屬性值時做一些限制(或者說控制)。下面的代碼示例是C#。

軟體的一些概念解釋
軟體的一些概念解釋
軟體的一些概念解釋

繼續閱讀