|
| 1 | +<div dir="rtl"> |
| 2 | + |
| 3 | +# الگوی طراحی Callback در سیستمهای نهفته |
| 4 | + |
| 5 | +این README قراره بهت کمک کنه تا با الگوی طراحی Callback تو سیستمهای نهفته آشنا بشی. همچنین شامل یه سری تمرین از ساده تا پیچیده است که میتونی با انجامشون مهارتهات رو تو این زمینه تقویت کنی. |
| 6 | + |
| 7 | +## سناریو: مدیریت دادههای سنسور در سیستم تهویه مطبوع هوشمند |
| 8 | + |
| 9 | +فرض کن داری یه سیستم تهویه مطبوع هوشمند برای یه ساختمون طراحی میکنی. این سیستم باید بتونه دادههای مختلفی رو از سنسورها (مثل دما، رطوبت و کیفیت هوا) بگیره و بر اساس اونها تهویه رو کنترل کنه. مثلا وقتی دما میره بالا، تهویه باید سریعتر کار کنه تا محیط خنک بشه. |
| 10 | + |
| 11 | +### پیادهسازی بدون استفاده از Callback |
| 12 | + |
| 13 | +اول بیا مسئله رو بدون استفاده از الگوی طراحی Callback پیادهسازی کنیم. تو این روش، همه چیز تو یه ماژول متمرکز شده و تصمیمگیریها مستقیماً تو کد نوشته میشن. |
| 14 | + |
| 15 | +#### 1. تعریف ساختار مدیریت سنسور |
| 16 | + |
| 17 | +<div dir="ltr"> |
| 18 | + |
| 19 | +```c |
| 20 | +// sensor_manager.h |
| 21 | +#ifndef SENSOR_MANAGER_H |
| 22 | +#define SENSOR_MANAGER_H |
| 23 | + |
| 24 | +typedef struct { |
| 25 | + int sensor_id; |
| 26 | + float current_temperature; |
| 27 | + float threshold; |
| 28 | +} SensorManager; |
| 29 | + |
| 30 | +void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold); |
| 31 | +void check_temperature(SensorManager* manager); |
| 32 | + |
| 33 | +#endif |
| 34 | +``` |
| 35 | +</div> |
| 36 | + |
| 37 | +#### 2. پیادهسازی ماژول مدیریت سنسور |
| 38 | + |
| 39 | +<div dir="ltr"> |
| 40 | + |
| 41 | +```c |
| 42 | +// sensor_manager.c |
| 43 | +#include "sensor_manager.h" |
| 44 | +#include <stdio.h> |
| 45 | + |
| 46 | +void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold) { |
| 47 | + manager->sensor_id = sensor_id; |
| 48 | + manager->threshold = threshold; |
| 49 | +} |
| 50 | + |
| 51 | +void check_temperature(SensorManager* manager) { |
| 52 | + // فرض کن این تابع دما رو از سنسور میخونه |
| 53 | + manager->current_temperature = read_sensor(manager->sensor_id); |
| 54 | + |
| 55 | + if (manager->current_temperature > manager->threshold) { |
| 56 | + printf("Warning: Temperature is too high! Taking action... |
| 57 | +"); |
| 58 | + // اینجا مثلاً فن رو روشن میکنیم یا هر اقدام دیگهای که لازمه |
| 59 | + } |
| 60 | +} |
| 61 | +``` |
| 62 | +</div> |
| 63 | +
|
| 64 | +#### 3. استفاده از ماژول تو برنامه اصلی |
| 65 | +
|
| 66 | +<div dir="ltr"> |
| 67 | +
|
| 68 | +```c |
| 69 | +// main.c |
| 70 | +#include "sensor_manager.h" |
| 71 | +
|
| 72 | +int main(void) { |
| 73 | + SensorManager temperature_manager; |
| 74 | + init_sensor_manager(&temperature_manager, 1, 30.0); |
| 75 | +
|
| 76 | + while (1) { |
| 77 | + check_temperature(&temperature_manager); |
| 78 | + delay(1000); // تأخیر برای کنترل سرعت حلقه |
| 79 | + } |
| 80 | +
|
| 81 | + return 0; |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +</div> |
| 86 | + |
| 87 | +### مشکلات روش بدون Callback |
| 88 | + |
| 89 | +- **وابستگی مستقیم:** اگه بخوایم رفتار سیستم رو تغییر بدیم، باید مستقیماً تو کد اصلی تغییرات ایجاد کنیم. |
| 90 | +- **قابلیت گسترش محدود:** اگه بخوایم سنسورهای جدید اضافه کنیم یا رفتار سنسورهای فعلی رو تغییر بدیم، نیاز به تغییرات زیادی تو کد داریم. |
| 91 | +- **نگهداری سخت:** تغییرات مکرر باعث میشه کد پیچیده بشه و نگهداریش سخت بشه. |
| 92 | + |
| 93 | +## استفاده از الگوی طراحی Callback |
| 94 | + |
| 95 | +حالا بیا با استفاده از الگوی طراحی Callback کد رو انعطافپذیرتر و قابل گسترشتر کنیم. |
| 96 | + |
| 97 | +### پیادهسازی ماژول مدیریت سنسور با پشتیبانی از Callback |
| 98 | + |
| 99 | +<div dir="ltr"> |
| 100 | + |
| 101 | +```c |
| 102 | +// sensor_manager.h |
| 103 | +#ifndef SENSOR_MANAGER_H |
| 104 | +#define SENSOR_MANAGER_H |
| 105 | + |
| 106 | +typedef void (*TemperatureCallback)(float current_temperature); |
| 107 | + |
| 108 | +typedef struct { |
| 109 | + int sensor_id; |
| 110 | + float threshold; |
| 111 | + TemperatureCallback on_threshold_exceed; |
| 112 | +} SensorManager; |
| 113 | + |
| 114 | +void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold); |
| 115 | +void set_temperature_callback(SensorManager* manager, TemperatureCallback callback); |
| 116 | +void check_temperature(SensorManager* manager); |
| 117 | + |
| 118 | +#endif |
| 119 | +``` |
| 120 | + |
| 121 | +</div> |
| 122 | + |
| 123 | +### پیادهسازی ماژول مدیریت سنسور |
| 124 | + |
| 125 | +<div dir="ltr"> |
| 126 | + |
| 127 | +```c |
| 128 | +// sensor_manager.c |
| 129 | +#include "sensor_manager.h" |
| 130 | +#include <stdio.h> |
| 131 | + |
| 132 | +void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold) { |
| 133 | + manager->sensor_id = sensor_id; |
| 134 | + manager->threshold = threshold; |
| 135 | + manager->on_threshold_exceed = NULL; |
| 136 | +} |
| 137 | + |
| 138 | +void set_temperature_callback(SensorManager* manager, TemperatureCallback callback) { |
| 139 | + manager->on_threshold_exceed = callback; |
| 140 | +} |
| 141 | + |
| 142 | +void check_temperature(SensorManager* manager) { |
| 143 | + float current_temperature = read_sensor(manager->sensor_id); |
| 144 | + |
| 145 | + if (current_temperature > manager->threshold && manager->on_threshold_exceed != NULL) { |
| 146 | + manager->on_threshold_exceed(current_temperature); |
| 147 | + } |
| 148 | +} |
| 149 | +``` |
| 150 | +
|
| 151 | +</div> |
| 152 | +
|
| 153 | +### پیادهسازی توابع Callback تو برنامه اصلی |
| 154 | +
|
| 155 | +<div dir="ltr"> |
| 156 | +
|
| 157 | +```c |
| 158 | +// main.c |
| 159 | +#include "sensor_manager.h" |
| 160 | +#include <stdio.h> |
| 161 | +
|
| 162 | +void handle_high_temperature(float current_temperature) { |
| 163 | + printf("Warning: Temperature is %.2f! Taking action... |
| 164 | +", current_temperature); |
| 165 | + // اقدام لازم، مثلاً روشن کردن فن |
| 166 | +} |
| 167 | +
|
| 168 | +int main(void) { |
| 169 | + SensorManager temperature_manager; |
| 170 | + init_sensor_manager(&temperature_manager, 1, 30.0); |
| 171 | +
|
| 172 | + set_temperature_callback(&temperature_manager, handle_high_temperature); |
| 173 | +
|
| 174 | + while (1) { |
| 175 | + check_temperature(&temperature_manager); |
| 176 | + delay(1000); // تأخیر برای کنترل سرعت حلقه |
| 177 | + } |
| 178 | +
|
| 179 | + return 0; |
| 180 | +} |
| 181 | +``` |
| 182 | + |
| 183 | +</div> |
| 184 | + |
| 185 | +### مزایای استفاده از Callback |
| 186 | + |
| 187 | +- **انعطافپذیری بالا:** میتونیم به راحتی رفتار سیستم رو تغییر بدیم، بدون اینکه نیاز باشه کد اصلی رو تغییر بدیم. |
| 188 | +- **قابلیت گسترش آسان:** اضافه کردن سنسورهای جدید فقط با تعریف یه `SensorManager` جدید و تنظیم Callback مربوطه انجام میشه. |
| 189 | +- **کد مرتبتر و قابل نگهداریتر:** تصمیمگیریها و واکنشها تو توابع جداگانه مدیریت میشه و کد سادهتر میشه. |
| 190 | + |
| 191 | +## تمرینها |
| 192 | + |
| 193 | +| شماره | سوال | بارم | |
| 194 | +| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | |
| 195 | +| 1 | یه تابع Callback تعریف کن که یه پیام متنی رو دریافت کنه و چاپش کنه. بعد یه تابع دیگه بنویس که این Callback رو به عنوان آرگومان دریافت کنه و اون رو فراخوانی کنه. | 1 | |
| 196 | +| 2 | یه آرایه از اعداد صحیح تعریف کن و یه تابع Callback بنویس که اعداد رو پردازش کنه (مثلاً هر عدد رو یه واحد اضافه کنه). بعد این Callback رو به هر عنصر آرایه اعمال کن. | 2 | |
| 197 | +| 3 | یه برنامه ساده بنویس که دو رویداد "کلید A فشرده شده" و "کلید B فشرده شده" رو مدیریت کنه. برای هر رویداد یه Callback تعریف کن و اونها رو به توابع مربوطه متصل کن. | 3 | |
| 198 | +| 4 | یه سناریوی ساده با سه نوع سنسور (دما، رطوبت و نور) تعریف کن. برای هر سنسور یه Callback بنویس که وقتی به یه حد مشخص رسید، اقدامات لازم رو انجام بده. سیستم باید بتونه هر کدوم از این توابع Callback رو جداگانه مدیریت کنه. | 5 | |
| 199 | + |
| 200 | +</div> |
0 commit comments