درود🌹
بیاین امروز در مورد معماری Event-driven Architecture با یک مثال ساده صحبت کنیم.
معماری مبتنی بر رویدادها یه جور سیستم برنامهنویسیه که توش بخشهای مختلف برنامه میتونن با هم حرف بزنن و به تغییرات و اتفاقات مختلف واکنش نشون بدن. این معماری مخصوصاً برای برنامههای بزرگ و پیچیده که تعاملات زیادی دارن خیلی خوبه.
اجزای اصلی این معماری عبارتند از:
فرستنده رویداد (Event Emitter): این بخش کارش اینه که رویدادها رو به بقیه بخشهای برنامه اطلاع بده.
شنوندهها (Listeners): اینا فانکشنهایی هستن که وقتی یه رویداد خاص اتفاق میافته، اجرا میشن.
رویدادها (Events): رویدادها پیغامهایی هستن که نشون میدن یه تغییر یا اتفاق خاص رخ داده.
مزایای معماری مبتنی بر رویدادها:
جداسازی وظایف: هر بخش از برنامه کار خودش رو انجام میده و به تغییرات مرتبط واکنش نشون میده.
افزایش قابلیت نگهداری: اگه بخوای یه تغییر کوچیک تو یه بخش برنامه بدی، لازم نیست کل کد رو تغییر بدی.
افزایش مقیاسپذیری: به راحتی میتونی شنوندههای جدید اضافه کنی یا رفتار برنامه رو تغییر بدی.
مثال کامل از معماری مبتنی بر رویدادها
فرض کن یه برنامه داری که توش چند تا کاربر هستن. میخوای هر وقت یکی از کاربرا اطلاعاتش تغییر کرد یا کاربری اضافه شد، این تغییرات به بقیه بخشهای برنامه اطلاع داده بشه. برای این کار از معماری مبتنی بر رویداد استفاده میکنیم.
اول یه کلاس میسازیم که کارش مدیریت رویدادهاست:
// این کلاس مسئولیت مدیریت رویدادها رو داره
class EventEmitter {
constructor() {
this.events = {}; // اینجا رویدادها و شنوندههاشون رو نگه میداریم
}
// این متد یه شنونده جدید برای یه رویداد خاص ثبت میکنه
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
// این متد همه شنوندههای یه رویداد خاص رو اجرا میکنه
emit(event, args) {
if (this.events[event]) {
this.events[event].forEach(listener => listener(args));
}
}
}
حالا یه کلاس میسازیم که کاربرها رو مدیریت کنه و وقتی کاربری اضافه یا تغییر کرد، رویدادهای مناسب رو صادر کنه:
// این کلاس مسئول مدیریت کاربران و رویدادهای مرتبط با اوناست
class UserManager extends EventEmitter {
constructor() {
super();
this.users = []; // لیست کاربران رو اینجا نگه میداریم
}
// این متد یه کاربر جدید اضافه میکنه
addUser(user) {
this.users.push(user);
this.emit('userAdded', user); // رویداد اضافه شدن کاربر رو صادر میکنیم
}
// این متد اطلاعات یه کاربر رو تغییر میده
updateUser(id, newUser) {
const index = this.users.findIndex(user => user.id === id);
if (index !== -1) {
this.users[index] = { ...this.users[index], ...newUser };
this.emit('userUpdated', this.users[index]); // رویداد بهروزرسانی کاربر رو صادر میکنیم
}
}
}
حالا از UserManager استفاده میکنیم و شنوندههای مختلفی برای رویدادها ثبت میکنیم:
const userManager = new UserManager();
// ثبت یه شنونده برای وقتی که یه کاربر جدید اضافه میشه
userManager.on('userAdded', (user) => {
console.log(`کاربر جدید اضافه شد: ${user.name}`);
// اینجا میتونیم کارهای دیگهای هم انجام بدیم، مثل بهروزرسانی رابط کاربری
});
// ثبت یه شنونده برای وقتی که اطلاعات یه کاربر تغییر میکنه
userManager.on('userUpdated', (user) => {
console.log(`اطلاعات کاربر بهروزرسانی شد: ${user.name}`);
// اینجا میتونیم کارهای دیگهای هم انجام بدیم، مثل بهروزرسانی رابط کاربری
});
// اضافه کردن یه کاربر جدید
userManager.addUser({ id: 1, name: 'Ali', age: 30 });
// نتیجه: کاربر جدید اضافه شد: Ali
// تغییر اطلاعات یه کاربر
userManager.updateUser(1, { name: 'Hassan', age: 35 });
// نتیجه: اطلاعات کاربر بهروزرسانی شد: Hassan
حالا فرض کن میخوای هر وقت کاربری اضافه شد یا تغییر کرد، علاوه بر چاپ توی کنسول، یه نوتیفیکیشن هم نشون بدی:
// ثبت شنونده برای نوتیفیکیشنها
userManager.on('userAdded', (user) => {
alert(`کاربر جدید اضافه شد: ${user.name}`);
});
userManager.on('userUpdated', (user) => {
alert(`اطلاعات کاربر بهروزرسانی شد: ${user.name}`);
});
از این معماری در drawio استفاده شده.ری اکت و ویو و همچنین Apache Kafka از این معماری استفاده میکنه، اگر علاقه داشتین مثال های بیشتری باهاش میزنیم یا تو یک برنامه ای ازش استفاده میکنیم اصلا
موفق باشید❤️
#Event_driven_Architecture
@CleverDevs -
@CleverDevsGp