C語言-裝飾器模式詳解與實踐 - LED控制系統

文章目錄

  • C語言裝飾器模式詳解與實踐 - LED控制系統
    • 1. 什么是裝飾器模式?
    • 2. 為什么需要裝飾器模式?
    • 3. 實際應用場景
    • 4. 代碼實現
      • 4.1 頭文件 (led_decorator.h)
      • 4.2 實現文件 (led_decorator.c)
      • 4.3 使用示例 (main.c)
    • 5. 代碼分析
      • 5.1 關鍵設計點
      • 5.2 實現特點
    • 6. 編譯和運行
    • 7. 注意事項
    • 8. 改進建議
    • 9. 總結
    • 參考資料

C語言裝飾器模式詳解與實踐 - LED控制系統

1. 什么是裝飾器模式?

裝飾器模式允許我們動態地向對象添加新的功能,而不改變其原有結構。在LED控制系統中,我們可以通過裝飾器模式實現不同的LED效果疊加。

2. 為什么需要裝飾器模式?

  • 動態添加LED效果
  • 效果可以自由組合
  • 不修改原有代碼
  • 符合開閉原則
  • 代碼復用性高

3. 實際應用場景

  • LED狀態指示
  • 設備運行狀態顯示
  • 警告信號顯示
  • 用戶界面反饋
  • 調試信息顯示

4. 代碼實現

LedController
+set_state()
+update()
+destroy()
BasicLed
-pin
-state
LedDecorator
-wrapped
BlinkLed
-interval
-counter
-state
BreathLed
-period
-counter
SosLed
-counter
-pattern_pos
-pattern
-pattern_length

4.1 頭文件 (led_decorator.h)

#ifndef LED_DECORATOR_H
#define LED_DECORATOR_H#include <stdint.h>
#include <stdbool.h>// LED控制接口
typedef struct {void (*set_brightness)(void* self, uint8_t level);void (*update)(void* self);void (*destroy)(void* self);
} LedController;// 基礎LED控制器
typedef struct {LedController base;uint8_t pin;         // LED引腳uint8_t brightness;  // 當前亮度
} BasicLed;// LED裝飾器基類
typedef struct {LedController base;LedController* wrapped;
} LedDecorator;// 創建基礎LED控制器
LedController* create_basic_led(uint8_t pin);// 創建閃爍裝飾器
LedController* create_blink_led(LedController* wrapped, uint16_t interval_ms);// 創建呼吸燈裝飾器
LedController* create_breath_led(LedController* wrapped, uint16_t period_ms);// 創建漸變裝飾器
LedController* create_fade_led(LedController* wrapped, uint16_t fade_time_ms);// 銷毀LED控制器
void destroy_led_controller(LedController* controller);#endif // LED_DECORATOR_H

4.2 實現文件 (led_decorator.c)

#include "led_decorator.h"
#include <stdio.h>
#include <stdlib.h>// 模擬硬件操作
static void hw_set_pin(uint8_t pin, uint8_t level) {printf("設置引腳 %d 亮度為 %d\n", pin, level);
}// 基礎LED控制器實現
static void basic_set_brightness(void* self, uint8_t level) {BasicLed* led = (BasicLed*)self;led->brightness = level;hw_set_pin(led->pin, level);
}static void basic_update(void* self) {// 基礎LED不需要更新
}static void basic_destroy(void* self) {free(self);
}// 閃爍裝飾器實現
typedef struct {LedDecorator base;uint16_t interval;uint16_t counter;bool state;
} BlinkLed;static void blink_set_brightness(void* self, uint8_t level) {BlinkLed* led = (BlinkLed*)self;led->base.wrapped->set_brightness(led->base.wrapped, level);
}static void blink_update(void* self) {BlinkLed* led = (BlinkLed*)self;led->counter++;if (led->counter >= led->interval) {led->counter = 0;led->state = !led->state;led->base.wrapped->set_brightness(led->base.wrapped, led->state ? 255 : 0);}
}static void blink_destroy(void* self) {BlinkLed* led = (BlinkLed*)self;destroy_led_controller(led->base.wrapped);free(led);
}// 呼吸燈裝飾器實現
typedef struct {LedDecorator base;uint16_t period;uint16_t counter;
} BreathLed;static void breath_set_brightness(void* self, uint8_t level) {BreathLed* led = (BreathLed*)self;led->base.wrapped->set_brightness(led->base.wrapped, level);
}static void breath_update(void* self) {BreathLed* led = (BreathLed*)self;led->counter++;if (led->counter >= led->period) {led->counter = 0;}// 使用正弦波實現呼吸效果float phase = (float)led->counter / led->period * 3.14159f * 2;uint8_t brightness = (uint8_t)((sinf(phase) + 1.0f) * 127.5f);led->base.wrapped->set_brightness(led->base.wrapped, brightness);
}static void breath_destroy(void* self) {BreathLed* led = (BreathLed*)self;destroy_led_controller(led->base.wrapped);free(led);
}// 創建函數實現
LedController* create_basic_led(uint8_t pin) {BasicLed* led = (BasicLed*)malloc(sizeof(BasicLed));led->base.set_brightness = basic_set_brightness;led->base.update = basic_update;led->base.destroy = basic_destroy;led->pin = pin;led->brightness = 0;return (LedController*)led;
}LedController* create_blink_led(LedController* wrapped, uint16_t interval_ms) {BlinkLed* led = (BlinkLed*)malloc(sizeof(BlinkLed));led->base.base.set_brightness = blink_set_brightness;led->base.base.update = blink_update;led->base.base.destroy = blink_destroy;led->base.wrapped = wrapped;led->interval = interval_ms;led->counter = 0;led->state = false;return (LedController*)led;
}LedController* create_breath_led(LedController* wrapped, uint16_t period_ms) {BreathLed* led = (BreathLed*)malloc(sizeof(BreathLed));led->base.base.set_brightness = breath_set_brightness;led->base.base.update = breath_update;led->base.base.destroy = breath_destroy;led->base.wrapped = wrapped;led->period = period_ms;led->counter = 0;return (LedController*)led;
}void destroy_led_controller(LedController* controller) {if (controller && controller->destroy) {controller->destroy(controller);}
}

4.3 使用示例 (main.c)

#include "led_decorator.h"
#include <stdio.h>
#include <windows.h>  // 用于Sleep函數void simulate_time(LedController* led, int ms) {printf("\n模擬運行 %d ms:\n", ms);for (int i = 0; i < ms; i += 100) {led->update(led);Sleep(100);  // 模擬時間流逝}
}int main() {// 創建基礎LED(使用引腳13)LedController* led = create_basic_led(13);printf("=== 測試基礎LED ===\n");led->set_brightness(led, 128);  // 設置50%亮度printf("\n=== 測試閃爍LED ===\n");led = create_blink_led(led, 500);  // 500ms閃爍間隔simulate_time(led, 2000);  // 運行2秒printf("\n=== 測試呼吸LED ===\n");led = create_breath_led(led, 2000);  // 2000ms呼吸周期simulate_time(led, 3000);  // 運行3秒// 清理資源destroy_led_controller(led);return 0;
}

5. 代碼分析

5.1 關鍵設計點

  1. LED控制接口統一
  2. 裝飾器鏈式組合
  3. 時間管理機制
  4. 資源管理完善

5.2 實現特點

  1. 函數指針實現多態
  2. 模塊化設計
  3. 效果可組合
  4. 代碼復用性高

6. 編譯和運行

gcc -c led_decorator.c -o led_decorator.o
gcc -c main.c -o main.o
gcc led_decorator.o main.o -o led_demo

7. 注意事項

  1. 時序控制精度
  2. 內存管理
  3. 硬件接口抽象
  4. 中斷處理

8. 改進建議

  1. 添加PWM控制
  2. 實現更多效果
  3. 優化時間管理
  4. 添加錯誤處理

9. 總結

裝飾器模式在LED控制系統中的應用,使得我們可以靈活地組合不同的LED效果,同時保持代碼的清晰和可維護性。這種模式特別適合需要動態組合多種LED效果的場景。

參考資料

  1. 《嵌入式系統設計》
  2. 《設計模式》
  3. 《單片機編程實踐》

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898882.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898882.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898882.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go常見問題與回答(下)

文章目錄 1、通過指針變量 p 訪問其成員變量 name&#xff0c;有哪幾種方式&#xff1f;2、代碼&#xff0c;說出結果3、擴容提&#xff0c;代碼&#xff0c;說出結果4、指出下面這段代碼的錯誤之處5、是否通過編譯6、關于字符串連接&#xff0c;下面語法正確的是7、關于iota&a…

JVM 核心知識點總結

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;…

SQL中體會多對多

我們可以根據學生與課程多對多關系的數據庫模型&#xff0c;給出實際的表數據以及對應的查詢結果示例&#xff0c;會用到JOINLEFT JOIN兩種連接 1. 學生表&#xff08;students&#xff09; student_idstudent_name1張三2李四3王五 2. 課程表&#xff08;courses&#xff09…

ES如果要查10條數據需要從各個分片上各取多少條數據?

目錄 ES如果要查10條數據需要從各個分片上各取多少條數據? 簡單查詢(如 match_all 或 term 查詢) 深度分頁查詢(如 from + size 查詢) 聚合查詢 什么叫聚合查詢? 聚合查詢的基本結構 常見的聚合類型 聚合查詢的執行過程 聚合查詢的示例 聚合查詢的應用場景 注意…

人機交互自學引導

第1關&#xff1a;輸出“Hello World!” # 在下面一行補充代碼&#xff0c;輸出“Hello World!” print(Hello World!) 第2關&#xff1a;輸出“李白&#xff0c;你好&#xff01;” # 在下面補充代碼&#xff0c;在兩行中依次輸出“李白&#xff0c;你好&#xff01;”和“…

CentOS 7 更換 yum 源(阿里云)+ 擴展 epel 源

CentOS 7 更換 yum 源&#xff08;阿里云&#xff09; 擴展 epel 源 一、備份現有 yum 源二、下載 yum 源&#xff08;任選其一即可&#xff09;三、清理并生成緩存四、安裝 EPEL 擴展源&#xff08;根據需要下載&#xff09;五、驗證是否生效六、一鍵腳本&#xff08;阿里云源…

無人機與傳統巡檢優劣勢對比!

一、無人機巡檢的優勢 1. 高效性 覆蓋范圍廣&#xff1a;可快速掃描大范圍區域&#xff08;如電力線路、管道、農田等&#xff09;&#xff0c;尤其適合復雜地形&#xff08;山區、沼澤等&#xff09;。 速度快&#xff1a;飛行速度遠高于人工巡檢&#xff0c;縮短任務周期…

DrRacket是一款專為Scheme和Racket編程語言設計的集成開發環境(IDE)

DrRacket是一款專為Scheme和Racket編程語言設計的集成開發環境&#xff08;IDE&#xff09;&#xff0c;由瑞士蘇黎世聯邦理工學院開發。它不僅是初學者學習編程的理想工具&#xff0c;也適用于專業級開發?。 安裝DrRacket 請訪問https://download.racket-lang.org安裝Racke…

走進底層-Java中的IO流

Java中IO流 在Java編程中&#xff0c;IO流&#xff08;Input/Output Stream&#xff09;是非常重要的概念&#xff0c;它為程序的輸入和輸出操作提供了一套強大而靈活的機制。本文將詳細介紹Java中IO流的相關內容&#xff0c;包括其基本概念、分類以及常見類的使用示例。 一、…

【Tiny RDM】Redis客戶端工具

Tiny RDM Tiny RDM是一款現代化、輕量級、跨平臺的Redis客戶端&#xff0c;支持Mac、Windows和Linux&#xff0c;目前在Github上已有10kStar。 Github 項目地址&#xff1a; https://github.com/tiny-craft/tiny-rdm 功能特性 極度輕量&#xff0c;基于Webview2&#xff0c…

ctfshow REVERSE re2 萌新賽 內部賽 七夕杯 WP

目錄 re2 萌新賽 flag白給 簽退 數學不及格 內部賽 批量生產的偽劣產品 來一個派森 好好學習 天天向上 屏幕裂開了 七夕杯 逆向簽到 easy_magic re2 ida分析主函數&#xff0c;將flag.txt內容加密寫入enflag.txt 這是密鑰加密過程 標準rc4加密 簡單異或解…

【Linux】線程庫

一、線程庫管理 tid其實是一個地址 void* start(void* args) {const char* name (const char *)args;while(true){printf("我是新線程 %s &#xff0c;我的地址&#xff1a;0x%lx\n",name,pthread_self());sleep(1);}return nullptr; }int main() {pthread_t tid…

深入剖析 Android Compose 框架的自動動畫:AnimatedVisibility 與 AnimatedContent(二十四)

深入剖析 Android Compose 框架的自動動畫&#xff1a;AnimatedVisibility 與 AnimatedContent 引言 在 Android 應用開發中&#xff0c;動畫是提升用戶體驗的重要手段。它能夠讓界面元素的顯示與隱藏、狀態的切換變得更加自然和流暢&#xff0c;避免生硬的變化給用戶帶來不佳…

文件上傳的小點總結(1)

2.文件類型繞過 問題插入&#xff1a;BP無法攔截本地流量 ①插件限制 不代理的地址列表通常寫有localhost和127.0.0.1&#xff0c;把本地的全都刪掉&#xff0c;然后應用保存。 ②瀏覽器限制 Firefox瀏覽器設置&#xff1a;檢查瀏覽器代理配置和proxy listeners都沒問題后&…

AI基礎01-文本數據采集

本篇文章是學習文本數據的采集&#xff0c;作為人工智能訓練師或者數據分析師有時需要先獲取數據&#xff0c;然后進行數據清洗、數據標注。很明顯數據采集是后續步驟的基礎。 1&#xff09;數據采集定義 數據采集&#xff1a;data acquisition&#xff0c;DAQ 又稱為數據獲取…

深度學習Python編程:從入門到工程實踐

第一章 Python語言概述與生態體系 1.3 Python在工業界的應用場景 # 示例:使用FastAPI構建RESTful接口 from fastapi import FastAPI from pydantic import BaseModelapp = FastAPI()class Item(BaseModel):name: strprice: float@app.post("/items/") async def cr…

使用CSS3實現炫酷的3D翻轉卡片效果

使用CSS3實現炫酷的3D翻轉卡片效果 這里寫目錄標題 使用CSS3實現炫酷的3D翻轉卡片效果項目介紹技術要點分析1. 3D空間設置2. 核心CSS屬性3. 布局和定位 實現難點和解決方案1. 3D效果的流暢性2. 卡片內容布局3. 響應式設計 性能優化建議瀏覽器兼容性總結 項目介紹 在這個項目中…

HAl庫開發中斷方式接收Can報文的詳細流程

下面給出一個基于 HAL 庫的中斷方式接收 CAN 報文的詳細流程說明&#xff0c;描述每一步的硬件配置、軟件調用和中斷處理機制&#xff0c;而不涉及具體代碼細節&#xff0c;只講解整體原理和步驟&#xff1a; 在使用 HAL 庫時&#xff0c;不需要手動清除中斷標志位。原因如下&…

【讀書筆記】華為《從偶然到必然》

note 華為的成功并非偶然&#xff0c;而是通過IPD體系、投資組合管理、平臺戰略等系統性工具&#xff0c;將研發投資轉化為可持續的商業競爭力。書中強調的“管理即內部因素”理念&#xff0c;揭示了企業規模擴張與管理能力匹配的深層規律&#xff0c;為高科技企業提供了可借鑒…

6.4考研408數據結構圖論核心知識點深度解析

一、最小生成樹(Minimum Spanning Tree) 1.1 Prim算法 易錯點與難點 lowcost數組更新邏輯 錯誤將已加入生成樹的頂點距離重置為0后繼續參與計算,導致后續頂點選擇錯誤未正確處理非連通圖情況,可能陷入死循環(需結合visited數組判斷)示例錯誤:for(int j=0; j<G.vexn…