【軟工】【軟體工程基礎知識】【第一版】

yyyyfly發表於2022-04-09

軟體工程基本概念

軟體工程的目標與常用模型

  1. 軟體工程的目標:提高軟體的質量與生產率,最終實現軟體工業化生產
  2. 軟體工程的主要環節【軟工】【軟體工程基礎知識】【第一版】
  3. 軟體工程的線性模型【軟工】【軟體工程基礎知識】【第一版】
  4. 線性模型又稱瀑布模型,但是太過理想化,抗風險能力太弱了,偶爾被提起也是屬於被貶物件
  5. 但應該認識到線性思維確實人們最容易掌握的思想方法,遇到非線性問題時,人們總是想盡辦法轉換成線性問題,因此儘管線性模型被拋棄了,但是線性思維仍然需要領會
  6. 對於一個優秀的程式設計師不能總是套用固定的模型,例如程式設計不是總是先設計後測試,往往是把測試分為同步測試和總測試,即邊做邊測試,最後再測試

軟體開發的基本策略

  1. 複用,文人簡稱為拿來主義,即過去做對的東西要保留下來,筆者也是因為這個原因針對部落格推行版本更新,成果積累制度,不然每次都要從頭再來這個效率就太低了
  2. 物件導向的口頭禪:不要發明相同的車輪子
  3. 軟構件:將具有一定整合度並可以重複使用的軟體組成單元
  4. 軟體複用可以表述為:構造新的軟體系統可以不必每次從零做起,直接使用已有的軟構件,即可組裝(或加以合理修改)成新的系統
  5. 軟體複用有可能從別人那裡拿來,就有可能從自己這裡被拿去,因此必須要保證方便
  6. 利用軟構件生產應用軟體的過程【軟工】【軟體工程基礎知識】【第一版】
  7. 分而治之:即一塊蛋糕一口吃不下,分成幾塊來吃【軟工】【軟體工程基礎知識】【第一版】
  8. 軟體人員執行分為治之時應當考慮:複雜問題分解後能否用程式實現,最後組成一個軟體系統解決複雜原始的問題
  9. 優化:軟體的優化是指優化軟體的各個質量因素,如提高執行速度,提高對記憶體資源的利用率,使使用者介面更加友好,使三維圖形的真實感更強等等。就好比造武器,火力總是走向又猛又輕巧
  10. 但是優化並不一定要把事情做好,因為軟體之間總是存在千絲萬縷的聯絡,往往牽一髮而動全身,不能所有的目標都得到優化的時候,就需要折中
  11. 折中策略筆者的理解就是集體主義往往比個人英雄主義強,我們必須要考慮到整體的優化,不能執著於某一個地方過於加強,但是折中不能濫用,否則容易造成拖鞋,這是兩回事情

不正確的觀念

觀念之一:我們擁有一套講述如何開發軟體的書籍,書中充滿了標準與示例,可以幫助我們解決軟體開發中遇到的任何問題。

客觀情況:好的參考書無疑能指導我們的工作。充分利用書籍中的方法、技術和技巧,可以有效地解決軟體開發中大量常見的問題。但實踐者並不能因此依賴於書籍,這是因為:

(1)現實的工作中,由於條件千差萬別,即使是相當成熟的軟體工程規範,常常也無法套用。

(2)軟體技術日新月異,沒有哪一種軟體標準能長盛不衰。祖傳祕方在某些領域很吃香,而在軟體領域則意味著落後。

觀念之二:我們擁有最好的開發工具、最好的計算機,一定能做出優秀的軟體。

客觀情況:良好的開發環境只是產出成果的必要條件,而不是充分條件。如果擁有好環境的是一群庸人,難保他們不幹出南轅北轍的事情。正所謂往往學渣文具多

觀念之三:如果我們落後於計劃,可以增加更多的程式設計師來解決。

客觀情況:軟體開發不同於傳統的農業生產,人多不見得力量大。如果給落後於計劃的專案增添新手,可能會更加延誤專案。因為:

(1)新手會產生很多新的錯誤,使專案混亂。

(2)老手向新手解釋工作以及交流思想都要花費時間,使實際開發時間更少。所以科學的專案計劃很重要,不在乎計劃能提前多少,重在恰如其分。

觀念之四:既然需求分析很困難,不管三七二十一先把軟體做了再說,反正軟體是靈活的,隨時可以修改。

客觀情況:對需求把握得越準確,軟體的修修補補就越少。有些需求在一開始時很難確定,在開發過程中要不斷地加以改正。軟體修改越早代價越少,修改越晚代價越大,就跟治病一樣道理。

爭議性觀點

爭議之一:如果軟體執行較慢,是換一臺更快的計算機,還是設計一種更快的演算法?

參考觀點:如果開發軟體的目的是為了學習或是研究,那麼應該設計一種更快的演算法。如果該軟體已經用於商業,則需謹慎考慮:若換一臺更快的計算機能解決問題,則是最快的解決方案。改進演算法雖然可以從根本上提高軟體的執行速度,但可能引入錯誤以及延誤程式。技術狂毫無疑問會選擇後者,因為他們覺得放棄任何可以優化的機會就等於犯罪。

類似的爭議還有:是買現成的程式,還是徹底自己開發?技術人員和商業人士常常會有不同的選擇。

 

爭議之二:有最好的軟體工程方法,最好的程式語言嗎?

參考觀點:在軟體領域永遠沒有最好的,只有更好的。能解決問題的都是好方法或是好語言。程式設計師在最初學習 Basic、Fortran、 Pascal、C、C++等語言時會感覺一個比一個好,不免有喜新厭舊之舉。而如今的 Visual Basic、Delphi、Visual C++、Java 等語言各有所長,真的難分優劣。開發人員應該根據客觀條件,選擇自己熟悉的方法和語言,才能保證合格的質量與生產率。

程式設計是自由與快樂的事情,不要發誓忠於某某主義而自尋煩惱。

 

爭議之三:程式設計時是否應該多使用技巧?

參考觀點:就軟體開發而言,技巧的優點在於能另闢蹊徑地解決一些問題,缺點是技巧並不為人熟知。若在程式中用太多的技巧,可能會留下隱患,別人也難以理解程式。鑑於一個區域性的優點對整個系統而言是微不足道的,而一個錯誤則可能是致命的。作者建議用自然的方式程式設計,少用技巧。

 

爭議之四:軟體中的錯誤是否可按嚴重程度分等級?

參考觀點:在定量分析時,可以將錯誤分等級,以便於管理。微軟的一些開發小組將錯誤分成四個等級

一級嚴重:錯誤導致軟體崩潰。

二級嚴重:錯誤導致一個特性不能執行並且沒有替代方案。

三級嚴重:錯誤導致一個特性不能執行但有替代方案。

四級嚴重:錯誤是表面化的或是微小的。

可行性研究

  1. 可行性分析是要決定“做還是不做”。需求分析是要決定“做什麼,不做什麼”。
  2. 即使可行性分析是客觀的、科學的,但決策仍有可能是錯誤的。因為決策者是人,人會衝動,有賭博心態。
  3. 經濟【有沒有錢賺】
    1. 成本收益分析:
      1. 人都是無利不起早的,大家參加工作不可能用愛發電,所以收益是第一位的
      2. 如果是為客戶做軟體專案,那麼收益就寫在合同中。如果是做自己的軟體產品,那麼收益就是銷售額
      3. 如果做的是小本生意,那可得對成本進行細算。軟體的成本不是指存放軟體的那張光碟的成本,而是指開發成本。
    1. 經濟——短期長遠利益分析
  1. 技術【做得了嗎?做得好嗎?做得快嗎?】
    1. 在給定的時間內能否實現需求說明中的功能。如果在專案開發過程中遇到難以克服的技術問題,麻煩就大了。輕則拖延進度,重則斷送專案。
    2. 軟體的質量如何?有些應用對實時性要求很高,如果軟體執行慢如蝸牛,即便功能具備也毫無實用價值。有些高風險的應用對軟體的正確性與精確性要求極高,如果軟體出了差錯而造成客戶利益損失,那麼軟體開發方可要賠慘了。
    3. 軟體的生產率如何?如果生產率低下,能賺到的錢就少,並且會逐漸喪失競爭力。在統計軟體總的開發時間時,不能漏掉用於維護的時間。軟體維護是非常拖後腿的事,它能把前期拿到的利潤慢慢地消耗光。如果軟體的質量不好,將會導致維護的代價很高,企圖通過偷工減料而提高生產率,是得不償失的事。
  1. 社會環境【有沒有人用】社會環境的可行性至少包括兩種因素:市場與政策。

需求分析

需求分析的困難

  1. 客戶說不清楚需求:有些客戶對需求只有朦朧的感覺,當然說不清楚具體的需求。筆者過去發現一家外包公司對接過一家律所,因為律所的老闆怎麼都說不清楚,導致了一個僅僅是校園畢設的技術專案,做了三年沒做完
  2. 需求自身經常變動:據歷史記載,沒有一個軟體的需求改動少於三次。唯一隻改動需求兩次的客戶是個死人。這個可憐的傢伙還是在運送第三次需求的路上被車子撞死的,但是辦法總比問題多,可以提供以下幾種解決方案
    1. 看清楚合同,避免曖昧的說法
    2. 儘量把軟體設計成可變動性比較強的,最極端的就是超能陸戰隊裡的微型機器人,無論什麼東西都能拼出來,雖然這不可能
    3. 儘可能地分析清楚哪些是穩定的需求,哪些是易變的需求。以便在進行系統設計時,將軟體的核心建築在穩定的需求上,否則將會吃盡苦頭
  1. 分析人員和客戶理解有誤,程式設計師往往理科強,文科弱,筆者接觸的很多程式設計師連基本的話都說不清楚,因此技術和自然語言上的鴻溝就很難彌補

如何進行需求分析

  1. 兩個核心問題開展需求分析:(1)應該瞭解什麼?(2)通過什麼方式去了解?
  2. 應該瞭解什麼
    1. 【軟工】【軟體工程基礎知識】【第一版】
    2. 最好為每個需求註釋“為什麼”,這樣可讓程式設計師瞭解需求的本質,以便選用最合適的技術來實現此需求。
    3. 需求說明不可有二義性,更不能前後相矛盾。如果有二義性或前後相矛盾,則要重新分析此需求。
  1. 通過什麼方式去了解
    1. 直接與客戶交談。如果分析人員生有足球評論員的那張“大嘴”,就非常容易侃出需求。
    2. 有些需求客戶講不清楚,分析人員又猜不透,這時就要請教行家。有些高手真的很厲害,你還沒有開始問,他就能講出前因後果。讓你感到“聽君一席言,勝讀十年書。”這裡筆者忍不住要吹牛了,因為筆者參與過和律所對接的業務,由於筆者通過了法律職業資格證照,所以對於法律業務的軟體開發易如反掌
    3. 有很多需求可能客戶與分析人員想都沒有想過,或者想得太幼稚。要經常分析優秀的和蹩腳的同類軟體,看到了優點就儘量吸取,看到了缺點就引以為戒。前人既然付了學費,後人就不要拒絕坐享其成。

系統設計

  1. ppt畫完了當然就要動手啦,系統設計是把需求轉換為軟體系統最重要的環節
  2. 系統設計一共有四個方面:體系結構,模組結構,資料結構與演算法,使用者介面
    1. 系統結構相當於骨架
    2. 模組結構相當於人體器官
    3. 資料結構與演算法相當於血脈和神經【所以同學們明白為什麼面試對演算法要求這麼高了嗎,因為少個器官或許還不一定有大事,但是少跟神經那就麻煩大啦】
    4. 使用者介面相當於人的外表

體系結構設計

  1. 體系結構是軟體系統中最本質的東西
    1. 體系結構是對複雜事物的一種抽象。良好的體系結構是普遍適用的,它可以高效地處理多種多樣的個體需求。
    2. 體系結構在一定的時間內保持穩定。
  1. 層次結構:有些事情比較複雜,我們沒法一口氣幹完,就把事情分為好幾層,一層一層地去做。高層的工作總是建立在低層的工作之上。層次關係主要有兩種:上下級關係和順序相鄰關係
    1. 上下級關係的層次結構:上層子系統可以使用下層子系統的功能,而下層子系統不能夠使用上層子系統的功能
    2. 順序相鄰關係的層次結構:順序相鄰關係的層次結構表明通訊只能在相鄰兩層之間發生,資訊只能被一層一層地順序傳遞
    3. 其他層次結構
  1. 客戶機/ 伺服器結構
    1. 以集中的方式高效率地管理通訊。前面講電話系統的故事就是要說明這一點。
    2. 可以共享資源。比如在資訊管理系統中,伺服器將資訊集中起來,任何客戶機都可以通過訪問伺服器而獲得所需的資訊。

模組設計

  1. 評價模組設計優劣的三個特徵因素:“資訊隱藏”、“內聚與耦合”和“封閉——開放性
  2. 資訊隱藏
    1. 如果不想讓壞事傳播開來,就應該把壞事隱藏起來,“家醜不可外揚”就是這個道理
    2. 模組的資訊隱藏可以通過介面設計來實現。
  1. 內聚耦合【內聚耦合翻譯過來就是反連坐制度,一個人出問題不影響周圍的鄰居】
    1. 內聚強度
      1. 偶然內聚。如果一個模組的各成分之間毫無關係,則稱為偶然內聚。
      2. 邏輯內聚。幾個邏輯上相關的功能被放在同一模組中,則稱為邏輯內聚。如一個模組讀取各種不同型別外設的輸入。儘管邏輯內聚比偶然內聚合理一些,但邏輯內聚的模組各成分在功能上並無關係,即使區域性功能的修改有時也會影響全域性,因此這類模組的修改也比較困難。
      3. 時間內聚。如果一個模組完成的功能必須在同一時間內執行(如系統初始化),但這些功能只是因為時間因素關聯在一起,則稱為時間內聚。
      4. 過程內聚。如果一個模組內部的處理成分是相關的,而且這些處理必須以特定的次序執行,則稱為過程內聚。
      5. 通訊內聚。如果一個模組的所有成分都操作同一資料集或生成同一資料集,則稱為通訊內聚。
      6. 順序內聚。如果一個模組的各個成分和同一個功能密切相關,而且一個成分的輸出作為另一個成分的輸入,則稱為順序內聚。
      7. 功能內聚。模組的所有成分對於完成單一的功能都是必須的,則稱為功能內聚。
    1. 耦合強度:依賴於以下幾個因素耦合的強度依賴於以下幾個因素:一個模組對另一個模組的呼叫;一個模組向另一個模組傳遞的資料量;一個模組施加到另一個模組的控制的多少;模組之間介面的複雜程度。耦合按從強到弱的順序可分為以下幾種型別
      1. 內容耦合。當一個模組直接修改或操作另一個模組的資料,或者直接轉入另一個模組時,就發生了內容耦合。此時,被修改的模組完全依賴於修改它的模組。
      2. 公共耦合。兩個以上的模組共同引用一個全域性資料項就稱為公共耦合。
      3. 控制耦合。一個模組在介面上傳遞一個訊號(如開關值、標誌量等)控制另一個模組,接收訊號的模組的動作根據訊號值進行調整,稱為控制耦合。
      4. 標記耦合。模組間通過引數傳遞複雜的內部資料結構,稱為標記耦合。此資料結構的變化將使相關的模組發生變化。
      5. 資料耦合。模組間通過引數傳遞基本型別的資料,稱為資料耦合。
      6. 非直接耦合。模組間沒有資訊傳遞時,屬於非直接耦合。如果模組間必須存在耦合,就儘量使用資料耦合,少用控制耦合,限制公共耦合的範圍,堅決避免使用內容耦合。
  1. 封閉開放性:如果一個模組可以作為一個獨立體被其它程式引用,則稱模組具有封閉性。如果一個模組可以被擴充,則稱模組具有開放性。

資料結構演算法設計

  1. 該部分內容想必對於經常刷演算法題的同學來說已經爛熟於心,因此不做過多解釋
  2. 對於這部分內容不熟練的同學請去刷leetcode官網多刷題

使用者介面設計

  1. 這部分內容就是我們平常看到的介面,如果太難看的程式往往我們就沒有用下去的想法,正所謂人要衣裝,佛要金裝,這讓筆者想起了學校的教務系統,怎一個爛字了得
  2. 這裡其實和程式設計師的關係聯絡就稍微少一些了,更多的是美學,因此同學們千萬不要沉迷於程式設計對其他事物充耳不聞,據說愛因斯坦身為科學家對藝術有著很高的研究,怎麼樣是不是顛覆了同學們的認知,在這裡只簡單介紹介面美相對有三個方面
    1. 介面核實性
    2. 介面的風格
    3. 介面的廣義美

編碼與測試

  1. 這裡就來到了所有開發者最討厭的地方,因為這個組別的同學總能給你挑出刺來,這讓筆者想起了大學做課設的時候有一個划水的舍友,啥都沒幹,就去做測試,結果偏偏同樣的資料經過筆者的手沒問題,經過他的手就會爆炸,真是想把他千刀萬剮
  2. 測試的目的:儘可能發現多的缺陷,言下之意一個挑不出缺陷的程式反而是有問題的,也永遠不可能做出沒有缺陷的程式,因此開發和測試總是相愛相殺【聽說測試組女生偏多,因為程式設計師社交圈小,所以開發和測試跑多了往往最後結婚了,還好筆者在大學就早早破圈了,認識不少文科妹子】
  3. 測試有助於提高軟體的質量,但是提高軟體的質量不能依賴於測試,就好像我們是先會做題再檢查,但是白卷怎麼檢查呢,軟體的高質量是設計出來的,而不是靠測試修補出來的

維護

維護的嘗試

  1. 任何東西用多了總會磨損,所以為了減少這方面的工作,同學們所做的程式要儘可能耐操,要沙漠能用,沼澤能用,太空能用,熱帶能用,寒帶能用【開個玩笑哈】
  2. 一些學者將軟體維護劃分為主要的三類
    1. 糾錯性維護。由於前期的測試不可能揭露軟體系統中所有替在的錯誤,使用者在使用軟體時仍將會遇到錯誤,診斷和改正這些錯誤的過程稱為糾錯性維護。
    2. 適應性維護。由於新的硬體裝置不斷推出,作業系統和編譯系統也不斷地升級,為了使軟體能適應新的環境而引起的程式修改和擴充活動稱為適應性維護。
    3. 完善性維護。在軟體的正常使用過程中,使用者還會不斷提出新的需求。為了滿足使用者新的需求而增加軟體功能的活動稱為完善性維護。

維護的代價及其主要因素

  1. 非技術因素
    1. 應用域的複雜性。如果應用域問題已被很好地理解,需求分析工作比較完善,那麼維護代價就較低。反之維護代價就較高。
    2. 開發人員的穩定性。如果某些程式的開發者還在,讓他們對自己的程式進行維護,那麼代價就較低。如果原來的開發者已經不在,只好讓新手來維護陌生的程式,那麼代價就較高。
    3. 軟體的生命期。越是早期的程式越難維護,你很難想像十年前的程式是多麼的落後(設計思想與開發工具都落後)。一般地,軟體的生命期越長,維護代價就越高。生命期越短,維護代價就越低。
    4. 商業操作模式變化對軟體的影響。比如財務軟體,對財務制度的變化很敏感。財務制度一變動,財務軟體就必須修改。一般地,商業操作模式變化越頻繁,相應軟體的維護代價就越高。
  1. 技術因素
    1. 軟體對執行環境的依賴性。由於硬體以及作業系統更新很快,使得對執行環境依賴性很強的應用軟體也要不停地更新,維護代價就高。
    2. 程式語言。雖然低階語言比高階語言具有更好的執行速度,但是低階語言比高階語言難以理解。用高階語言編寫的程式比用低階語言編寫的程式的維護代價要低得多(並且生產率高得多)。一般地,商業應用軟體大多采用高階語言。比如,開發一套Windows 環境下的資訊管理系統,使用者大多采用 Visual Basic、Delphi 或 Power Builder來程式設計,用 Visual C++的就少些,沒有人會採用組合語言。
    3. 程式設計風格。良好的程式設計風格意味著良好的可理解性,可以降低維護的代價。
    4. 測試與改錯工作。如果測試與改錯工作做得好,後期的維護代價就能降低。反之維護代價就升高。
    5. 文件的質量。清晰、正確和完備的文件能降低維護的代價。低質量的文件將增加維護的代價(錯誤百出的文件還不如沒有文件)。

相關文章