軟體工程基本概念
軟體工程的目標與常用模型
- 軟體工程的目標:提高軟體的質量與生產率,最終實作軟體工業化生產
- 軟體工程的主要環節

- 軟體工程的線性模型

- 線性模型又稱瀑布模型,但是太過理想化,抗風險能力太弱了,偶爾被提起也是屬于被貶物件
- 但應該認識到線性思維確實人們最容易掌握的思想方法,遇到非線性問題時,人們總是想盡辦法轉換成線性問題,因此盡管線性模型被拋棄了,但是線性思維仍然需要領會
- 對于一個優秀的程式員不能總是套用固定的模型,例如程式設計不是總是先設計后測驗,往往是把測驗分為同步測驗和總測驗,即邊做邊測驗,最后再測驗
軟體開發的基本策略
- 復用,文人簡稱為拿來主義,即過去做對的東西要保留下來,筆者也是因為這個原因針對博客推行版本更新,成果積累制度,不然每次都要從頭再來這個效率就太低了
- 面向物件的口頭禪:不要發明相同的車輪子
- 軟構件:將具有一定集成度并可以重復使用的軟體組成單元
- 軟體復用可以表述為:構造新的軟體系統可以不必每次從零做起,直接使用已有的軟構件,即可組裝(或加以合理修改)成新的系統
- 軟體復用有可能從別人那里拿來,就有可能從自己這里被拿去,因此必須要保證方便
- 利用軟構件生產應用軟體的程序

- 分而治之:即一塊蛋糕一口吃不下,分成幾塊來吃

- 軟體人員執行分為治之時應當考慮:復雜問題分解后能否用程式實作,最后組成一個軟體系統解決復雜原始的問題
- 優化:軟體的優化是指優化軟體的各個質量因素,如提高運行速度,提高對記憶體資源的利用率,使用戶界面更加友好,使三維圖形的真實感更強等等,就好比造武器,火力總是走向又猛又輕巧
- 但是優化并不一定要把事情做好,因為軟體之間總是存在千絲萬縷的聯系,往往牽一發而動全身,不能所有的目標都得到優化的時候,就需要折中
- 折中策略筆者的理解就是集體主義往往比個人英雄主義強,我們必須要考慮到整體的優化,不能執著于某一個地方過于加強,但是折中不能濫用,否則容易造成拖鞋,這是兩回事情
不正確的觀念
觀念之一:我們擁有一套講述如何開發軟體的書籍,書中充滿了標準與示例,可以幫助我們解決軟體開發中遇到的任何問題,
客觀情況:好的參考書無疑能指導我們的作業,充分利用書籍中的方法、技術和技巧,可以有效地解決軟體開發中大量常見的問題,但實踐者并不能因此依賴于書籍,這是因為:
(1)現實的作業中,由于條件千差萬別,即使是相當成熟的軟體工程規范,常常也無法套用,
(2)軟體技術日新月異,沒有哪一種軟體標準能長盛不衰,祖傳秘方在某些領域很吃香,而在軟體領域則意味著落后,
觀念之二:我們擁有最好的開發工具、最好的計算機,一定能做出優秀的軟體,
客觀情況:良好的開發環境只是產出成果的必要條件,而不是充分條件,如果擁有好環境的是一群庸人,難保他們不干出南轅北轍的事情,正所謂往往學渣文具多
觀念之三:如果我們落后于計劃,可以增加更多的程式員來解決,
客觀情況:軟體開發不同于傳統的農業生產,人多不見得力量大,如果給落后于計劃的專案增添新手,可能會更加延誤專案,因為:
(1)新手會產生很多新的錯誤,使專案混亂,
(2)老手向新手解釋作業以及交流思想都要花費時間,使實際開發時間更少,所以科學的專案計劃很重要,不在乎計劃能提前多少,重在恰如其分,
觀念之四:既然需求分析很困難,不管三七二十一先把軟體做了再說,反正軟體是靈活的,隨時可以修改,
客觀情況:對需求把握得越準確,軟體的修修補補就越少,有些需求在一開始時很難確定,在開發程序中要不斷地加以改正,軟體修改越早代價越少,修改越晚代價越大,就跟治病一樣道理,
爭議性觀點
爭議之一:如果軟體運行較慢,是換一臺更快的計算機,還是設計一種更快的演算法?
參考觀點:如果開發軟體的目的是為了學習或是研究,那么應該設計一種更快的演算法,如果該軟體已經用于商業,則需謹慎考慮:若換一臺更快的計算機能解決問題,則是最快的解決方案,改進演算法雖然可以從根本上提高軟體的運行速度,但可能引入錯誤以及延誤行程,技術狂毫無疑問會選擇后者,因為他們覺得放棄任何可以優化的機會就等于犯罪,
類似的爭議還有:是買現成的程式,還是徹底自己開發?技術人員和商業人士常常會有不同的選擇,
爭議之二:有最好的軟體工程方法,最好的編程語言嗎?
參考觀點:在軟體領域永遠沒有最好的,只有更好的,能解決問題的都是好方法或是好語言,程式員在最初學習 Basic、Fortran、 Pascal、C、C++等語言時會感覺一個比一個好,不免有喜新厭舊之舉,而如今的 Visual Basic、Delphi、Visual C++、Java 等語言各有所長,真的難分優劣,開發人員應該根據客觀條件,選擇自己熟悉的方法和語言,才能保證合格的質量與生產率,
程式設計是自由與快樂的事情,不要發誓忠于某某主義而自尋煩惱,
爭議之三:編程時是否應該多使用技巧?
參考觀點:就軟體開發而言,技巧的優點在于能另辟蹊徑地解決一些問題,缺點是技巧并不為人熟知,若在程式中用太多的技巧,可能會留下隱患,別人也難以理解程式,鑒于一個區域的優點對整個系統而言是微不足道的,而一個錯誤則可能是致命的,作者建議用自然的方式編程,少用技巧,
爭議之四:軟體中的錯誤是否可按嚴重程度分等級?
參考觀點:在定量分析時,可以將錯誤分等級,以便于管理,微軟的一些開發小組將錯誤分成四個等級
一級嚴重:錯誤導致軟體崩潰,
二級嚴重:錯誤導致一個特性不能運行并且沒有替代方案,
三級嚴重:錯誤導致一個特性不能運行但有替代方案,
四級嚴重:錯誤是表面化的或是微小的,
可行性研究
- 可行性分析是要決定“做還是不做”,需求分析是要決定“做什么,不做什么”,
- 即使可行性分析是客觀的、科學的,但決策仍有可能是錯誤的,因為決策者是人,人會沖動,有賭博心態,
- 經濟【有沒有錢賺】
- 成本收益分析:
- 人都是無利不起早的,大家參加作業不可能用愛發電,所以收益是第一位的
- 如果是為客戶做軟體專案,那么收益就寫在合同中,如果是做自己的軟體產品,那么收益就是銷售額
- 如果做的是小本生意,那可得對成本進行細算,軟體的成本不是指存放軟體的那張光碟的成本,而是指開發成本,
- 經濟——短期長遠利益分析
- 技術【做得了嗎?做得好嗎?做得快嗎?】
- 在給定的時間內能否實作需求說明中的功能,如果在專案開發程序中遇到難以克服的技術問題,麻煩就大了,輕則拖延進度,重則斷送專案,
- 軟體的質量如何?有些應用對實時性要求很高,如果軟體運行慢如蝸牛,即便功能具備也毫無實用價值,有些高風險的應用對軟體的正確性與精確性要求極高,如果軟體出了差錯而造成客戶利益損失,那么軟體開發方可要賠慘了,
- 軟體的生產率如何?如果生產率低下,能賺到的錢就少,并且會逐漸喪失競爭力,在統計軟體總的開發時間時,不能漏掉用于維護的時間,軟體維護是非常拖后腿的事,它能把前期拿到的利潤慢慢地消耗光,如果軟體的質量不好,將會導致維護的代價很高,企圖通過偷工減料而提高生產率,是得不償失的事,
- 社會環境【有沒有人用】社會環境的可行性至少包括兩種因素:市場與政策,
需求分析
需求分析的困難
- 客戶說不清楚需求:有些客戶對需求只有朦朧的感覺,當然說不清楚具體的需求,筆者過去發現一家外包公司對接過一家律所,因為律所的老板怎么都說不清楚,導致了一個僅僅是校園畢設的技術專案,做了三年沒做完
- 需求自身經常變動:據歷史記載,沒有一個軟體的需求改動少于三次,唯一只改動需求兩次的客戶是個死人,這個可憐的家伙還是在運送第三次需求的路上被車子撞死的,但是辦法總比問題多,可以提供以下幾種解決方案
- 看清楚合同,避免曖昧的說法
- 盡量把軟體設計成可變動性比較強的,最極端的就是超能陸戰隊里的微型機器人,無論什么東西都能拼出來,雖然這不可能
- 盡可能地分析清楚哪些是穩定的需求,哪些是易變的需求,以便在進行系統設計時,將軟體的核心建筑在穩定的需求上,否則將會吃盡苦頭
- 分析人員和客戶理解有誤,程式員往往理科強,文科弱,筆者接觸的很多程式員連基本的話都說不清楚,因此技術和自然語言上的鴻溝就很難彌補
如何進行需求分析
- 兩個核心問題開展需求分析:(1)應該了解什么?(2)通過什么方式去了解?
- 應該了解什么

- 最好為每個需求注釋“為什么”,這樣可讓程式員了解需求的本質,以便選用最合適的技術來實作此需求,
- 需求說明不可有二義性,更不能前后相矛盾,如果有二義性或前后相矛盾,則要重新分析此需求,
- 通過什么方式去了解
- 直接與客戶交談,如果分析人員生有足球評論員的那張“大嘴”,就非常容易侃出需求,
- 有些需求客戶講不清楚,分析人員又猜不透,這時就要請教行家,有些高手真的很厲害,你還沒有開始問,他就能講出前因后果,讓你感到“聽君一席言,勝讀十年書,”這里筆者忍不住要吹牛了,因為筆者參與過和律所對接的業務,由于筆者通過了法律職業資格證書,所以對于法律業務的軟體開發易如反掌
- 有很多需求可能客戶與分析人員想都沒有想過,或者想得太幼稚,要經常分析優秀的和蹩腳的同類軟體,看到了優點就盡量吸取,看到了缺點就引以為戒,前人既然付了學費,后人就不要拒絕坐享其成,
系統設計
- ppt畫完了當然就要動手啦,系統設計是把需求轉換為軟體系統最重要的環節
- 系統設計一共有四個方面:體系結構,模塊結構,資料結構與演算法,用戶界面
- 系統結構相當于骨架
- 模塊結構相當于人體器官
- 資料結構與演算法相當于血脈和神經【所以同學們明白為什么面試對演算法要求這么高了嗎,因為少個器官或許還不一定有大事,但是少跟神經那就麻煩大啦】
- 用戶界面相當于人的外表
體系結構設計
- 體系結構是軟體系統中最本質的東西
- 體系結構是對復雜事物的一種抽象,良好的體系結構是普遍適用的,它可以高效地處理多種多樣的個體需求,
- 體系結構在一定的時間內保持穩定,
- 層次結構:有些事情比較復雜,我們沒法一口氣干完,就把事情分為好幾層,一層一層地去做,高層的作業總是建立在低層的作業之上,層次關系主要有兩種:上下級關系和順序相鄰關系
- 上下級關系的層次結構:上層子系統可以使用下層子系統的功能,而下層子系統不能夠使用上層子系統的功能
- 順序相鄰關系的層次結構:順序相鄰關系的層次結構表明通訊只能在相鄰兩層之間發生,資訊只能被一層一層地順序傳遞
- 其他層次結構
- 客戶機/ 服務器結構
- 以集中的方式高效率地管理通訊,前面講電話系統的故事就是要說明這一點,
- 可以共享資源,比如在資訊管理系統中,服務器將資訊集中起來,任何客戶機都可以通過訪問服務器而獲得所需的資訊,
模塊設計
- 評價模塊設計優劣的三個特征因素:“資訊隱藏”、“內聚與耦合”和“封閉——開放性
- 資訊隱藏
- 如果不想讓壞事傳播開來,就應該把壞事隱藏起來,“家丑不可外揚”就是這個道理
- 模塊的資訊隱藏可以通過介面設計來實作,
- 內聚耦合【內聚耦合翻譯過來就是反連坐制度,一個人出問題不影響周圍的鄰居】
- 內聚強度
- 偶然內聚,如果一個模塊的各成分之間毫無關系,則稱為偶然內聚,
- 邏輯內聚,幾個邏輯上相關的功能被放在同一模塊中,則稱為邏輯內聚,如一個模塊讀取各種不同型別外設的輸入,盡管邏輯內聚比偶然內聚合理一些,但邏輯內聚的模塊各成分在功能上并無關系,即使區域功能的修改有時也會影響全域,因此這類模塊的修改也比較困難,
- 時間內聚,如果一個模塊完成的功能必須在同一時間內執行(如系統初始化),但這些功能只是因為時間因素關聯在一起,則稱為時間內聚,
- 程序內聚,如果一個模塊內部的處理成分是相關的,而且這些處理必須以特定的次序執行,則稱為程序內聚,
- 通信內聚,如果一個模塊的所有成分都操作同一資料集或生成同一資料集,則稱為通信內聚,
- 順序內聚,如果一個模塊的各個成分和同一個功能密切相關,而且一個成分的輸出作為另一個成分的輸入,則稱為順序內聚,
- 功能內聚,模塊的所有成分對于完成單一的功能都是必須的,則稱為功能內聚,
- 耦合強度:依賴于以下幾個因素耦合的強度依賴于以下幾個因素:一個模塊對另一個模塊的呼叫;一個模塊向另一個模塊傳遞的資料量;一個模塊施加到另一個模塊的控制的多少;模塊之間介面的復雜程度,耦合按從強到弱的順序可分為以下幾種型別
- 內容耦合,當一個模塊直接修改或操作另一個模塊的資料,或者直接轉入另一個模塊時,就發生了內容耦合,此時,被修改的模塊完全依賴于修改它的模塊,
- 公共耦合,兩個以上的模塊共同參考一個全域資料項就稱為公共耦合,
- 控制耦合,一個模塊在界面上傳遞一個信號(如開關值、標志量等)控制另一個模塊,接收信號的模塊的動作根據信號值進行調整,稱為控制耦合,
- 標記耦合,模塊間通過引數傳遞復雜的內部資料結構,稱為標記耦合,此資料結構的變化將使相關的模塊發生變化,
- 資料耦合,模塊間通過引數傳遞基本型別的資料,稱為資料耦合,
- 非直接耦合,模塊間沒有資訊傳遞時,屬于非直接耦合,如果模塊間必須存在耦合,就盡量使用資料耦合,少用控制耦合,限制公共耦合的范圍,堅決避免使用內容耦合,
- 封閉開放性:如果一個模塊可以作為一個獨立體被其它程式參考,則稱模塊具有封閉性,如果一個模塊可以被擴充,則稱模塊具有開放性,
資料結構演算法設計
- 該部分內容想必對于經常刷演算法題的同學來說已經爛熟于心,因此不做過多解釋
- 對于這部分內容不熟練的同學請去刷leetcode官網多刷題
用戶界面設計
- 這部分內容就是我們平常看到的界面,如果太難看的程式往往我們就沒有用下去的想法,正所謂人要衣裝,佛要金裝,這讓筆者想起了學校的教務系統,怎一個爛字了得
- 這里其實和程式員的關系聯系就稍微少一些了,更多的是美學,因此同學們千萬不要沉迷于編程對其他事物充耳不聞,據說愛因斯坦身為科學家對藝術有著很高的研究,怎么樣是不是顛覆了同學們的認知,在這里只簡單介紹界面美相對有三個方面
- 界面核實性
- 界面的風格
- 界面的廣義美
編碼與測驗
- 這里就來到了所有開發者最討厭的地方,因為這個組別的同學總能給你挑出刺來,這讓筆者想起了大學做課設的時候有一個劃水的舍友,啥都沒干,就去做測驗,結果偏偏同樣的資料經過筆者的手沒問題,經過他的手就會爆炸,真是想把他千刀萬剮
- 測驗的目的:盡可能發現多的缺陷,言下之意一個挑不出缺陷的程式反而是有問題的,也永遠不可能做出沒有缺陷的程式,因此開發和測驗總是相愛相殺【聽說測驗組女生偏多,因為程式員社交圈小,所以開發和測驗跑多了往往最后結婚了,還好筆者在大學就早早破圈了,認識不少文科妹子】
- 測驗有助于提高軟體的質量,但是提高軟體的質量不能依賴于測驗,就好像我們是先會做題再檢查,但是白卷怎么檢查呢,軟體的高質量是設計出來的,而不是靠測驗修補出來的
維護
維護的嘗試
- 任何東西用多了總會磨損,所以為了減少這方面的作業,同學們所做的程式要盡可能耐操,要沙漠能用,沼澤能用,太空能用,熱帶能用,寒帶能用【開個玩笑哈】
- 一些學者將軟體維護劃分為主要的三類
- 糾錯性維護,由于前期的測驗不可能揭露軟體系統中所有替在的錯誤,用戶在使用軟體時仍將會遇到錯誤,診斷和改正這些錯誤的程序稱為糾錯性維護,
- 適應性維護,由于新的硬體設備不斷推出,作業系統和編譯系統也不斷地升級,為了使軟體能適應新的環境而引起的程式修改和擴充活動稱為適應性維護,
- 完善性維護,在軟體的正常使用程序中,用戶還會不斷提出新的需求,為了滿足用戶新的需求而增加軟體功能的活動稱為完善性維護,
維護的代價及其主要因素
- 非技術因素
- 應用域的復雜性,如果應用域問題已被很好地理解,需求分析作業比較完善,那么維護代價就較低,反之維護代價就較高,
- 開發人員的穩定性,如果某些程式的開發者還在,讓他們對自己的程式進行維護,那么代價就較低,如果原來的開發者已經不在,只好讓新手來維護陌生的程式,那么代價就較高,
- 軟體的生命期,越是早期的程式越難維護,你很難想像十年前的程式是多么的落后(設計思想與開發工具都落后),一般地,軟體的生命期越長,維護代價就越高,生命期越短,維護代價就越低,
- 商業操作模式變化對軟體的影響,比如財務軟體,對財務制度的變化很敏感,財務制度一變動,財務軟體就必須修改,一般地,商業操作模式變化越頻繁,相應軟體的維護代價就越高,
- 技術因素
-
- 軟體對運行環境的依賴性,由于硬體以及作業系統更新很快,使得對運行環境依賴性很強的應用軟體也要不停地更新,維護代價就高,
- 編程語言,雖然低級語言比高級語言具有更好的運行速度,但是低級語言比高級語言難以理解,用高級語言撰寫的程式比用低級語言撰寫的程式的維護代價要低得多(并且生產率高得多),一般地,商業應用軟體大多采用高級語言,比如,開發一套Windows 環境下的資訊管理系統,用戶大多采用 Visual Basic、Delphi 或 Power Builder來編程,用 Visual C++的就少些,沒有人會采用匯編語言,
- 編程風格,良好的編程風格意味著良好的可理解性,可以降低維護的代價,
- 測驗與改錯作業,如果測驗與改錯作業做得好,后期的維護代價就能降低,反之維護代價就升高,
- 檔案的質量,清晰、正確和完備的檔案能降低維護的代價,低質量的檔案將增加維護的代價(錯誤百出的檔案還不如沒有檔案),
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/457619.html
標籤:其他
