iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0

可維護的程式碼原則

我們有很多的方法可以用程式實現我們的功能,但作為一個工程師是否寫出可維護的程式碼在於自己,卻往往對於團隊有很大的影響。好的程式碼不會有績效,在下班之餘再去看 clean code 的 CP 值很低?也許像在 Side Project 就可以自由發揮,但為了未來的擴展性,以及為了實現我們都有一個想成為一個更好的工程師的願望。當然 Clean Code 的細節很多,我想主要分享在《Good Code, Bad Code》這本書裡提到的六個大原則。

  1. 讓程式碼可讀
  2. 避免意外的執行效果
  3. 讓程式不會被誤用
  4. 讓程式模組化
  5. 讓程式碼可複用和可泛化
  6. 讓程式碼可測試且能正確測試

此外,我想舉實際的例子,以下是我分別實現了拖曳功能的兩個版本,包括重構前和重構後。首先需要強調的是,在我們尚未明確定義處理需求之前就開始編寫程式碼時,我們往往難以清晰區分功能和流程,也難以進行函式的模組化。換句話說,函式可能處理多個耦合的步驟。因為很重要,所以特別在這裡說明。或許在需求快速變化的情況下,我們無法投入足夠的時間或技術來編寫具有足夠彈性的程式碼,這就不可避免地導致了重構的需求。然而,我們仍然可以降低重構所需的時間成本,並盡量遵循一些簡潔程式碼的原則。

實際案例

=== 重構前 ===
從 mousedown 開始一條龍處理 mousemove, mouseup 事件

const dragstart_handler = (event) => {
   //此函式主要是使用者點擊 mousedown 之後出發
   //處理滑鼠拖曳卡片樣式變化,主要為位置 
  currentDraggingStyle.value = {
    position: "absolute",
    zIndex: 1000,
  };
  document.body.append(card.value);
  const moveAt = (pageX, pageY) => {
    currentDraggingStyle.value = {
      position: "absolute",
      zIndex: 1000,
      left: pageX - card.value.offsetWidth / 2 + "px",
      top: pageY - card.value.offsetHeight / 2 + "px",
    };
    cardWidth.value = card.value.offsetWidth;
    cardHeight.value = card.value.offsetHeight;
    cardX.value = pageX - card.value.offsetWidth / 2 + "px";
    cardY.value = pageY - card.value.offsetHeight / 2 + "px";
    cardPosition.leftTop = {
      x: pageX - card.value.offsetWidth / 2,
      y: pageY - card.value.offsetHeight / 2,
    };
    cardPosition.leftBottom = {
      x: pageX - card.value.offsetWidth / 2,
      y: pageY + card.value.offsetHeight / 2,
    };
    cardPosition.rightTop = {
      x: pageX + card.value.offsetWidth / 2,
      y: pageY - card.value.offsetHeight / 2,
    };
    cardPosition.rightBottom = {
      x: pageX + card.value.offsetWidth / 2,
      y: pageY + card.value.offsetHeight / 2,
    };
  };
  moveAt(event.pageX, event.pageY);
  const dragmove_handler = (ev) => {
    moveAt(ev.pageX, ev.pageY);
    // 處理卡片是否要顯示提示框,以及插入不同的位置
    handleTimelineObserver();
  };
  //處理使用者開始移動手指
  document.addEventListener("mousemove", dragmove_handler);
  //處理使用者手指放開結束拖曳
  card.value.addEventListener("mouseup", () => {
    document.removeEventListener("mousemove", dragmove_handler);
    groupAnimated.value = false;
    if (isMoveInTimeline.value) {
      cardLists.value.splice(overOutlineCount.value, 0, currentCard.value);
      cardLists.value[overOutlineCount.value].isCorrect = judgeOrder(
        overOutlineCount.value
      );
      setTimeout(() => {
        groupAnimated.value = true;
        cardLists.value.sort(function (a, b) {
          return a.order - b.order;
        });
      }, 1000);
      updateStep();
    }
    cardContainer.value.append(card.value);
    currentDraggingStyle.value = {
      position: "static",
      zIndex: 0,
      left: "auto",
      top: "auto",
      transition: "all 2s ease-in-out",
    };
    isMoveInTimeline.value = false;
    isOverOutline.value = false;
    overOutlineCount.value = 0;
    updateTimelineStyles();
    card.value.removeEventListener("mouseup", () => {});
  });
};

=== 重構後 ===
使用 Vue 框架提供的事件監聽處理器,

@mousedown.stop="handleClueCardClick(index, $event)"
@mouseup.stop="handleClueCardClickOff(index)"

...略

整理程式碼維護實踐步驟

遵循這些最佳實踐和原則將有助於編寫出更可維護、更可靠的程式碼。

  1. 設計之前先計劃
  • 在實際編碼之前,先進行需求分析和設計。
  • 考慮使用設計模式和架構模式。
  1. 編碼風格和命名規範
  • 選擇一套一致的編碼風格和命名規範,並堅持使用。
  • 變數和函數名應具有描述性,避免使用縮寫或不明確的名稱。
  1. 注釋和文檔
  • 寫出清晰的注釋,解釋為什麼這樣做,而不僅僅是怎麼做。
  • 建立良好的開發者文檔,包括 API 文檔、架構說明等。
  1. 模塊化和解耦
  • 將程式碼分解成小型、可重用的模塊或函數。
  • 避免過度耦合,使各個模塊或組件能獨立運作。
  1. 錯誤處理和日誌
  • 使用全面的錯誤處理機制,包括 try-catch 語句和自定義錯誤類型。
  • 使用日誌來追踪和記錄重要的運行時信息。
  1. 測試
  • 寫出可測試的程式碼並使用自動化測試(單元測試、集成測試等)。
  • 使用測試驅動開發(TDD)或行為驅動開發(BDD)。
  1. 版本控制
  • 使用版本控制系統(如 Git)來追踪程式碼變更。
  • 遵循一致的分支和合併策略。
  1. 程式碼審查
  • 進行代碼審查以確保程式碼的質量和可維護性。
  • 使用自動化代碼審查工具和人工審查。
  1. 持續集成和持續交付(CI/CD)
  • 使用 CI/CD 工具來自動化測試和部署。
  • 確保每次變更都能快速、可靠地進入生產環境。
  1. 重構
  • 定期進行重構以改善程式碼結構和性能。
  • 在重構過程中,保持功能的一致性和完整性。

上一篇
開發工具與相依套件安裝
下一篇
新增測試策略與實作
系列文
打造紐時風格的時間線小遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言