軟件工程-個人閱讀作業 #2


項目 內容
這個作業屬於哪個課程 2021春季軟件工程(羅傑 任健)
這個作業的要求在哪里 個人閱讀作業#2
我在這個課程的目標是 掌握並實踐利用軟件工程方法構建大規模高質量應用的技術,提升自身工程能力
這個作業在哪個具體方面幫助我實現目標 了解軟件開發過程中可能遇到的各個方面的問題,嘗試CI/CD等新型構建管理方式

Part 1: 《構建之法》閱讀中的問題

Q1:敏捷開發在大型項目中的應用

書中提到關於敏捷開發的知識。在中小型的軟件項目中,這些技巧可以非常好的提高開發效率,但是在大型軟件的開發過程中,人員數量規模巨大,經常會出現開發者跨地區、跨時區工作的特性。這樣,敏捷開發提倡的“交流”幾乎無法實行。即使通過切分,將應用切分成為一個一個的小模塊,但在一個復雜的系統中,各個小模塊之間必然有着大量相互重疊的部分。在這樣成規模的項目中,敏捷開發又應當如何應用呢。

Q2:關於goto語句的使用

作者提出:

函數最好有單一的出口,為了達到這一目的,可以使用goto

我在這點上與作者有一定的不同認知。根據我學習的經驗和網上查到的資料,goto語句在正常的程序中基本上是絕對不能使用的。在我個人的實踐中,也盡量避免采用goto語句。

性能方面的影響其實不大,主要是可讀性方面的問題,goto語句會極大的打亂程序結構性,大大提高閱讀代碼的開銷。作者顯然是知道這一問題的,但是提出,為了滿足單一出口原則,可以適當的妥協,允許這種情況下goto的使用。所謂的單一出口原則,出自《重構——改善既有代碼的設計》這本書,講的是一個函數最好只有一個return語句。這樣做有一定道理,可以使程序員一目了然程序的出口和返回值的來源。但是,近年來,這一原則也在受到質疑,如這篇博客中提到《The Art of Readable Code》中就對這一原則提出了批評。而在個人實踐的經驗中,很多時候不遵守單一出口原則(例:函數開頭判斷參數非法直接退出)能更好的提高代碼可讀/可維護性。

從我的角度來看,一切規范都是服務於開發效率的。因此,從代碼可讀性出發考慮,我們需要比較單一出口帶來的收益和goto語句帶來的負面效果。單一出口不是萬能靈葯,比如對於罕見錯誤情況處理時,早早退出是一個好選擇。事實上,這正是書中goto語句的用法示例。在我個人看來,此時放棄單一出口原則是比引入goto更好的做法。而且,近年來出現的新型語言都引入了專門的錯誤處理機制,通過精心設計的機制,可以更好地完成錯誤處理的功能,因此在一些新語言中,goto語句的用處進一步降低,甚至直接從語言本身就沒有goto語句。

當然,一切都是從可讀性/可維護性的角度出發,因此如果使用goto能提高可讀性,仍然可以使用。具體而言,我認為有以下規則:

  • 只有在需要錯誤處理而語言本身沒有提供錯誤處理功能的情況下使用goto語句

Q3:關於類的使用

作者提出:

僅在必要時,才使用“類”

在OO課程的學習中,我接觸了Java。Java的一個重要思想就是,“一切都是對象”。有對象,就必然有類,Java作為純粹的面向對象語言,非常鼓勵程序員對類的使用。因此,我對此有一定疑問。

我目前認為,作者針對的語言主要是C++,這方面的差異可能是不同編程范式的差異。但是我查詢資料,發現C++屬於一門多范式語言,自然也支持面向對象編程。此外,盡管作為編譯型語言,C++針對類和對象的支持不如Java自然,但是C++有RTTI,虛函數,虛基類等多種不同的方法實現運行時類型,只要選擇合適的方法,開銷都能控制在可以接受的范圍內。

我目前的猜測,一是在多范式編程中,面向對象模式與其他對象模式有一定的不兼容之處(但是是什么呢?),二是純粹的開銷方面原因。但我仍覺得不足以完全解釋這一問題,因此在此提出希望與大家討論。

Q4:關於多人合作中的代碼同步問題

書中11.5.4中提到了代碼簽入過程中的種種沖突問題,最后給出的解決方案是對不同的代碼實行不同的規則和流程控制,並給出了例子。但是,我仍然沒能看出來這樣如何解決了問題。在我的開發實踐中,我曾見過兩位同學針對4個issue同時對代碼進行修改,然后merge沖突,花費了很長時間,經歷多次merge/rebase才成功合並。這還僅僅是兩位同學,發現問題后一起合並的結果。在軟件公司,一份代碼同時修改的人相比更多,沖突也更多。我覺得即使如書中一樣限定在一個固定的時間段簽入代碼,仍然會發生沖突。

我目前能想到的解決辦法就是,將構建過程自動化,只允許能通過構建的代碼簽入。這樣可以保證簽入不會導致構建失敗,可以省去“合並版本后構建並測試”的時間,減少沖突的可能性。但是這並沒有解決代碼沖突頻繁的問題,且在項目工程龐大的情況下,自動構建和測試也要花費大量的算力和時間,因此希望與大家討論。

Q5:Beta期間,修復Bug的門檻要逐漸提高

書中提到

在Beta測試期間,修復Bug的門檻要逐漸提高

我對此存在疑惑,一個軟件進入Beta階段,應該是一個逐漸穩定的階段。這種情況下,程序的Bug數應當類似於一段下降曲線,影響巨大的Bug應該會越來越少,在這種情況下,不應該正好有更多的時間修復小Bug,來提升如軟件的細節么。書中指出是為了穩定性,避免頻繁改動代碼而引來新的Bug,但是對代碼的修改都有可能引入Bug。一般來說,嚴重的Bug修復所需的改動更多,而小Bug所需的改動更小,帶來Bug的可能性也相對有多少之分。因此,我對此條准則有一定的懷疑,希望與大家一起討論。

Part2:源代碼版本管理軟件調研

2.1 三大源代碼版本管理軟件相同之處

  • 都使用git這一源代碼管理系統
  • 都不同程度的支持權限管理、項目計划、在線基本編輯能力、代碼質量監測、代碼安全管理、持續集成和審計功能
  • 都支持通過第三方服務擴展功能

2.1 三大源代碼版本管理工具特色

  • Github:托管了大量開源項目和代碼片段(gist),有較完整的社區功能,用戶基數最大
  • BitBucket:可方便的與Atlassian公司的其他效率軟件(如Jira)配合使用,支持無限的免費私有倉庫
  • GitLab:本身開放源代碼,可以自行部署。對持續集成等操作支持相對較早也較完善

Part3:調研持續集成/部署工具

3.1 GitLab CI

采用我在數據庫大作業中的前端項目作為實驗項目,配置GitLab CI/CD,自動進行語法檢查,語法檢查通過后自動build並將結果打包成artifact以供下載

項目地址

image
image

看圖可知此人沒有外接顯示器(

對應的.gitlab-ci.yml文件如下

image: node:alpine

stages:
    - lint
    - build

cache:
    paths:
      - node_modules

lint 1/2:
    stage: lint
    script:
        - echo "Test Lint"

lint 2/2:
    stage: lint
    script:
        - npm install
        - npm run lint

build_dist:
    stage: build
    script:
        - npm install
        - npm run build
        - apk add zip
        - zip dist.zip -r ./dist
    artifacts:
        paths:
            - dist.zip
        expire_in: 1 week

3.2 GitHub Actions

同樣采用我在數據庫大作業中的前端項目作為實驗項目,配置GitHub Action,自動進行語法檢查,語法檢查通過后自動build並將結果打包成zip文件,然后利用社區市場提供的ncipollo/release-action@v1自動生成Release。

項目地址

image
image

對應配置文件如下

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. 
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  lint:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a single command using the runners shell
      - name: Install Dependencies
        run: npm install
      - name: lint
        run: npm run lint
        
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Runs a single command using the runners shell
      - name: Install Dependencies
        run: npm install
      - name: Build
        run: npm run build
      - name: Zip
        run: zip dist.zip -r ./dist
      
      - name: Release file
        uses: ncipollo/release-action@v1
        with:
          artifacts: "dist.zip"
          body: Release ID ${{github.run_id}}
          token: ${{ secrets.GITHUB_TOKEN }}
          # Name of Release to add file to
          tag: ${{github.run_id}}

簡單Actions使用介紹:

image

image

image

image

image

3.3 總結

無論是GitLab CI/CD還是Github Actions,都提供了相當方便的持續集成、持續部署功能。通過自動化代碼提交后的一套流程,可以有效地提高開發的質量,減輕手動作業的負擔。

在使用過程中明顯可以看出,GitLab CI/CD對流水線的管理要更加順暢,包括各階段的定義和階段之間的依賴關系,而Github Actions則顯得略微繁瑣。同時。GitLab CI/CD的runner可以以多種方式靈活配置,而Github Actions就顯得不那么靈活。但是,Github Actions提供了大量社區插件,可以輕松地完成一些常見任務,對於中小型項目來說可以極大的提高效率、

總而言之,GitLab CI/CD更加靈活,更適合商業化使用。而Github Actions則易於上手,可以在中小型項目中方便的應用。

參考文獻

  1. 《構建之法——現代軟件工程》,鄒欣,人民郵電出版社,第三版.
  2. 單一出口原則 Peter87
  3. https://about.gitlab.com/devops-tools/github-vs-gitlab/
  4. https://about.gitlab.com/devops-tools/bitbucket-vs-gitlab/
  5. https://docs.gitlab.com/ee/ci/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM