Skip to content

Commit 50ae1e0

Browse files
committed
Merge branch 'design_patterns'
2 parents 01e40cd + 8a46d28 commit 50ae1e0

File tree

7 files changed

+944
-2
lines changed

7 files changed

+944
-2
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
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>
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
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+
```c
18+
// sensor_manager.h
19+
#ifndef SENSOR_MANAGER_H
20+
#define SENSOR_MANAGER_H
21+
22+
typedef struct {
23+
int sensor_id;
24+
float current_temperature;
25+
float threshold;
26+
} SensorManager;
27+
28+
void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold);
29+
void check_temperature(SensorManager* manager);
30+
31+
#endif
32+
```
33+
34+
#### 2. پیاده‌سازی ماژول مدیریت سنسور
35+
36+
```c
37+
// sensor_manager.c
38+
#include "sensor_manager.h"
39+
#include <stdio.h>
40+
41+
void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold) {
42+
manager->sensor_id = sensor_id;
43+
manager->threshold = threshold;
44+
}
45+
46+
void check_temperature(SensorManager* manager) {
47+
// فرض کنید این تابع دما را از سنسور می‌خواند
48+
manager->current_temperature = read_sensor(manager->sensor_id);
49+
50+
if (manager->current_temperature > manager->threshold) {
51+
printf("Warning: Temperature is too high! Taking action...
52+
");
53+
// اینجا مثلاً فن را روشن می‌کنیم یا هر اقدام دیگری که لازم است
54+
}
55+
}
56+
```
57+
58+
#### 3. استفاده از ماژول در برنامه اصلی
59+
60+
```c
61+
// main.c
62+
#include "sensor_manager.h"
63+
64+
int main(void) {
65+
SensorManager temperature_manager;
66+
init_sensor_manager(&temperature_manager, 1, 30.0);
67+
68+
while (1) {
69+
check_temperature(&temperature_manager);
70+
delay(1000); // تأخیر برای کنترل سرعت حلقه
71+
}
72+
73+
return 0;
74+
}
75+
```
76+
77+
### مشکلات روش بدون Callback
78+
79+
- **وابستگی مستقیم:** برای تغییر رفتار سیستم، باید مستقیماً در کد اصلی تغییرات ایجاد کنیم.
80+
- **قابلیت گسترش محدود:** افزودن سنسورهای جدید یا تغییر رفتار سنسورهای فعلی نیاز به تغییرات گسترده‌ای در کد دارد.
81+
- **نگهداری سخت:** تغییرات مکرر باعث پیچیدگی و سختی در نگهداری کد می‌شود.
82+
83+
## استفاده از الگوی طراحی Callback
84+
85+
با استفاده از الگوی طراحی Callback، می‌توانیم کد را انعطاف‌پذیرتر و قابل گسترش‌تر کنیم.
86+
87+
### پیاده‌سازی ماژول مدیریت سنسور با پشتیبانی از Callback
88+
89+
```c
90+
// sensor_manager.h
91+
#ifndef SENSOR_MANAGER_H
92+
#define SENSOR_MANAGER_H
93+
94+
typedef void (*TemperatureCallback)(float current_temperature);
95+
96+
typedef struct {
97+
int sensor_id;
98+
float threshold;
99+
TemperatureCallback on_threshold_exceed;
100+
} SensorManager;
101+
102+
void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold);
103+
void set_temperature_callback(SensorManager* manager, TemperatureCallback callback);
104+
void check_temperature(SensorManager* manager);
105+
106+
#endif
107+
```
108+
109+
### پیاده‌سازی ماژول مدیریت سنسور
110+
111+
```c
112+
// sensor_manager.c
113+
#include "sensor_manager.h"
114+
#include <stdio.h>
115+
116+
void init_sensor_manager(SensorManager* manager, int sensor_id, float threshold) {
117+
manager->sensor_id = sensor_id;
118+
manager->threshold = threshold;
119+
manager->on_threshold_exceed = NULL;
120+
}
121+
122+
void set_temperature_callback(SensorManager* manager, TemperatureCallback callback) {
123+
manager->on_threshold_exceed = callback;
124+
}
125+
126+
void check_temperature(SensorManager* manager) {
127+
float current_temperature = read_sensor(manager->sensor_id);
128+
129+
if (current_temperature > manager->threshold && manager->on_threshold_exceed != NULL) {
130+
manager->on_threshold_exceed(current_temperature);
131+
}
132+
}
133+
```
134+
135+
### پیاده‌سازی توابع Callback در برنامه اصلی
136+
137+
```c
138+
// main.c
139+
#include "sensor_manager.h"
140+
#include <stdio.h>
141+
142+
void handle_high_temperature(float current_temperature) {
143+
printf("Warning: Temperature is %.2f! Taking action...
144+
", current_temperature);
145+
// اقدام لازم، مثلاً روشن کردن فن
146+
}
147+
148+
int main(void) {
149+
SensorManager temperature_manager;
150+
init_sensor_manager(&temperature_manager, 1, 30.0);
151+
152+
set_temperature_callback(&temperature_manager, handle_high_temperature);
153+
154+
while (1) {
155+
check_temperature(&temperature_manager);
156+
delay(1000); // تأخیر برای کنترل سرعت حلقه
157+
}
158+
159+
return 0;
160+
}
161+
```
162+
163+
### مزایای استفاده از Callback
164+
165+
- **انعطاف‌پذیری بالا:** می‌توانیم به راحتی رفتار سیستم را تغییر دهیم، بدون نیاز به تغییر در کد اصلی.
166+
- **قابلیت گسترش آسان:** افزودن سنسورهای جدید تنها با تعریف یک `SensorManager` جدید و تنظیم Callback مناسب انجام می‌شود.
167+
- **کد مرتب‌تر و قابل نگهداری‌تر:** تصمیم‌گیری‌ها و واکنش‌ها به توابع جداگانه سپرده شده و مدیریت کد ساده‌تر می‌شود.
168+
169+
</div>

0 commit comments

Comments
 (0)