日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

嵌入式編程模型 | 抽象工廠模式

一、抽象工廠模式

抽象工廠模式(Abstract Factory Pattern)是一種創(chuàng)建型設(shè)計模式,它提供一個接口用于創(chuàng)建相關(guān)或依賴對象的家族,而無需指定它們的具體類。

在需要高兼容性的嵌入式系統(tǒng)中,抽象工廠模式能顯著降低多平臺適配成本,確保硬件組件間的兼容性,是構(gòu)建可移植嵌入式框架的核心模式。

抽象工廠模式(Abstract Factory Pattern)與簡單工廠模式有很多相似之處。我們先做個對比:

特性簡單工廠模式抽象工廠模式嵌入式應(yīng)用單一設(shè)備驅(qū)動管理整套硬件平臺適配適用場景產(chǎn)品類型少且變化不頻繁需要創(chuàng)建多個相關(guān)產(chǎn)品的系統(tǒng)抽象級別產(chǎn)品級別抽象工廠級別抽象創(chuàng)建對象單個產(chǎn)品產(chǎn)品家族(多個相關(guān)產(chǎn)品)工廠類型單一工廠類抽象工廠+多個具體工廠實現(xiàn)類擴展性添加新產(chǎn)品需修改工廠類添加新產(chǎn)品族只需新增工廠類

簡單工廠模式適用于產(chǎn)品類型少且變化不頻繁的場景。如嵌入式中對單一設(shè)備驅(qū)動管理,比如管理LCD驅(qū)動:

抽象工廠模式適用于需要創(chuàng)建多個相關(guān)產(chǎn)品的系統(tǒng)。如嵌入式中對整個硬件平臺的管理。

抽象工廠模式的核心包含四個關(guān)鍵部分:

  1. 抽象工廠(Abstract Factory):聲明創(chuàng)建一系列產(chǎn)品的方法。
  2. 具體工廠(Concrete Factory):實現(xiàn)抽象工廠的方法,創(chuàng)建具體產(chǎn)品。
  3. 抽象產(chǎn)品(Abstract Product):聲明產(chǎn)品接口。
  4. 具體產(chǎn)品(Concrete Product):實現(xiàn)抽象產(chǎn)品接口,定義具體產(chǎn)品。

其中,第2~4點就是簡單工廠模式的要點。即簡單工廠模式加上第1點的抽象工廠這個要點就構(gòu)成了抽象工廠模式。

二、嵌入式:多平臺硬件抽象層

設(shè)備需要支持不同平臺(STM32/ESP32等),每個平臺有兼容的輸入、輸出驅(qū)動。

1、代碼

#include 
#include 

// 抽象產(chǎn)品(Abstract Product)
typedefstruct {
    void (*Init)(void);
    void (*Draw)(int x, int y);
} DisplayDriver;

typedefstruct {
    void (*Init)(void);
    bool (*ReadButton)(void);
} InputDriver;

// 具體產(chǎn)品實現(xiàn) - STM32平臺
void stm32_disp_init(void) {
    printf("STM32 Display Initialized\n");
}

void stm32_draw(int x, int y) {
    printf("STM32 Drawing at (%d, %d)\n", x, y);
}

void stm32_button_init(void) {
    printf("STM32 Button Initialized\n");
}

bool stm32_read_button(void) {
    printf("STM32 Button Read\n");
    returntrue; // 模擬按下狀態(tài)
}

// 具體產(chǎn)品實現(xiàn) - ESP32平臺
void esp32_disp_init(void) {
    printf("ESP32 Display Initialized\n");
}

void esp32_draw(int x, int y) {
    printf("ESP32 Drawing at (%d, %d)\n", x, y);
}

void esp32_button_init(void) {
    printf("ESP32 Button Initialized\n");
}

bool esp32_read_button(void) {
    printf("ESP32 Button Read\n");
    returnfalse; // 模擬未按下狀態(tài)
}

// 抽象工廠(Abstract Factory)
typedefstruct {
    DisplayDriver display;
    InputDriver input;
} HWPlatform;

// 具體工廠(Concrete Factory) - STM32平臺
const HWPlatform stm32_platform = {
    {stm32_disp_init, stm32_draw},
    {stm32_button_init, stm32_read_button}
};

// 具體工廠(Concrete Factory) - ESP32平臺
const HWPlatform esp32_platform = {
    {esp32_disp_init, esp32_draw},
    {esp32_button_init, esp32_read_button}
};

int main() {
    // 選擇平臺 - 通過定義USE_STM32宏來選擇
    #if defined(USE_STM32)
        constchar* platform_name = "STM32";
        const HWPlatform* platform = &stm32_platform;
    #else
        constchar* platform_name = "ESP32";
        const HWPlatform* platform = &esp32_platform;
    #endif
    
    printf("Running on %s platform\n", platform_name);
    
    // 初始化顯示
    platform->display.Init();
    
    // 初始化輸入
    platform->input.Init();
    
    // 繪制圖形
    platform->display.Draw(10, 20);
    platform->display.Draw(30, 40);
    
    // 讀取按鈕狀態(tài)
    bool buttonState = platform->input.ReadButton();
    printf("Button state: %s\n", buttonState ? "PRESSED" : "RELEASED");
    
    return0;
}

C ++版本:

#include 
#include 

// 抽象產(chǎn)品接口
struct DisplayDriver {
    void (*Init)(void);
    void (*Draw)(int x, int y);
};

struct InputDriver {
    void (*Init)(void);
    bool (*ReadButton)(void);
};

// 具體產(chǎn)品實現(xiàn) - STM32平臺
namespace STM32 {
    void DisplayInit() {
        std::cout << "[STM32] Display initialized\n";
    }
    
    void DisplayDraw(int x, int y) {
        std::cout << "[STM32] Drawing at (" << x << ", " << y << ")\n";
    }
    
    void InputInit() {
        std::cout << "[STM32] Input initialized\n";
    }
    
    bool InputReadButton() {
        std::cout << "[STM32] Reading button\n";
        returntrue; // 模擬按鈕被按下
    }
}

// 具體產(chǎn)品實現(xiàn) - ESP32平臺
namespace ESP32 {
    void DisplayInit() {
        std::cout << "[ESP32] Display initialized\n";
    }
    
    void DisplayDraw(int x, int y) {
        std::cout << "[ESP32] Drawing at (" << x << ", " << y << ")\n";
    }
    
    void InputInit() {
        std::cout << "[ESP32] Input initialized\n";
    }
    
    bool InputReadButton() {
        std::cout << "[ESP32] Reading button\n";
        returnfalse; // 模擬按鈕未被按下
    }
}

// 抽象工廠
class HWPlatform {
public:
    const DisplayDriver& GetDisplayDriver() const { return display; }
    const InputDriver& GetInputDriver() const { return input; }
    
    virtual void PrintPlatformInfo() const {
        std::cout << "Generic Hardware Platform\n";
    }
    
protected:
    DisplayDriver display;
    InputDriver input;
};

// 具體工廠 - STM32平臺
class STM32Platform :public HWPlatform {
public:
    STM32Platform() {
        display.Init = STM32::DisplayInit;
        display.Draw = STM32::DisplayDraw;
        input.Init = STM32::InputInit;
        input.ReadButton = STM32::InputReadButton;
    }
    
    void PrintPlatformInfo() const override {
        std::cout << "\n=== STM32 Hardware Platform ===\n";
    }
};

// 具體工廠 - ESP32平臺
class ESP32Platform :public HWPlatform {
public:
    ESP32Platform() {
        display.Init = ESP32::DisplayInit;
        display.Draw = ESP32::DisplayDraw;
        input.Init = ESP32::InputInit;
        input.ReadButton = ESP32::InputReadButton;
    }
    
    void PrintPlatformInfo() const override {
        std::cout << "\n=== ESP32 Hardware Platform ===\n";
    }
};

// 使用示例
int main() {
    std::cout << "=== Embedded Hardware Platform Demo ===\n";
    
    // 平臺選擇
    #if defined(USE_STM32)
        STM32Platform platform;
        std::cout << "Selected platform: STM32\n";
    #else
        ESP32Platform platform;
        std::cout << "Selected platform: ESP32\n";
    #endif

    // 打印平臺信息
    platform.PrintPlatformInfo();
    
    // 初始化硬件
    std::cout << "\nInitializing hardware...\n";
    platform.GetDisplayDriver().Init();
    platform.GetInputDriver().Init();
    
    // 使用顯示驅(qū)動
    std::cout << "\nDrawing on display...\n";
    platform.GetDisplayDriver().Draw(5, 10);
    platform.GetDisplayDriver().Draw(15, 25);
    platform.GetDisplayDriver().Draw(30, 40);
    
    // 讀取輸入狀態(tài)
    std::cout << "\nReading input...\n";
    bool buttonState = platform.GetInputDriver().ReadButton();
    std::cout << "Button state: " << (buttonState ? "PRESSED" : "RELEASED") << "\n";
    
    return0;
}

2、優(yōu)缺點分析

(1)優(yōu)點

① 符合開閉原則

開閉原則 (The Open/Closed Principle, OCP) :軟件中的對象(類,模塊,函數(shù)等等)應(yīng)該對于擴展是開放的,但是對于修改是封閉的。

  • 初始支持:STM32和ESP32
  • 新增平臺:添加Nordic nRF52支持
    • 新增NRF52Platform工廠類
    • 新增nRF52顯示/輸入驅(qū)動
    • 無需修改現(xiàn)有STM32/ESP32代碼

② 接口統(tǒng)一化

// 統(tǒng)一的硬件操作接口
platform->display.Init();
platform->input.Init();
platform->display.Draw(10, 20);
platform->display.Draw(30, 40);
bool buttonState = platform->input.ReadButton();

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關(guān)注 30
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧