iT邦幫忙

2024 iThome 鐵人賽

DAY 27
1
IT 管理

30天從版控到code review的實踐指南系列 第 27

Day 27. Code Review 模組化與重用性-規則篇。

  • 分享至 

  • xImage
  •  

在 Code Review 時,為了維持程式碼可維護性、易擴充原則,Function 的模組化與重用性為重要原則。今天將介紹撰寫程式碼時,開發人員需遵守的撰寫原則,以及 Reviewers 在 Review 時應考量的關鍵方向:

  • 單一職責原則 (Single Responsibility Principle, SRP)

    確保一個 Function 只處理單一邏輯,例如一個 Module 負責處理數據的取得,另一個負責將獲取的資料進行渲染,而一個 Function 負責取得數據同時又需要處理業務邏輯或是渲染到畫面上。


    // 壞例子:
    // 一個函數同時做兩件事情
    function fetchDataAndRender() {
        const data = fetchData();
        render(data);
    }
    
    // 好例子:
    // 將職責分開
    function fetchData() {
        // 從API取得數據
        return fetch('api/data');
    }
    
    function render(data) {
        // 渲染數據到畫面上
        console.log(data);
    }
    
  • 開放封閉原則 (Open/Closed Principle, OCP)

    不更動原功能核心邏輯的情況下,仍易於擴充新需求,例如:增加屬性等。


    // 壞例子:
    // 若要加入更多動物判斷,就要到 Function 裡調整
    function getAnimalSound(animal) {
        if (animal === 'dog') {
            return 'woof';
        } else if (animal === 'cat') {
            return 'meow';
        }
        // 每增加一個新動物都需要修改這裡
    }
    
    // 好例子:
    // 將動物類別獨立寫在變數裡,可隨時增加動物類型,也不會修改原來的 Function
    const animalSounds = {
        dog: 'woof',
        cat: 'meow'
        // 新動物可以直接加在這
    };
    
    function getAnimalSound(animal) {
        return animalSounds[animal] || 'unknown sound';
    }
    
  • 避免重複原則 (Don’t Repeat Yourself, DRY)

    減少重複的程式碼,以便維護和修正時只需修改一處。將重複的邏輯統一寫成可重用的 Function 或 Module。


    // 壞例子:有重複程式碼
    function greetUser() {
        const userName = getUserName();
        console.log(`Hello, ${userName}!`);
    }
    
    function greetAdmin() {
        const adminName = getAdminName();
        console.log(`Hello, ${adminName}!`);
    }
    
    // 好例子:重用共通函數
    function greet(name) {
        console.log(`Hello, ${name}!`);
    }
    
    greet(getUserName());
    greet(getAdminName());
    
  • 高內聚、低耦合 (High Cohesion and Low Coupling)

    高內聚:將相關的屬性和方法集中在一起,以便清晰地表達其功能和職責。


    // 在 Article class 中,所有方法都是圍繞著文章的特性設計的,
    // 如獲得摘要、新增日期和更新內容,皆與文章的管理有關。
    class Article {
        constructor(title, content) {
            this.title = title;
            this.content = content;
            this.createdAt = new Date();
        }
    
        getSummary() {
            return this.content.substring(0, 100) + '...';
        }
    
        getCreatedAt() {
            return this.createdAt.toLocaleDateString();
        }
    
        updateContent(newContent) {
            this.content = newContent;
        }
    }
    

    低耦合:Module 之間應避免過度依賴,降低改動一個 Module 對其他 Module 的影響。

    注意:也需考慮到實際的業務功能需求和系統的複雜性。對於簡單的應用,過度地強調高內聚和低耦合可能會導致不必要的複雜性和過度設計。

  • 介面隔離原則 (Interface Segregation Principle, ISP)

    讓 Module 只關注自己所需的部分。


    // 壞例子:所有物品都要執行不必要的功能
    class Item {
        use() { /* some code */ }
        equip() { /* some code */ }  // 某些物品不需要這個功能
    }
    
    // 好例子:為不同物品提供不同介面
    class UsableItem {
        use() { /* some code */ }
    }
    
    class EquippableItem extends UsableItem {
        equip() { /* some code */ }
    }
    
  • 使用依賴注入 (Dependency Injection, DI)

    降低 Module 之間的耦合。


    // 壞例子:Function 內部實作依賴
    function Logger() {
        const fileLogger = new FileLogger();
        fileLogger.log('Logging data');
    }
    
    // 好例子:透過依賴注入
    function Logger(logger) {
        logger.log('Logging data');
    }
    
    const fileLogger = new FileLogger();
    const consoleLogger = new ConsoleLogger();
    Logger(fileLogger); // 可以彈性注入不同的logger
    Logger(consoleLogger);
    
  • 重視可重用性 (Reusability)

  • 避免過早優化 (Avoid Premature Optimization)

    在設計 Module 時,應著重於程式碼可讀與可維護性,並避免為了微小的效能提升而破壞 Module 結構。


    // 壞例子:太早優化,程式碼變得難以閱讀
    function getSum(arr) {
        let sum = 0, i = 0, n = arr.length;
        while (i < n) {
            sum += arr[i++];
        }
        return sum;
    }
    
    // 好例子:先保持程式碼清楚,有效能問題再進行優化
    function getSum(arr) {
        return arr.reduce((total, num) => total + num, 0);
    }
    
  • 遵守一致性和命名規則

  • 高測試覆蓋率 (Testability)

    可透過單元測試和集成測試來驗證 Module 的功能,提高系統穩定。

Summary


今天提到的模組重用性和 code review 原則強調了 Function 單一職責、高內聚、低耦合以及可測試性等開發設計原則,希望能增加程式碼的可維護性。明天的內容將繼續提供更多實際範例,幫助讀者能較容易將這些原則帶入實際的開發與應用。


上一篇
Day 26. Code Review 安全性原則:CSRF、其他篇
下一篇
Day 28. Code Review 模組化與重用性-範例篇-1。
系列文
30天從版控到code review的實踐指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言