CodeCrafters
764 subscribers
92 photos
50 videos
42 files
170 links
Download Telegram
مرزها
طراحی معماری ذاتاً در مورد مرزها است: طراحی معماری طراحی سیستم است. طراحی سیستم یک طراحی زمینه‌ای است، ذاتاً در مورد مرزهاست (آنچه در داخل است، چه چیزی خارج است، چه چیزی رو در بر می‌گیرد، چه چیزی بین آن حرکت می‌کند) و در مورد مبادلات است. آن چیزی که بیرون است را دوباره شکل می‌دهد، درست همانطور که درون را شکل می‌دهد.الگوی بافت محدود ابزار طراحی حوزه محور برای تعریف مرزهای فیزیکی و مالکیت است

مرزهای فیزیکی:
بافت‌های محدود نه تنها به عنوان مرزهای مدل بلکه به عنوان مرزهای فیزیکی سیستم هایی که آنها را اجرا می کنند نیز عمل می کنند. هر بافت محدود باید به عنوان یک سرویس/پروژه فردی پیاده‌سازی شود، به این معنی که مستقل از سایر بافت‌های محدود پیاده‌سازی، تکامل و نسخه‌بندی می‌شود (soa, microservice)

مرزهای فیزیکی واضح بین بافت‌های محدود به ما این امکان را می‌دهد که هر بافت محدود را با پشته فناوری که به بهترین وجه با نیازهای آن مطابقت دارد، پیاده‌سازی کنیم(یکی از مفاهیم میکروسرویس)

یک بافت محدود می تواند شامل چندین زیر دامنه باشد. در چنین حالتی، بافت محدود یک مرز فیزیکی است، در حالی که هر یک از زیر دامنه های آن یک مرز منطقی است. مرزهای منطقی در زبان های برنامه نویسی مختلف نام های مختلفی دارند:فضاهای نام، ماژول ها یا بسته ها

مرزهای مالکیت:
در پروژه‌های نرم‌افزاری، می‌توانیم از مرزهای مدل (بافت محدود) برای همزیستی مسالمت‌آمیز تیم‌ها استفاده کنیم. تقسیم کار بین تیم ها یکی دیگر از تصمیمات استراتژیک است که می تواند با استفاده از الگوی بافت محدود اتخاذ شود. یک بافت محدود باید تنها توسط یک تیم اجرا، تکامل و نگهداری شود. هیچ دو تیمی نمی توانند روی یک بافت محدود کار کنند. این جداسازی مفروضات ضمنی را که ممکن است تیم ها درباره مدل های یکدیگر بسازند، حذف می کند.
در عوض، آنها باید پروتکل های ارتباطی را برای یکپارچه سازی مدل ها و سیستم های خود به طور صریح تعریف کنند. توجه به این نکته مهم است که رابطه بین تیم ها و بافت‌های محدود یک طرفه است: یک بافت محدود باید تنها در اختیار یک تیم باشد. با این حال، یک تیم می تواند دارای چندین بافت محدود باشد.

در انتهای این بخش از کتاب نویسنده مجدد فاز افلاطون گرفته و مباحث فلسفی و علمی رو برای توضیح زیردامنه‌ مطرح کرده است که بسیار مثالهای جالبی بود(واقعا سوادش رو به رخ کشید)

#DDD
#domain_driven_design

@code_crafters
4👍1
چهل نکته درباره Linux Server Hardening.pdf
713.1 KB
با تشکر از اعضای گروه (جناب امیر) بابت ترجمه و تهیه این سند

@code_crafters
10
یکپارچه سازی بافت محدود

الگوی بافت محدود علاوه بر محافظت از زبان فراگیر، مدلسازی رو هم برامون امکان پذیر میکنه، بدون مشخص شدن هدف و مرز یک مدل نمیتونید بسازیدش، مرز مسئولیت زبان‌ها رو تقسیم میکنه، یک زبان در یک بافت محدود می‌تواند دامنه کسب و کار را برای حل یک مشکل خاص مدل کند، یک بافت محدود دیگر میتواند همان واحدهای تجاری را نشان دهد اما آنها را برای حل یک مشکل متفاوت مدل کند

مدل‌ها در بافت‌های محدود متفاوت میتوانند بطور مستقل تکامل یافته و پیاده سازی شوند، (خود بافت‌های محدود مستقل نیستند) یک سیستم را نمیتوان از اجزای مستقل ساخت آنها باید با هم در تعامل باشند تا به هدف کلی سیستم دست یابند(پیاده سازی‌ها در بافت‌های محدود نیز انجام می‌شود) بافت‌ها میتوانند مستقل تکامل یابند اما باید با یکدیگر ادغام شوند. در نتیجه همیشه نقاط تماس بین بافت‌های محدود وجود خواهد داشت به این‌ -قرادادها- میگویند(لپ کلام میکروسرویس)

نیاز به قرادادها ناشی از تفاوت در مدل‌ها و زبان‌های بافت‌های محدود است. هر قرارداد بیش از یک طرف را درگیر میکند لذا لازم است قراردادها تعریف و هماهنگ شوند(دو بافت محدود از زبانهای مختلف در همه حا استفاده میکنند) کدام زبان برای ادغام استفاده خواهد شد؟ این نگرانی‌های یکپارچه سازی باید توسط طراحی راه حل ارزیابی و برطرف شود

موضوعیت بحث بر سر ادغام و یکپارچه سازی بافت‌های محدود هستش، طراحی دامنه محور اینکار رو با الگوهای مدنظر خودش انجام خواهد داد، الگوها رو میتوان در سه گروه زیر دسته بندی کرد: همکاری ، مشتری-تامین کننده، راه‌های جداگانه

همکاری:
الگوهای همکاری مربوط به بافت‌های محدودی است که توسط تیم هایی با ارتباطات تثبیت شده اجرا می شود. در ساده‌ترین حالت، اینها بافت‌های محدودی هستند که توسط یک تیم واحد پیاده‌سازی شده‌اند. این در مورد تیم هایی با اهداف وابسته نیز صدق می کند، جایی که موفقیت یک تیم به موفقیت تیم دیگر بستگی دارد و بالعکس. باز هم، معیار اصلی در اینجا کیفیت ارتباطات و همکاری تیم ها است.
بیایید به دو الگوی DDD مناسب برای تیم های همکار نگاه کنیم: الگوهای مشارکت و هسته مشترک.

الگوی مشارکت:
ادغام بین بافت‌های محدود به شیوه ای موقت هماهنگ می شود. یک تیم می تواند تیم دوم را در مورد تغییر در API مطلع کند، و تیم دوم همکاری خواهد کرد و تطبیق خواهد کرد، بدون درام یا درگیری، هماهنگی ادغام دو طرفه است، تیم‌ها می‌توانند تفاوت‌ها را حل کنند و مناسب ترین راه حل را انتخاب کنند، هر دو طرف در حل مسائل مربوط به ادغام که ممکن است پیش بیاید، همکاری می‌کنند، هیچ یک از تیم‌ها علاقه‌ای به مسدود کردن تیم دیگر ندارند، برای ادغام موفقیت آمیز، همکاری تثبیت شده، سطوح بالای تعهد و هماهنگی‌های مکرر بین تیم‌ها مورد نیاز است، این الگو ممکن است برای تیم‌های توزیع شده جغرافیایی مناسب نباشد به دلیل چالش‌های همگام سازی و ارتباطی

هسته مشترک:
بافت‌های محدود مرز مدل‌ها رو مشخص میکنند، اما ممکن است مواردی رخ دهد که همان مدل زیردامنه یا بخشی ازون در کرانهای چندگانه پیاده سازی شود(مدل مشترک بر اساس نیازهای همه بافت‌های محدود طراحی شده است) مدل مشترک باید در تمام بافت‌های محدودی که از آن استفاده میکنند سازگار باشد(نمونه آن مدل authorization است)

دامنه مشترک:
همپوشانی چرخه حیات بافت‌های محدود مشارکت‌ کننده را جفت می‌کند. تغییری که در مدل مشترک ایجاد شده است، تأثیر فوری بر تمام متون محدود دارد. از این رو، برای به حداقل رساندن اثرات آبشاری تغییرات، مدل همپوشانی باید محدود شود و تنها بخشی از مدل را که باید توسط هر دو بافت محدود اجرا شود، در معرض دید قرار دهد. در حالت ایده‌آل، هسته مشترک فقط شامل قراردادهای یکپارچه‌سازی و ساختارهای داده‌ای است که در نظر گرفته شده‌اند از مرزهای بافت‌های محدود عبور داده شوند

پیاده‌سازی:
هسته مشترک به گونه‌ای پیاده‌سازی می‌شود که هرگونه تغییر در کد منبع آن بلافاصله در تمام بافت‌های محدودی که از آن استفاده می‌کنند منعکس شود.اگر سازمان از رویکرد تک مخزن استفاده کند، این فایل‌ها می‌توانند همان فایل‌های منبع ارجاع‌شده توسط بافت‌های محدود شده متعدد باشند. اگر استفاده از یک مخزن مشترک امکان پذیر نباشد، هسته مشترک را میتوان در یک پروژه اختصاصی استخراج کرد و در بافت‌های محدود به عنوان یک کتابخانه پیوندی ارجاع داد.هر تغییر در هسته مشترک، آزمایش‌های یکپارچه‌سازی را برای تمام بافت‌های محدود تحت تاثیر قرار میدهد. ادغام پیوسته تغییرات نیاز است زیرا هسته مشترک متعلق به چندین بافت محدود است. عدم انتشار تغییرات هسته مشترک در همه بافت‌های محدود مرتبط منجر به ناسازگاری در یک مدل می‌شود: بافت‌های محدود ممکن است(در پیاده‌سازی‌های قدیمی هسته مشترک منجر به خرابی داده‌/مشکلات اجرایی میشود)

#DDD
#domain_driven_design

@code_crafters
🔥5👍1
مشتری – تامین کننده:
دومین گروه از الگوهای همکاری که بررسی خواهیم کرد، الگوهای مشتری – تامین کننده است. یکی از بافت‌های محدود - تامین کننده - خدماتی را برای مشتریان خود ارائه می دهد.
ارائه‌دهنده خدمات «بالادست» و مشتری یا مصرف‌کننده «پایین دست» است.
بر خلاف مورد همکاری، هر دو تیم (بالا دستی و پایین دستی) می توانند به طور مستقل موفق شوند. در نتیجه، در بیشتر موارد ما یک عدم تعادل قدرت داریم: تیم بالادستی یا پایین دستی می توانند قرارداد ادغام را دیکته کنند.
این بخش سه الگو را مورد بحث قرار می‌دهد که به چنین تفاوت‌های قدرتی می‌پردازد: الگوهای سازگاری، لایه ضدفساد و الگوهای خدمات میزبان باز.

سازگار:
در برخی موارد، توازن قدرت به نفع تیم بالادستی است که هیچ انگیزه واقعی برای حمایت از نیازهای مشتریان خود ندارد. در عوض، فقط قرارداد یکپارچه‌سازی را ارائه می‌کند که بر اساس مدل خودش تعریف شده است (آن را بگیرید یا ترک کنید) چنین عدم توازن قدرت می تواند ناشی از ادغام با ارائه دهندگان خدماتی باشد که خارج از سازمان هستند یا صرفاً توسط سیاست های سازمانی است. اگر تیم پایین‌دستی بتواند مدل تیم بالادستی را بپذیرد، رابطه بافت‌های محدود را انطباق‌پذیر می‌گویند. پایین‌دست با مدل بافت محدود بالادست مطابقت دارد

تصمیم تیم پایین دستی برای کنار گذاشتن برخی از اختیارات خود را می توان به روش های مختلفی توجیه کرد. برای مثال: قراردادی که توسط تیم بالادستی فاش می شود ممکن است یک مدل استاندارد صنعتی و تثبیت شده باشد، یا ممکن است به اندازه کافی برای نیازهای تیم پایین دستی خوب باشد

لایه ضد فساد(ACL):
همانطور که در الگوی انطباق گرایانه، توازن قدرت در این رابطه همچنان به سمت خدمات بالادستی منحرف است. با این حال، در این مورد، بافت محدود پایین دست مایل به انطباق نیست. می تواند مدل بافت محدود بالادستی را به مدلی متناسب با نیازهای خود از طریق یک لایه ضد فساد ترجمه کند.

خارج از مبحث کتاب:
لایه ضد فساد بصورت کاربردی، تصور کنید شما در یکی از سرویس‌هاتون (بافت محدود) نیاز به گرفتن اطلاعات از یک سرویس بیرونی دارید که اطلاعات زو به شکل مدنظر خودش ارسال میکنه که با سرویس شما و مدل مشکل گشای شما در زیردامنه ،سازگار نیست در اینجا شما یک کلاس می‌سازید که به سرویس بیرونی request میزند پس از دریافت پاسخ اطلاعات رو به شکل ساختار مدنظر مدل شما در آورده و باز میگرداند ،این کلاس رابط بین بافت محدود شما و سرویس بیرونی میشود، بدین ترتیب مرزهای مدل شما بصورت محافظت شده باقی میماند

الگوی لایه ضدفساد به سناریوهایی می پردازد که در آنها مطلوب/ارزش تلاش برای انطباق با مدل تامین کننده را ندارد، مانند موارد زیر:
هنگامی که بافت محدود پایین دستی حاوی یک زیر دامنه اصلی است، یک مدل زیر دامنه اصلی نیاز به توجه بیشتری دارد و پایبندی به مدل تأمین‌کننده ممکن است مدل‌سازی دامنه مشکل را مختل کند.
زمانی که مدل بالادستی برای نیازهای مصرف کننده ناکارآمد یا نامناسب است، اگر یک بافت محدود با یک آشفتگی مطابقت داشته باشد، خطر تبدیل شدن به یک آشفتگی را دارد. این اغلب هنگام ادغام با سیستم های قدیمی اتفاق می افتد.
هنگامی که قرارداد تامین کننده تغییر می کند، مصرف کننده می خواهد مدل خود را از تغییرات مکرر محافظت کند. با یک لایه ضد فساد، تغییرات در مدل تأمین‌کننده تنها بر مکانیسم ترجمه تأثیر می‌گذارد.

سرویس میزبان باز(Open-Host Service):
این دقیقا نقطه متقابل لایه ضد فساد است و تامین کننده(سرویس بالادستی-بیرونی-) از مصرف کنندگان حمایت میکند و خروجی را مطابق میل انها ارائه میدهد این ملزم به نوشتن لایه‌هایی مختلفی است که زیان مصرف کنندگان رو تامین کند و خروجی کطابق زبان انها ارائه دهد

راه‌های جداگانه:
راه دیگر این است که دست از همکاری بکشید، ممکن هزینه ارتباط گرفتن بسیار بالا باشد یا مشکلاتی بوجود بیاورد که منحر به شکسته شدن مدل مشکل گشا شود در این مواقع همکاری نکردن و توسعه سرویس شخصی خود بسیار مقرون بصرفه‌تر خواهد بود

همکاری بین سرویس‌های خود را بصورت یک نقشه در بیاورید (تصویر در کامنت‌ها) تا افراد درون گروه‌ها ببینند ارتباطات چگونه است و چه گروه‌هایی باهمدیگر در حال همکاری هستند و نحوه همکاری آنها چگونه است ،ممکن است این نقشه پیچیده شود لذا در دو طرح متفاوت ساماندهی گردد

برای ترسیم نقشه از برنامه context mapper استفاده کنید

#DDD
#domain_driven_design

@code_crsfters
4
CodeCrafters
زبان های معروف بلاکچین خب تو این پست قراره با زبان های برنامه نویسی که در بلاکچین کاربرد زیادی داشتند و دارند اشنا بشیم و همچنین در پست بعدی مریم سراغ پیاده سازی بلاکچین و الگورتیم های مربوطه با پایتون🥸🥸 برای توسعه‌ی بلاک چین زبان‌های مختلفی وجود دارند، اما…
سلام🥸همونطور که از پست قبلی متوجه شدیم با زبان های بسیاری میتونیم بلاکچین رو طراحی کنیم و خب تو این پست قراره بلاکچینی رو برای زنجیره تامینی با استفاده از پایتون پیاده کنیم
زنجیر تامین یکی دیگه از کاربرد های بلاکچین در کنار ارز دیجیتیال و قرار داد های هوشمند و... هست.
بلاکچینی که قراره طراحی کنیم برای پیگیری محصولات غذایی از مزرعه تا فروشگاه برای اطمینان از کیفیت و اصالت کالا هستش

اولین چیزی که نیاز داریم یه کلاس تراکنش هست که یه سری مشخصات رو مثل فرستنده , گیرنده , محصول و مقدار اون محصول رو دریافت کنیم


import hashlib
import time

class Transaction:
def __init__(self, sender, recipient, product, quantity):
self.sender = sender
self.recipient = recipient
self.product = product
self.quantity = quantity

def __str__(self):
return f"Transaction(sender: {self.sender}, recipient: {self.recipient}, product: {self.product}, quantity: {self.quantity})"

حالا که تراکنش‌ها رو تعریف کردیم، باید یک کلاس برای بلاک‌ها ایجاد کنیم. هر بلاک در زنجیره شامل چند ویژگی اصلی که به ترتیب عبارتند از:
شماره بلاک در زنجیره (index)
هش بلاک قبلی در زنجیره (previous_hash)
زمان ایجاد بلاک (timestamp)
لیست تراکنش‌های درون بلاک (transactions)
عددی که برای ماینینگ استفاده میشه (nonce)
هش بلاک (hash):که با استفاده از تراکنش‌ها و ویژگی‌های دیگر بلاک ساخته میشه

class Block:
def __init__(self, index, previous_hash, timestamp, transactions, nonce=0):
self.index = index
self.previous_hash = previous_hash
self.timestamp = timestamp
self.transactions = transactions
self.nonce = nonce
self.hash = self.calculate_hash()

def calculate_hash(self):
transactions_string = ""
for tx in self.transactions:
transactions_string += str(tx)

block_string = f"{self.index}{self.previous_hash}{self.timestamp}{transactions_string}{self.nonce}"
return hashlib.sha256(block_string.encode()).hexdigest()

def __str__(self):
return f"Block<index: {self.index}, hash: {self.hash}>"


حالا که بلاک‌ها و تراکنش‌ها رو تعریف کردیم، باید یک کلاس برای بلاکچین خودمون ایجاد کنیم که شامل ویژگی‌هایی مثل لیستی از بلاک‌ها، تراکنش‌های معلق و سایر عملیات مانند اضافه کردن تراکنش، ماین کردن بلاک و بررسی اعتبار زنجیره باشه. درواقع نیاز به یه کلاس داریم که بیاد و بلاکچینمون رو مدیریت کنه
class Blockchain:
difficulty = 4 # میزان سختی برای ماینینگ بلاک

def __init__(self):
self.chain = [self.create_genesis_block()]
self.pending_transactions = []

def create_genesis_block(self):
# genesis block ایجاد بلاک اول با متود
return Block(0, "0", time.time(), [])

def get_latest_block(self):
#A: دریافت آخرین بلاک در زنجیره
return self.chain[-1]

def add_transaction(self, transaction):
#B: اضافه کردن تراکنش به لیست تراکنش‌های معلق یا در تایید انتظار
self.pending_transactions.append(transaction)

def mine_pending_transactions(self):
#C: ماین کردن تراکنش‌های معلق و اضافه کردن بلاک به زنجیره
block = Block(len(self.chain), self.get_latest_block().hash, time.time(), self.pending_transactions)
self.mine_block(block)
self.chain.append(block)
self.pending_transactions = []

def mine_block(self, block):
#D: Proof of Work ماین کردن یک بلاک با استفاده از الگوریتم
while block.hash[:self.difficulty] != "0" * self.difficulty:
block.nonce += 1
block.hash = block.calculate_hash()
print(f"Block mined: {block.hash}")

def is_chain_valid(self):
#E: بررسی اعتبار کل زنجیره با مقایسه هش‌ها و هش‌های محاسبه شده
for i in range(1, len(self.chain)):
current_block = self.chain[i]
previous_block = self.chain[i - 1]

if current_block.hash != current_block.calculate_hash():
return False

if current_block.previous_hash != previous_block.hash:
return False

return True

ادامه توضیحات کلس BlockChain و نحوه ساخت یه بلاک با تراکنش هاش تو پست بعدی🥸
#blockchain
🔥6
CodeCrafters
سلام🥸همونطور که از پست قبلی متوجه شدیم با زبان های بسیاری میتونیم بلاکچین رو طراحی کنیم و خب تو این پست قراره بلاکچینی رو برای زنجیره تامینی با استفاده از پایتون پیاده کنیم زنجیر تامین یکی دیگه از کاربرد های بلاکچین در کنار ارز دیجیتیال و قرار داد های هوشمند…
ساخت بلاک های اولیه و تراکنش
خب در نهایت به این میرسیم که چطوری میتونیم از کلس هامون استفاده کنیم
blockchain = Blockchain()

#A: ایجاد تراکنش‌
blockchain.add_transaction(Transaction('Farm', 'Warehouse', 'Tomatoes', 70))
blockchain.add_transaction(Transaction('Warehouse', 'Distributor', 'Tomatoes', 90))
blockchain.add_transaction(Transaction('Distributor', 'Retailer', 'Tomatoes', 80))

#B: ماین کردن تراکنش‌های معلق
blockchain.mine_pending_transactions()

#C: بررسی اعتبار زنجیره
print(f"Blockchain valid: {blockchain.is_chain_valid()}")

#D: نمایش بلاک‌ها و تراکنش‌ها
for block in blockchain.chain:
    print(block)
    for tx in block.transactions:
        print(f"txt = {tx}")

این تیکه کد، یک نمونه ساده از استفاده از کلاس بلاکچین و متود  های اون را نشان می‌ده. در اینجا، یک ابجکت از کلاس Blockchain ایجاد می‌شود و  سه تراکنش برای ردیابی محصولات غذایی  اضافه می‌شه. بعد از اون تراکنش‌های معلق ماین شده و یک بلاک جدید به زنجیره اضافه می‌شود و  اعتبار زنجیره چک می‌شه و در نهایت بلاک‌ها و تراکنش‌ها نمایش داده می‌شود.


پ ن: توضیح عمقی تر درمورد کلاس Blockchain
مورد اول difficulty: این متغییر نشان می‌دهه که برای ماین کردن یک بلاک جدید چه تعداد صفر در ابتدای هش باید وجود داشته باشد.فرض کنید که مقدار difficulty در بلاکچین  برابر 3 باشد.
ب فرض کنیم ما بلاکی را می‌خواهیم ماین کنیم و هش بلاک  باید اینگونه باشد:
hash: 000abc123

دوم ()init: در این متد، زنجیره با ایجاد بلاک اول (genesis block) شروع می‌شود و لیست تراکنش‌های در انتظار برای ماین کردن خالی می‌شود.

سوم:create_genesis_bloc()k: این متد بلاک اول یا genesis block را با شماره بلاک 0، هش بلاک قبلی صفر، زمان فعلی و بدون تراکنش ایجاد می‌کند. معمولا بلاک اول زنجیره رو خوومون درست میکنیم و بدون تراکنش و هش صفر

چهار: get_latest_block(): این متد آخرین بلاک در زنجیره را برمی‌گرداند.

پنج:add_transaction(transaction): این متد یک تراکنش را به لیست تراکنش‌های در انتظار برای ماین کردن اضافه می‌کند.

شش:mine_pending_transactions: این متد تمام تراکنش‌های در انتظار را ماین می‌کند و بلاک حاوی آن‌ها را به زنجیره اضافه می‌کند.

هفت:mine_block(block): این متد یک بلاک را با استفاده از الگوریتم Proof of Work ماین می‌کند، تا هش بلاک با تعداد صفرهای مشخص (بر اساس difficulty) شکل بگیرد.

هشت:()is_chain_valid: این متد بررسی می‌کند که زنجیره فعلی اعتبار دارد یا نه، با مقایسه هش‌های بلاک‌ها و هش‌های محاسبه شده.
#blo

#blockchain

@Code_Crafters
🔥6
راه‌هایی برای بهینه‌سازی کوئری‌های SQL

پایگاه داده جزء ضروری بسیاری از سازمان‌ها در دنیای داده‌محور امروزی تبدیل شده‌اند. با توجه به اینکه بسیاری از شرکت‌ها داده‌های خود را در فضای ابری پردازش و ذخیره می‌کنند، بهینه‌سازی کوئری‌ها از اهمیت بیشتری برای بهبود عملکرد و کاهش هزینه‌ها برخوردار شده است.

در این مقاله، به بررسی تکنیک‌های موثری برای افزایش سرعت عملکرد کوئری‌های SQL می‌پردازیم. چندین راه برای بهینه‌سازی کوئری‌های SQL وجود دارد که در ادامه توضیح داده شده‌اند.

1. کاهش استفاده از کاراکترهای وایلدکارت (wildcard)
استفاده از کاراکترهای وایلدکارت مانند % و _ در کوئری‌های SQL می‌تواند عملکرد کوئری را کند کند. زمانی که از کاراکترهای وایلدکارت استفاده می‌شود، پایگاه داده باید کل جدول را برای یافتن داده‌های مرتبط بررسی کند. برای بهینه‌سازی کوئری‌های SQL، لازم است استفاده از کاراکترهای وایلدکارت را به حداقل برسانیم و تنها در مواقع ضروری از آن‌ها استفاده کنیم.

به عنوان مثال، برای یافتن تمام مشتریانی که نام خانوادگی شهرشان با حرف "P" شروع می‌شود، کوئری زیر استفاده می‌شود:

SELECT * FROM customers WHERE last_name_city LIKE 'P%';


این کوئری کار می‌کند، اما کندتر از کوئری است که از ایندکس (Index) استفاده می‌کند. می‌توان کوئری را با افزودن ایندکس به ستون last_name_city بهبود بخشید و آن را به شکل زیر نوشت:

SELECT * FROM customers WHERE last_name_city >= 'P' AND last_name < 'Q';


این کوئری از ایندکس استفاده می‌کند و سریع‌تر از کوئری قبلی خواهد بود.

2. افزایش عملکرد کوئری با استفاده از ایندکس‌ها
استفاده از ایندکس‌ها می‌تواند سرعت کوئری‌های SQL را افزایش دهد، زیرا پایگاه داده می‌تواند به سرعت ورودی‌هایی را که با معیارهای خاصی مطابقت دارند پیدا کند. ایندکس‌گذاری فرآیندی است که مقادیر یک یا چند ستون از یک جدول را به یک مقدار منحصر به فرد نقشه‌برداری می‌کند که جستجوی ردیف‌هایی که با یک مقدار خاص یا محدوده‌ای از مقادیر مطابقت دارند را آسان می‌کند.

برای بهبود کوئری‌های SQL، می‌توان ایندکس‌هایی بر روی ستون‌هایی که به طور مکرر در عبارات WHERE، JOIN و ORDER BY استفاده می‌شوند ایجاد کرد. اما ایجاد ایندکس‌های زیاد می‌تواند عملیات اصلاح داده‌ها مانند INSERT، UPDATE و DELETE را کند کند. در انتخاب ستون‌هایی که باید ایندکس شوند و نوع ایندکس‌هایی که باید استفاده شوند، باید تعادلی بین عملکرد خواندن و نوشتن برقرار کرد.

برای یافتن تمام سفارش‌هایی که توسط یک مشتری خاص انجام شده‌اند، می‌توان از کوئری زیر استفاده کرد:

SELECT * FROM orders WHERE customer_number = 2154;


اگر جدول سفارش‌ها حاوی تعداد زیادی رکورد باشد، این کوئری ممکن است زمان زیادی طول بکشد زیرا پایگاه داده باید کل جدول را برای یافتن ورودی‌های مطابق با شماره مشتری جستجو کند. می‌توان یک ایندکس بر روی ستون customer_number ایجاد کرد تا کوئری بهبود یابد:

CREATE INDEX idx_orders_customer_number ON orders (customer_id);


این ایندکس بر روی ستون customer_number جدول orders ایجاد می‌شود. حالا وقتی کوئری را اجرا می‌کنید، پایگاه داده می‌تواند با استفاده از ایندکس، به سرعت ردیف‌هایی که با شماره مشتری مطابقت دارند را پیدا کند که می‌تواند عملکرد کوئری را بهبود بخشد.

3. استفاده از نوع داده‌های مناسب
استفاده از نوع داده‌های مناسب برای ستون‌ها در یک پایگاه داده می‌تواند به طور قابل توجهی عملکرد کوئری‌ها را بهبود بخشد. به عنوان مثال، استفاده از نوع داده عددی برای ستونی که حاوی مقادیر عددی است می‌تواند باعث شود کوئری‌ها سریع‌تر از زمانی که نوع داده متنی استفاده می‌شود اجرا شوند. استفاده از نوع داده صحیح همچنین به تضمین یکپارچگی داده‌ها کمک می‌کند و می‌تواند از خطاهای تبدیل داده جلوگیری کند.

فرض کنید جدولی داریم که هر ردیف آن نمایانگر جزئیات سفارش‌های یک فروشگاه خرده‌فروشی است. این جدول ستون‌هایی برای شناسه سفارش، شناسه مشتری، تاریخ سفارش و مجموع سفارش دارد. ستون مجموع سفارش حاوی مقادیر عددی است. اگر ستون مجموع سفارش به عنوان نوع داده متنی ذخیره شود، کوئری‌هایی که محاسبات روی مجموع سفارش انجام می‌دهند کندتر از زمانی خواهد بود که ستون به عنوان نوع داده عددی ذخیره شده باشد.

#SQL
@Code_Crafters
🔥4
4. اجتناب از استفاده از زیرکوئری‌ها (subqueries)
زیرکوئری‌ها می‌توانند عملکرد کوئری را کند کنند، به خصوص زمانی که در عبارات WHERE یا HAVING استفاده می‌شوند. لازم است تا حد ممکن از زیرکوئری‌ها اجتناب شود و از JOIN یا تکنیک‌های دیگر استفاده شود.

به عنوان مثال، برای یافتن تمامی مشتریانی که در 30 روز گذشته سفارشی ثبت کرده‌اند، کوئری زیر از یک زیرکوئری برای یافتن تمامی شناسه‌های سفارش در 30 روز گذشته استفاده می‌کند:
```
SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_date >= DATEADD(day, -30, GETDATE()));


این کوئری کار می‌کند، اما کندتر از کوئری است که از JOIN برای یافتن داده‌های مرتبط استفاده می‌کند. کوئری زیر از JOIN برای یافتن تمامی مشتریانی که در 30 روز گذشته سفارشی ثبت کرده‌اند استفاده می‌کند:

SELECT DISTINCT c.* FROM customers c JOIN orders o ON c.customer_id = o.customer_id WHERE o.order_date >= DATEADD(day, -30, GETDATE());


این کوئری جدول customers را با جدول orders پیوند می‌دهد و اطلاعات تمامی مشتریانی که در 30 روز گذشته سفارشی ثبت کرده‌اند را بازیابی می‌کند. این کوئری سریع‌تر از کوئری قبلی خواهد بود زیرا از زیرکوئری استفاده نمی‌کند.

5. استفاده از LIMIT یا TOP برای محدود کردن تعداد ردیف‌های بازگشتی
باید از عبارت LIMIT یا TOP برای محدود کردن تعداد ردیف‌های بازگشتی در کوئری‌های SQL استفاده شود. این کار باعث می‌شود داده‌های کمتری پردازش و بازگردانده شود.
(این مورد بستگی به نوع پایگاه داده دارد مثلا SQL Server از Top پشتیبانی میکند در حالی که PostgreSQL و MySQL از Limit پشتیبانی میکنند )
برای مثال، اگر بخواهیم تمامی مشتریانی که در 27 روز گذشته سفارشی ثبت کرده‌اند را پیدا کنیم و تعداد زیادی از مشتریان در این مدت سفارش داده‌اند، کوئری می‌تواند تعداد زیادی ردیف بازگرداند. این کوئری را می‌توان با استفاده از LIMIT یا TOP بهینه کرد. کوئری زیر تعداد ردیف‌های بازگشتی را به 10 محدود می‌کند:

SELECT TOP 10 * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_date >= DATEADD(day, -27, GETDATE()));


این کوئری تنها 10 ردیف اولی که با معیارها مطابقت دارند را بازمی‌گرداند که باعث بهبود عملکرد کوئری خواهد شد.

6. اجتناب از استفاده از SELECT *
استفاده از عبارت SELECT * می‌تواند عملکرد کوئری را کند کند زیرا تمامی ستون‌های یک جدول را بازمی‌گرداند، حتی آن‌هایی که برای کوئری لازم نیستند. برای بهینه‌سازی کوئری‌های SQL، مهم است که تنها ستون‌هایی را که برای کوئری لازم هستند انتخاب کنید.

به عنوان مثال، برای یافتن تمامی مشتریانی که در 30 روز گذشته سفارشی ثبت کرده‌اند، کوئری زیر تمامی ستون‌ها از جدول customers را انتخاب می‌کند:

SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_date >= DATEADD(day, -30, GETDATE()));


برای بهینه‌سازی این کوئری، می‌توان عبارت SELECT را تغییر داد تا تنها ستون‌های مورد نیاز را انتخاب کند:

SELECT customer_id, first_name, last_name FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_date >= DATEADD(day, -30, GETDATE()));


این کوئری تنها ستون‌های customer_id، first_name و last_name را انتخاب می‌کند که عملکرد کوئری را بهبود می‌بخشد.

#SQL
@Code_Crafters
2
یه مورد دیگه ای هم خودم اضافه کنم که به نظرم لازمه گاهی اوقات لازمه که یک همچنین کوئری بزنید که بررسی کند که یک مقداری وجود دارد یا خیر که در نوشتن پروسیجر ها بسیار مرسوم است:
 
IF EXISTS(SELECT * FROM dbo.Employee AS em WHERE em.Id = 1)
BEGIN
PRINT('exist')
RETURN;
END
PRINT('not found')

در حالی که شما هیچ نیازی به موارد پاس داده شده از طرف جدول ندارید
پس میتوانید کوئری خود را به این صورت اصلاح کنید که بهتر است
 
IF EXISTS(SELECT 1 FROM dbo.Employee AS em WHERE em.Id = 1)
BEGIN
PRINT('exist')
RETURN ;
END
PRINT('not found')

به جای عملکرد * از عدد یا حروف به شکل 'A' میتوان استفاده کرد که اگر مقداری با شرط ما پیدا کرد را برگرداند که عملکرد بهتری دارد

در این کد بخش های پرینت و شرط و.. T-SQL است و به موضوع پست مربوط نیست تنها قصدم نشان دادن کاربردی تره موضوع بود.

#SQL
@Code_Crafters
2👍2😁1
7. استفاده از EXISTS به جای IN
عبارت IN یک مقدار را با لیستی از مقادیر بازگشتی از یک زیرکوئری مقایسه می‌کند. با این حال، استفاده از IN می‌تواند عملکرد کوئری را کند کند زیرا نیازمند اسکن کامل جدول بر روی زیرکوئری است. برای بهینه‌سازی کوئری‌های SQL، می‌توان از EXISTS به جای IN استفاده کرد.

به عنوان مثال، برای یافتن تمامی مشتریانی که در 30 روز گذشته سفارشی ثبت کرده‌اند:

SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM orders WHERE order_date >= DATEADD(day, -30, GETDATE()));


این کوئری از IN برای مقایسه شناسه مشتری با لیست شناسه‌های مشتری بازگشتی از زیرکوئری

استفاده می‌کند. برای بهینه‌سازی کوئری، می‌توان از EXISTS به جای IN استفاده کرد:

SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id AND o.order_date >= DATEADD(day, -30, GETDATE()));


این کوئری از EXISTS برای بررسی اینکه آیا ردیف مطابقی در جدول orders وجود دارد یا خیر استفاده می‌کند. این می‌تواند عملکرد کوئری را با اجتناب از اسکن کامل جدول بهبود بخشد.

8. استفاده از GROUP BY برای گروه‌بندی داده‌ها
عبارت GROUP BY برای گروه‌بندی ردیف‌ها بر اساس یک یا چند ستون استفاده می‌شود. این می‌تواند برای خلاصه کردن داده‌ها یا انجام توابع تجمعی بر روی گروه‌های داده مفید باشد. با این حال، استفاده از GROUP BY می‌تواند عملکرد کوئری را کند کند اگر به طور غیرضروری استفاده شود. برای بهینه‌سازی کوئری‌های SQL، باید تنها زمانی که ضروری است از GROUP BY استفاده کرد.

به عنوان مثال، برای یافتن تعداد کل سفارش‌های انجام شده توسط هر مشتری:

SELECT customer_id, COUNT(*) as order_count FROM orders GROUP BY customer_id;

این کوئری از GROUP BY برای گروه‌بندی ردیف‌ها بر اساس شناسه مشتری و شمارش تعداد سفارش‌های انجام شده توسط هر مشتری استفاده می‌کند. برای بهینه‌سازی کوئری، می‌توان از زیرکوئری برای بازیابی اطلاعات مشتری و پیوند آن با جدول orders استفاده کرد:

SELECT c.customer_id, c.first_name, c.last_name, o.order_count FROM customers c JOIN (SELECT customer_id, COUNT(*) as order_count FROM orders GROUP BY customer_id) o ON c.customer_id = o.customer_id;


این کوئری از زیرکوئری برای محاسبه تعداد سفارش‌های انجام شده توسط هر مشتری استفاده می‌کند و سپس نتیجه را با جدول customers برای بازیابی اطلاعات مشتری پیوند می‌دهد. این اجتناب از استفاده از GROUP BY می‌کند و می‌تواند عملکرد کوئری را بهبود بخشد.

9. استفاده از رویه‌های ذخیره‌شده (Stored Procedures)
رویه‌های ذخیره‌شده (Stored Procedures) دستورات SQL پیش‌کامپایل شده‌ای هستند که در پایگاه داده ذخیره می‌شوند. آن‌ها می‌توانند از یک برنامه یا مستقیماً از یک کوئری SQL فراخوانی شوند. استفاده از رویه‌های ذخیره‌شده می‌تواند عملکرد کوئری را با کاهش مقدار داده‌ای که بین پایگاه داده و برنامه ارسال می‌شود و با کاهش زمان لازم برای کامپایل و اجرای دستورات SQL بهبود بخشد.

#SQL
@Code_Crafters
🔥3👍2😁1
10. بهینه‌سازی طراحی پایگاه داده
بهینه‌سازی طراحی پایگاه داده نیز می‌تواند عملکرد کوئری را بهبود بخشد. این شامل اطمینان از نرمال‌سازی صحیح جداول و استفاده مؤثر از ایندکس‌ها است. علاوه بر این، مهم است که پایگاه داده برای بار کاری مورد انتظار به درستی تنظیم شود و برای سطح مناسب همزمانی (Concurrency) پیکربندی شود.

11. استفاده از ابزارهای بهینه‌سازی کوئری
انواع مختلفی از ابزارهای بهینه‌سازی کوئری موجود هستند که می‌توانند به شناسایی مشکلات عملکرد در کوئری‌های SQL کمک کنند. این ابزارها می‌توانند توصیه‌هایی برای بهبود عملکرد کوئری‌ها ارائه دهند، مانند ایجاد ایندکس‌ها، بازنویسی کوئری‌ها یا بهینه‌سازی طراحی پایگاه داده. برخی از ابزارهای محبوب بهینه‌سازی کوئری شامل Microsoft SQL Server Query Optimizer، Oracle SQL Developer و MySQL Query Optimizer هستند.

12. مانیتورینگ عملکرد کوئری
مانیتورینگ عملکرد کوئری یک گام مهم در بهینه‌سازی کوئری‌های SQL است. با مانیتورینگ عملکرد کوئری، می‌توان مشکلات عملکرد را شناسایی و تنظیمات مناسب را انجام داد. این می‌تواند شامل بهینه‌سازی ایندکس‌ها، بازنویسی کوئری‌ها یا تنظیم طراحی پایگاه داده باشد. برای ردیابی عملکرد کوئری، تعدادی ابزار موجود است، از جمله SQL Server Profiler، Oracle Enterprise Manager و MySQL Enterprise Monitor.

نتیجه‌گیری

بهینه‌سازی کوئری‌های SQL برای عملکرد سریع‌تر یک گام مهم در اطمینان از اجرای کارآمد برنامه‌های پایگاه داده است. از طریق این مقاله، می‌توانیم به نکات زیر برسیم:

- ایندکس‌گذاری مؤثرترین تکنیک برای افزایش عملکرد کوئری‌های SQL است، اما باید ملاحظات بین عملکرد خواندن و نوشتن را در نظر گرفت و تصمیم‌گیری کرد که کدام ستون‌ها باید ایندکس شوند و کدام نوع ایندکس‌ها باید استفاده شوند.(ایندکس ها مثل چاقو دو لبه هستند اگر اشتباه استفاده شوند میتوانند موجب سربار شوند اعمال کردن آنها به درستی نیاز به کمی تخصص دارد )
- بهینه‌سازی کوئری‌های SQL یک فرآیند پیوسته است و نیاز به مانیتورینگ و تنظیمات منظم برای اطمینان از بهبود مداوم عملکرد دارد.
- باید استفاده از عملیات هزینه‌بر مانند JOIN، GROUP BY، IN و زیرکوئری‌ها را به حداقل رساند تا عملکرد بهبود یابد.
- کوئری‌ها را بر روی مجموعه‌های داده واقعی آزمایش کنید تا اطمینان حاصل شود که بهینه‌سازی‌ها تأثیر مطلوبی دارند.

منبع

#SQL
@Code_Crafters
🔥3😁1
تاکتیک طراحی

تا کنون در خصوص چه چیزی و چرایی صحبت کردیم، ازین ببعد میخواهیم راجب چگونگی صحبت کنیم

پیاده سازی منطق تجاری ساده:
منطق تجاری مهمترین بخش یک نرم افزار است، و این همان چیزیست که نرم افزار در وهله اول پیاده سازی شده است، اگر نرم افزار مناسب یک منطق کسب و کار نباشد چیزی جز یک نمایش فناوری گران قیمت نیست

همه زیردامنه‌های تجاری یکسان ایجاد نمیشوند، حوزه‌های فرعی مختلف، سطوح مختلفی از اهمیت استراتژیک و پیچیدگی دارند، اکنون روش‌های مختلف مدلسازی و پیاده سازی کد و منطق کسب و کار رو فرا میگیریم.با دو الگوی مناسب منطق تجاری ساده شروع خواهیم کرد: اسکریپت تراکنش و سابقه فعال

اسکریپت تراکنش:
منطق تجاری را با رویه هایی سازماندهی می کند، که در آن هر رویه یک درخواست واحد از ارائه را مدیریت می کند

رابط عمومی یک سیستم را میتوان به عنوان مجموعه‌ای از معاملات تجاری که مصرف کنندگان میتوانند اجرا مشاهده کرد، این تراکنش‌ها میتوانند اطلاعات مدیریت سده توسط سیستم را بازیابی و اصلاح کنند، این الگو منطق تجاری سیستم را بر اساس رویه‌ها سازماندهی میکند، جایی که هر رویه عملیاتی را اجرا می‌کند که توسط مصرف کننده سیستم از طریق رابط عمومی آن اجرا میشود، عملیات عمومی سیستم بعنوان مرزهای کپسوله سازی استفاده می‌شود

پیاده سازی:
هر رویه، به عنوان یک اسکریپت رویه ای ساده و سرراست پیاده سازی می شود. می‌تواند از یک لایه انتزاعی نازک برای ادغام با مکانیسم های ذخیره سازی استفاده کند، اما دسترسی مستقیم به پایگاه های داده نیز امکان پذیر است. تنها الزامی که باید انجام شود رفتار معاملاتی است. هر عملیاتی باید یا با موفقیت یا شکست مواجه شود، اما هرگز نمی تواند منجر به وضعیت نامعتبر شود. حتی اگر اجرای یک اسکریپت تراکنش در ناخوشایندترین لحظه با شکست مواجه شود، سیستم باید ثابت بماند چه با برگرداندن تغییرات ایجاد شده تا زمان شکست یا با اجرای اقدامات جبرانی، این رفتار تراکنشی در نام الگو منعکس می شود: اسکریپت تراکنش.

الگوی اسکریپت تراکنش پایه‌ای برای الگوهای پیشرفته‌تر پیاده‌سازی منطق تجاری است، بیشتر مشکلات نرم افزاری بابت عدم درک و پیاده سازی این الگوهای ساده اولیه است (برای مثال: پردازش همزمان چندین رکورد توسط دیتابیس که میتواند ایجاد مشکل کند یا حتی عدم پشتیبانی، یا عدم توجه به اجرای صحیح و مرتب کوئری‌ها)

در سیستم‌های توزیع شده که از طریق کانال‌های پیام تغییرات در سیستم اطلاع رسانی می‌شود نیز میتواند حاصل مشکلاتی گردد(تصور کنید تغییری صورت گیرد و اطلاع رسانی به هر دلیلی با خرابی مواجه شود)

سیستم‌های توزیع شده مستعد خطا هستند و مشکلات فراوانی رو ایجاد میکند(الگوی CQRS راهکار آن است)
تصور کنید که سیستم داریم و مصرف کننده برای هر بازدید یک شمارنده از دیتابیس رو افزایش میده و رابط بین آنها یک متد لاگر است،یک متد یک کانال یک دیتابیس، اگر تحت هر شرایطی کانال بین لاگر و دیتابیس خراب شود یا لاگر و دیتابیس در یک برنامه باشد و ارتباط خودشون رو با مصرف کننده از دست بدهند چه اتفاقی خواهد افتاد، هربار مصرف با تصور دریافت خطا از سمت کانال مجدد رفتار خودش رو تکرار میکند و این مستعد ایجاد مشکل در دیتابیس خواهد شد(بجای افزایش یک واحد چندین واحد افزایش میدهد) ،مشکل ساده است اما راه حل آن ساده نیست، همه چیز به حوزه کسب و کار و نیازهای آن بستگی دارد، برای حل این مشکل راه حل ناتوان کردن عملیات مصرف کننده است، به دو شیوه میتوان اینکار را انجام داد ابتدا مصرف کننده مقدار رو از دیتابیس گرفته یک واحد افزایش داده و نتیجه را به کانال بفرستد، راه حل دوم این است که همراه افزاینده مقدار شمارنده رو هم برای کانال ارسال کند

زمان استفاده از اسکریپت تراکنش:
الگوی اسکریپت تراکنش بخوبی با ساده‌ترین حوزه‌های مسئله که در آن منطق تجاری شبیه عملیات رویه‌ای ساده است، سازگار است. به عنوان مثال، در عملیات استخراج-تغییر-بار (ETL)، هر عملیات داده ها را از یک منبع استخراج می کند، منطق تبدیل را برای تبدیل آن به شکل دیگری اعمال می کند و نتیجه را در مقصد بارگذاری می کند.

الگوی اسکریپت تراکنشی بصورت پیش فرض مناسب زیردامنه‌های پشتیبانی است که منطق تجاری ساده‌ای دارن، مزیت اصلی آن سادگی آن است. حداقل انتزاعات را معرفی می کند و سربار را هم در عملکرد زمان اجرا و هم در درک منطق تجاری به حداقل می رساند. لذا استفاده از ان در زیردامنه‌های عمومی یا بعنوان لایه ضدفساد(ACL) مناسب است

هرچقدر منطق کسب و کار پیچیده‌تر باشد موجب می‌شود که منطق تجاری بیشتر تکرار شده و مستعد ناسازگاری سده و کد تکراری از همگام خارج شود، لذا در زیردامنه‌های اصلی که پیچیدگی در آن زیاد است نباید از الگوی اسکریپت تراکنشی استفاده کرد


#DDD
#domain_driven_design

@code_crafters
7
این الگو در همه جا دیده می‌شود اما شهرت آن مورد تردید قرار گرفت و گاها بعنوان ضد الگو شناخته می‌شود، به هرحال اگر در منطق‌های پیچیده کسب و کار از آن استفاده کنید ذره ذره به یک توپ گنده غیرقابل نگهداری تبدیل میشود


رکورد فعال(active record):
یک شی که یک ردیف را در جدول یا نمای پایگاه داده می پیچد، دسترسی به پایگاه داده را کپسوله می کند و منطق دامنه را روی آن داده اضافه می کند, شبیه الگوی اسکریپت تراکنشی حالت‌های مختلفی رو پشتیبانی میکند، جاییکه منطق تجاری ساده است، با این حال منطق تجاری ممکن است بر روی ساختار داده گسترده تری مانند درختان کار کند

پیاده سازی:
در نتیجه، این الگو از اشیاء اختصاصی، معروف به رکوردهای فعال، برای نمایش ساختارهای داده پیچیده استفاده می کند. جدا از ساختار داده، این اشیاء همچنین روش‌های دسترسی به داده‌ها را برای ایجاد عملیات CRUD پیاده‌سازی می‌کنند. در نتیجه، اشیاء رکورد فعال به یک (ORM) یا برخی چارچوب های دسترسی به داده، دیگر جفت می شوند. نام الگو از این واقعیت گرفته شده است که هر ساختار داده "فعال" است. یعنی منطق دسترسی به داده ها را پیاده سازی می کند. مانند الگوی قبلی، منطق تجاری سیستم در یک اسکریپت تراکنش سازماندهی شده است. تفاوت بین این دو الگو این است که در این مورد، به جای دسترسی مستقیم به پایگاه داده، اسکریپت تراکنش اشیاء رکورد فعال را دستکاری می کند. وقتی کامل شد، عملیات باید به عنوان یک تراکنش اتمی یا کامل شود یا شکست بخورد

هدف الگو کپسوله کردن پیچیدگی نگاشت شی درون حافظه به طرح پایگاه داده است. علاوه بر مسئولیت ماندگاری، اشیاء رکورد فعال می توانند دارای منطق تجاری باشند. به عنوان مثال، اعتبارسنجی مقادیر جدید اختصاص داده شده به فیلدها، یا حتی اجرای رویه های مرتبط با کسب و کار که داده های یک شی را دستکاری می کند. همانطور که گفته شد، ویژگی متمایز یک شی رکورد فعال، جداسازی ساختارهای داده و رفتار (منطق تجاری) است. معمولاً، فیلدهای یک رکورد فعال دارای گیرنده‌ها و تنظیم‌کننده‌های عمومی هستند که به روش‌های خارجی اجازه می‌دهند حالت آن را تغییر دهند.

زمان پیاده سازی:
از آنجا که یک رکورد فعال اساساً یک اسکریپت تراکنش است که دسترسی به پایگاه‌های داده را بهینه می‌کند، این الگو تنها می‌تواند از منطق تجاری نسبتاً ساده، مانند عملیات CRUD، که حداکثر، ورودی کاربر را تأیید می‌کند، پشتیبانی کند. بر این اساس، مانند الگوی اسکریپت تراکنش، الگوی رکورد فعال خود را به پشتیبانی از زیر دامنه‌ها، ادغام راه‌حل‌های خارجی برای زیر دامنه‌های عمومی، یا وظایف تبدیل مدل می‌دهد. تفاوت بین الگوها در این است که رکورد فعال به پیچیدگی نگاشت ساختارهای داده پیچیده در طرحواره پایگاه داده می پردازد.

این الگو نیز برای زیردامنه‌های عمومی یا وظایف تبدیل مدل مناسب است و در پیچیدگی‌های زیردامنه اصلی موجب مشکلات متعدد میگردد، این الگو از ساختار داده پیچیده مدل آگاه است و مناسب نگاشت طرحواره آن اما برای منطق‌های تجاری ساده مناسب است


عملگرا باشید:
اگرچه داده های کسب و کار مهم هستند و کدی که ما طراحی و ایجاد می کنیم باید از یکپارچگی آن محافظت کند، مواردی وجود دارد که در آنها رویکرد عملی مطلوب تر است.
بخصوص در سطوح بالای مقیاس، مواردی وجود دارد که تضمین‌های سازگاری داده‌ها را می‌توان تسهیل کرد. بررسی کنید که آیا خراب کردن وضعیت یک رکورد از 1 میلیون واقعاً یک عامل نمایشی برای تجارت است و آیا می تواند بر عملکرد و سودآوری کسب و کار تأثیر منفی بگذارد. برای مثال، فرض کنید شما در حال ساختن سیستمی هستید که روزانه میلیاردها رویداد را از دستگاه‌های IoT دریافت می‌کند. آیا اگر 0.001٪ از رویدادها تکراری یا گم شوند، مشکل بزرگی است؟
همه چیز به حوزه کاری که در آن کار می کنید بستگی دارد. فقط مطمئن شوید که ریسک ها و پیامدهای تجاری را ارزیابی کرده اید

#DDD
#domain_driven_design

@code_crafters
8
اگه دنبال کتاب تخصصی میگشتید
این یکی از بهترین سایت های ممکنه
فرانت سایتش به شدت داغونه😕
ولی از نظر عملکرد خیلی خوبه
مخزن کتاباهاش از z lib بیشتره🥳
همینطور نیاز به ورود هم نداره 🥰
و بر اساس ویژگی های بیشتری می‌توانید جست و جو و مرتب سازی کنید🔥

با پهپ زدنش😒🤢

https://libgen.is/

@Code_Crafters
👍112👎2😁2👏1
مقابله با منطق تجاری پیچیده

به مباحث منطق تجاری رسیدین قلب تپنده هر سیستمی در پست‌های قبلی دو الگوی ساده اسکریپت و الگوی فعال رو بررسی کردیم و در ادامه مباحث منطق تجاری، الگوی دامنه پیچیده رو بررسی میکنیم، الگوی «مدل دامنه» مجموع‌ها و اشیا ارزش بلوک‌های سازنده آن است

الگوی مدل دامنه برای مقابله با موارد منطق تجاری پیچیده در نظر گرفته شده است.
در اینجا، به‌جای رابط‌های CRUD، با انتقال‌های حالت پیچیده، قوانین تجاری، و متغیرها سروکار داریم: قوانینی که همیشه باید محافظت شوند. برای مثال یک سیستم مدیریت پیام بصورت ارزش گذاری روی پیام‌هارو در نظر بگیرید(یک سیستم help desk) که شامل یکسری الزامات هست که مانند یک شبکه درهم تنیده از وابستگی‌ها قوانینی که همگی بر چرخه حیات سیستم تاثیر گذار است، تلاش برای پیاده سازی این منطق با استفاده از اشیا رکورد فعال تکرار منطق را میسر میکند و با اجرای نادرست برخی قوانین تجاری، وضعیت سیستم را خراب میکند

پیاده‌سازی:
مدل دامنه یک مدل شی از دامنه است که هم رفتار و هم داده‌ها را در بر می‌گیرد. الگوهای تاکتیکی DDD - مجموع‌ها، اشیاء ارزش، رویدادهای دامنه و خدمات دامنه - بلوک‌های سازنده چنین مدل شی هستند. همه این الگوها منطق تجاری را در اولویت قرار می دهند

پیچیدگی:
منطق تحاری دامنه ذاتا پیچیده است، بنابراین در مدلسازی آن نباید پیچیدگی اضافی ایجاد کرد. مدل نباید درگیر نگرانی‌های زیرساختی و موارد مربوط به تکنولوژی باشد(مثه فراخوانی به پایگاه داده یا سایر اجزای خارجی سیستم) این محدودیت نیازمند آن است که اشیا مدل، اشیا قدیمی ساده باشند، اشیایی که منطق تجاری رو بدون تکیه و ترکیب مستقیم چارچوب زیرساختی پیاده سازی میکنند

زبان فراگیر:
تاکید بر منطق تجاری به جای نگرانی های فنی، پیروی از اصطلاحات زبان فراگیر بافت محدود را برای اشیاء مدل دامنه آسان تر می کند. به عبارت دیگر، این الگو به کد اجازه می‌دهد تا به زبان فراگیر صحبت کند و از مدل‌های ذهنی متخصصان حوزه پیروی کند

بلوک‌های ساختمانی:
بیایید به بلوک‌های ساختمانی مدل دامنه مرکزی یا الگوهای تاکتیکی ارائه‌شده توسط DDD نگاهی بیندازیم: اشیاء ارزشvalue object، مجموعه‌ها aggregate و خدمات دامنه domain service


شئ ارزش value object:
شئی است که با ترکیب مقادیر آن قابل شناسایی است (بجای هویت با خصوصیات آن شناسایی می‌شود)

برای مثال به کلاس فرد دقت کنید
class Person:
phone:int
name:str
email:str

این کلاس میتواند هر مقداری رو بگیرد و هیچگونه مقدار یکتایی رو نمیده، تیکه بر انواع داده‌های ابتدایی کتابخانه استاندارد زبان مانند رشته‌ها و اعداد صحیح برای نمایش مفاهیم حوزه کسب و کار بعنوان بوی کد اولیه obsession شناخته میشود، سیستم به کاربر نمیتواند اعتماد کند که همیشه مقادیر صحیح وارد کند لذا لازم است مقادیر اعتبارسنجی شود، این رویکرد ریسک های طراحی متعددی را ارائه می دهد. اول، منطق اعتبارسنجی تمایل به تکرار دارد. دوم، اجرای فراخوانی منطق اعتبارسنجی قبل از استفاده از مقادیر، دشوار است. در آینده، زمانی که پایه کد توسط مهندسان دیگر تکامل یابد، چالش برانگیزتر خواهد شد. به مقدار اصلاح شده زیر نگاه کنید

class Person:
phone:Phone
name:Name
email:Email

ابتدا وضوح در آن افزایش یافته است و در زبان فراگیر در حوزه کسب و کار، مفاهیم با همین اسامی صدا زده میشوند، دوم، نیازی به اعتبارسنجی مقادیر قبل از تخصیص نیست، زیرا منطق اعتبارسنجی در خود اشیاء ارزش قرار دارد. با این حال، رفتار یک شیء ارزشی به اعتبارسنجی صرف محدود نمی شود. اشیاء ارزشی زمانی که منطق تجاری را که ارزش ها را دستکاری می کند متمرکز می کنند، درخشانتر می‌شود. منطق منسجم در یک مکان پیاده سازی شده است و به راحتی قابل آزمایش است.

اشیاء ارزش نیاز به قراردادها را از بین می‌برند، برای مثال: نیاز به در نظر گرفتن این نکته که این رشته یک ایمیل است و رشته دیگر یک شماره تلفن است، و در عوض با استفاده از مدل شی ایجاد می‌کند. کمتر مستعد خطا و شهودی تر می‌باشد

زمان استفاده از اشیاء ارزشی
پاسخ ساده این است که هر زمان که بتوانید. نه تنها اشیاء ارزش کد را گویاتر می‌کنند و منطق تجاری را که تمایل به پراکندگی دارند در بر می‌گیرد، بلکه الگوی کد را ایمن‌تر می‌کند. از آنجایی که اشیاء ارزشی تغییرناپذیر هستند، رفتار اشیای ارزشی عاری از عوارض جانبی بوده و به صورت نخ است.

موجودیت‌ها:
یک موجودیت مخالف یک شیء ارزشی است. برای تمایز بین نمونه‌های مختلف موجودیت، به یک فیلد شناسایی صریح نیاز دارد


#DDD
#domain_driven_design

@code_crafters
6
شی ارزشی بر اساس خصوصیاتش متمایز میشد-دو شئ با خصوصیات یکسان یکی هستند-و تغییر ناپذیر، اما موجودیت یک هویت یکتایی دارد حتی اگر خصوصیات یکسانی داشته باشند و تغییرپذیر هم می‌باشند

برای مثال: کلاس شخص در مثال رو فقط با فیلد نام در نظر بگیرید، این فیلد یکتا نیست چون دو نفر میتوانند یک اسم داشته باشند هرچند هویت واقعی آنها جداست اما برای شناسایی کافی نیست لذا فیلدی مانند id یا کدملی نیز دارد، شرط اصلی فیلد شناسایی یکتا بودن آن است، موجودیت‌ها تغییر پذیرند و انتظار می‌رود تغییر کنند، موحودیت‌ها یک بلوک ساختمانی ضروری برای هر حوزه تجاری هستند، ما موجودیت‌ها رو در چارچوب الگوی کل اجرا میکنیم و به این دلیل در لیست بلوک‌های سازنده مدل دامنه قرار نمی‌دهیم

در پست‌های قبلی گفته بودم که اکانت کاربری یک موجودیت است اما پروفایل اون هویت است، کاربرد کلمه هویت‌ها در جایگاه استفاده معنای متفاوت است، لازم بذکر است که از دیدگاه DDD اکانت و پروفایل هردو موجودیت هستند که پروفایل بسته به طراحی و کاربرد آن می‌تواند یک موجودیت جدا باشد، منطق موجودیت اکانت بابت کنترل دسترسی و محدودیت است و منطق پروفایل مدیریت اطلاعات شخصی و نمایش آن است

تجمیع‌ها aggregate:
یک تجمیع در واقع یک موجودیت است، که انتظار میرود تغییر کند، هدف از این الگو محافظت از ثبات داده‌های آن است، از آنجا که داده‌های تجمیع قابل تغییر هستند پیامدها و چالش‌هایی وجود دارد که الگو باید برای ثابت نگه داشتن وضعیت خود در همه زمانها به آنها رسیدگی کند

اجرای سازگاری:
وضعیت یک تجمیع می تواند جهش یابد، که دریچه ای برای راه های متعددی ایجاد می کند که در آن داده های آن می توانند خراب شوند. برای اعمال سازگاری داده ها، الگوی کل یک مرز واضح بین کل و محدوده بیرونی آن ترسیم می کند: کل یک مرز اجرای سازگاری است. منطق تجمیع باید تمام اصلاحات دریافتی را تأیید کند و اطمینان حاصل کند که تغییرات با قوانین تجاری آن مغایرت ندارد. از منظر پیاده سازی، سازگاری با اجازه دادن به منطق تجاری تجمیع برای تغییر وضعیت آن اعمال می شود. تمام فرآیندها یا اشیاء خارج از تجمیع فقط مجاز به خواندن وضعیت تجمع هستند .حالت آن را فقط می توان با اجرای روش های مربوط به رابط عمومی تجمیع تغییر داد. مقابله با منطق تجاری پیچیده روش‌های تغییر حالت که به‌عنوان واسط عمومی یک تجمیع در معرض نمایش قرار می‌گیرند، اغلب به عنوان دستورات شناخته می‌شوند، مانند «فرمان انجام کاری». یک دستور به دو صورت قابل پیاده سازی است. اول، می توان آن را به عنوان یک روش عمومی ساده از شی انبوه پیاده سازی کرد: افزودن یک متد به موجودیت روت برای مثال یک کلاس سفارشات داریم که یک متد افزودن تعداد سفارشات در خود کلاس جاساز شده است. از طرف دیگر، یک فرمان را می توان به عنوان یک شی پارامتر نشان داد (اشیاء فرمان) که تمام ورودی های مورد نیاز برای اجرای دستور را محصور می کند: برای مثال متدی که شی را گرفته و متد افزودن را اجرا میکند

اطمینان از اینکه دیتابیس مدنظر از روش همزمانی پشتیبانی میکند الزامی است

مرز تراکنشی:
از آنجایی که وضعیت یک تجمیع فقط با منطق تجاری خودش قابل تغییر است، تجمیع به عنوان یک مرز معاملاتی نیز عمل می کند. تمام تغییرات در وضعیت کل باید به صورت یک عملیات اتمی انجام شود. اگر وضعیت یک تجمیع اصلاح شود، یا تمام تغییرات انجام می شود یا هیچ یک از آنها انجام نمی شود. علاوه بر این، هیچ عملیات سیستمی نمی تواند یک تراکنش چند انبوه را فرض کند. تغییر در وضعیت یک تجمیع فقط می تواند به صورت جداگانه انجام شود، یک تجمیع در هر تراکنش پایگاه داده. یک نمونه انبوه در هر تراکنش ما را مجبور می‌کند تا مرزهای تجمیع را با دقت طراحی کنیم، و اطمینان حاصل کنیم که طرح به تغییرات و قوانین حوزه کسب‌وکار می‌پردازد. نیاز به انجام تغییرات در تجمیع‌های متعدد، یک مرز تراکنش اشتباه و از این رو، مرزهای کل اشتباه را نشان می دهد. به نظر می رسد که این یک محدودیت مدل سازی را تحمیل می کند. اگر بخواهیم چندین شی را در یک تراکنش تغییر دهیم چه؟ بیایید ببینیم الگو چگونه چنین موقعیت‌هایی را نشان می‌دهد.
ما از موجودیت ها به عنوان یک الگوی مستقل استفاده نمی کنیم، بلکه تنها به عنوان بخشی از یک تجمیع در نظر میگیریم. بیایید تفاوت اساسی بین موجودیت ها و تجمیع‌ها را ببینیم، و اینکه چرا موجودیت ها به جای مدل دامنه فراگیر، بلوک ساختمانی یک تجمیع هستند

#DDD
#domain_driven_diven

@code_crafters
6
سناریوهای تجاری وجود دارد که در آنها چندین شی باید، یک مرز معاملاتی را به اشتراک بگذارند. به عنوان مثال، زمانی که هر دو را می‌توان به طور همزمان تغییر داد یا قوانین تجاری یک شی به وضعیت یک شی دیگر بستگی دارد. DDD تجویز می کند که طراحی یک سیستم باید توسط دامنه تجاری آن هدایت شود. تجمیع نیز از این قاعده مستثنی نیستند. برای پشتیبانی از تغییرات در اشیاء متعددی که باید در یک تراکنش اتمی اعمال شوند، الگوی تجمیع شبیه سلسله مراتبی از موجودیت‌ها است. سلسله مراتب شامل هر دو موجودیت و اشیاء ارزشی است و همه آنها در صورتی که به منطق تجاری دامنه محدود شوند به یک تجمیع تعلق دارند. به همین دلیل است که این الگو «تجمیع» نامیده می‌شود: این الگو نهادهای تجاری و اشیاء ارزشی را که به یک مرز معامله تعلق دارند، جمع‌آوری می‌کند. نمونه کد زیر یک قانون کسب‌وکار را نشان می‌دهد که چندین نهاد متعلق به مرز کل را در بر می‌گیرد. تجمیع تضمین می‌کند که همه شرایط در برابر داده‌های کاملاً سازگار بررسی می‌شوند، و پس از تکمیل بررسی‌ها با اطمینان از اینکه همه تغییرات در داده‌های کل به‌عنوان یک تراکنش اتمی انجام می‌شوند، تغییری نمی‌کند.

ارجاع به سایر تجمیع‌ها:
از آنجایی که تمام اشیاء موجود در یک تجمیع دارای مرز تراکنشی یکسانی هستند، در صورت بزرگ شدن بیش از حد یک تجمیع، ممکن است مسائل مربوط به عملکرد و مقیاس پذیری ایجاد شود. سازگاری داده ها می تواند یک اصل راهنمای مناسب برای طراحی مرزهای یک تجمیع باشد. فقط اطلاعاتی که توسط منطق تجاری کل مورد نیاز است تا به شدت سازگار باشد باید بخشی از کل باشد. تمام اطلاعاتی که در نهایت می‌توانند سازگار باشند، باید خارج از مرز تجمیع باشند. قاعده کلی این است که تجمیع‌ها تا حد امکان کوچک نگه داشته شوند و فقط اشیایی را در بر گیرد که طبق منطق تجاری تجمیع باید در یک حالت کاملاً سازگار باشند

ریشه تجمیع aggregate root:
با اسامی موجودیت ریشه root entity نیز شناخته می‌شود 

وضعیت یک تجمیع فقط با اجرای یکی از دستورات آن قابل تغییر است. از آنجایی که یک تجمیع نشان دهنده سلسله مراتبی از موجودیت ها است (هر تجمیع می‌تواند شامل چند موجودیت باشد)، تنها یکی از آنها باید به عنوان رابط عمومی تجمیع تعیین شود. برای مثال در بافت محدود به سیستم تیکتینگ و موجودیت‌های آن که شامل ticket, messages, attachments ، میشود ticket بعنوان root شناخته میشود

علاوه بر رابط عمومی ریشه تجمیع، مکانیسم دیگری وجود دارد که از طریق آن دنیای بیرونی می تواند با تجمیع‌ها ارتباط برقرار کند: رویدادهای دامنه domain events

رویدادهای دامنه domain events:
رویداد دامنه پیامی است که رویداد مهمی را که در حوزه کسب و کار رخ داده است توصیف می کند. برای مثال: بلیط اختصاص داده شده، بلیط افزایش یافته،پیام دریافت شده.
از آنجایی که رویدادهای دامنه چیزی را توصیف می کنند که قبلاً اتفاق افتاده است، نام آنها باید در زمان گذشته فرموله شود. هدف یک رویداد دامنه توصیف آنچه در حوزه کسب و کار اتفاق افتاده و ارائه تمام داده های لازم مربوط به رویداد است. به عنوان مثال، رویداد دامنه زیر نشان می دهد که بلیط خاص، در چه زمانی و به چه دلیل افزایش یافته است

مانند همه چیز در مهندسی نرم افزار، نامگذاری نیز مهم است. اطمینان حاصل کنید که نام رویدادهای دامنه به طور خلاصه منعکس کننده آنچه در حوزه کسب و کار اتفاق افتاده است. رویدادهای دامنه بخشی از رابط عمومی یک مجموعه هستند. یک مجموعه رویدادهای دامنه خود را منتشر می کند. سایر فرآیندها، تجمیع‌ها یا حتی سیستم‌های خارجی می‌توانند در پاسخ به رویدادهای دامنه، مشترک شوند و منطق خود را اجرا کنند

زبان فراگیر:
آخرین اما نه کم‌اهمیت‌ترین، تجمیع‌ها باید انعکاسی از زبان فراگیر باشند. اصطلاحاتی که برای نام تجمیع، اعضای داده‌های آن، اقدامات و رویدادهای دامنه آن استفاده می‌شود، همگی باید به زبان فراگیر بافت محدود فرموله شوند. کد باید بر اساس همان زبانی باشد که توسعه دهندگان هنگام صحبت با یکدیگر و با کارشناسان حوزه از آن استفاده می کنند. این امر به ویژه برای اجرای منطق پیچیده تجاری مهم است

خدمات دامنه domain service:
دیر یا زود، ممکن است با منطق تجاری مواجه شوید که یا به هیچ شیء تجمیع یا ارزشی تعلق ندارد، یا به نظر می رسد که به چندین مجموعه مرتبط باشد. در چنین مواردی، طراحی دامنه محور پیشنهاد می کند که منطق را به عنوان یک سرویس دامنه پیاده سازی کند. یک سرویس دامنه یک شیء بدون حالت است که منطق تجاری را پیاده سازی می کند. در اکثریت قریب به اتفاق موارد، چنین منطقی فراخوانی به اجزای مختلف سیستم را برای انجام برخی محاسبات یا تجزیه و تحلیل هماهنگ می کند.

#DDD
#domain_driven_design

@code_crafters
5
خدمات دامنه، هماهنگی بین چندین مجموعه را آسان می کند.اما مهم است که همیشه محدودیت الگوی تحمیع را برای اصلاح تنها یک نمونه از یک مجموعه در یک تراکنش پایگاه داده در نظر داشته باشید(خدمات دامنه یک راه گریز برای آن نیست) قانون یک نمونه در هر تراکنش همچنان وجود دارد. در عوض، سرویس‌های دامنه خود را به پیاده‌سازی منطق محاسباتی که نیازمند خواندن داده‌های چند مجموعه است، می‌دهند. سرویس دامنه فقط یک شیء بدون حالت است که برای میزبانی منطق تجاری استفاده می شود.

مدیریت پیچیدگی:
همانطور که در مقدمه این فصل اشاره شد، الگوهای شی تجمیع و ارزش به عنوان ابزاری برای مقابله با پیچیدگی در اجرای منطق تجاری معرفی شدند. بیایید دلیل پشت این موضوع را ببینیم
به گفته گلدرات، هنگام بحث در مورد پیچیدگی یک سیستم، ما علاقه مندیم که دشواری کنترل و پیش بینی رفتار سیستم را ارزیابی کنیم.  این دو جنبه توسط درجات آزادی سیستم منعکس می شود. درجات آزادی یک سیستم، نقاط داده مورد نیاز برای توصیف وضعیت آن است

الگوهای شی تجمیع و ارزش، ثابت ها را محصور می کنند و در نتیجه پیچیدگی را کاهش می دهند.
تمام منطق تجاری مربوط به وضعیت یک شی ارزش در مرزهای آن قرار دارد.
همین امر در مورد سنگدانه ها نیز صادق است. یک مجموعه را فقط می توان با روش های خاص خود اصلاح کرد. منطق تجاری آن، متغیرهای کسب و کار را محصور می کند و از آن محافظت می کند، بنابراین درجات آزادی را کاهش می دهد.
از آنجایی که الگوی مدل دامنه فقط برای زیر دامنه‌هایی با منطق تجاری پیچیده اعمال می‌شود، می‌توان فرض کرد که اینها زیردامنه‌های اصلی - قلب نرم‌افزار هستند.


#DDD
#domain_driven_design


@code_crafters
8
37 Important Linux Commands You Should Know.pdf
2 MB
37 دستور پر کاربرد لینوکس

ترجمه و سند شده توسط اعضای کانال (جناب امیر)


#linux
@code_crafters
9
در پست قبلی درباره الگوی مدل دامنه حرف زدیم(بلوک‌های سازنده، هدف و زمینه کاربردی آن) الگوی مدل دامنه منبع رویداد بر اساس همان فرض الگوی مدل دامنه است، منطق تجاری پیچیده و متعلق به زیردامنه‌ اصلی است و از الگوهای تاکتیکی مانند اشیا ارزش، تجمیع‌ها و رویدادهای دامنه استفاده می‌کند. تفاوت بین آنها به تداوم وضعیت، تجمیع نهفته وابسته است، مدل دامنه منبع رویداد از الگوی منبع‌یابی رویداد برای مدیریت حالت‌های تجمیع استفاده میکند(مدل بجای تداوم وضعیت یک تجمیع، رویدادهای دامنه رو تولید میکنه، که هر تغییر رو توصیف و از آنها بعنوان منبع حقیقت برای داده‌های تجمیع استفاده می‌کند)

در این بخش با معرفی مفهوم منبع رویداد، ترکیب آن با الگوی مدل دامنه و تبدیل آن به یک مدل دامنه منبع رویداد، صحبت میکنیم

منبع یابی رویداد:
نمودار جریان خود را به من نشان دهید و جداول خود را پنهان کنید، و من همچنان مرموز خواهم بود. جداول خود را به من نشان دهید، و من معمولاً به فلوچارت شما نیاز نخواهم داشت.  آشکار خواهد شد

بیایید از استدلال بالا برای تعریف الگوی منبع یابی رویداد استفاده کنیم و تفاوت آن با مدل سازی سنتی و تداوم داده ها را درک کنیم. تصویر اول در کامنت‌ها را بررسی کنید و آنچه را که می توانید از این داده ها در مورد سیستمی که به آن تعلق دارد بیاموزید، تجزیه و تحلیل کنید.

این یک جدول بازاریابی است که شامل افراد و وضعیت انها می‌باشد که status فیلد وضعیت هر کاربر را مشخص میکند(نفر جدید، خرید شده، عدم خرید و بسته)

این اطلاعات بسیار زیادی است که می‌توانیم فقط با تجزیه و تحلیل طرحواره جدول و داده‌های ذخیره شده در آن جمع‌آوری کنیم. حتی می‌توانیم فرض کنیم که هنگام مدل‌سازی داده‌ها از چه زبانی استفاده شده است. اما از فرآیند کاری که روی هر مشتری صورت گرفته اطلاعی نداریم و این موجب نگرانی‌های کسب و کار می‌شود و نمیتوان تصمیمات درستی در مورد هر مشتری گرفت، حال اگر یه فیلد version روی مدل بزاریم و بابت هر مرحله مشخص انجام شده یک مقدار عددی به آن نسبت بدهیم با یک نگاه گذرا می‌توان به یک سفر در گذشته رفت، برای مثال: مقدار ۱ اطلاعات از مشتری گرفته شده، مقدار ۲ کارشناسان با مشتری تماس گرفته‌اند، مقدار ۳ تاییدیه از مشتری گرفته شده است و ... علاوه بر ان میتوان پی برد چه تعداد مشتری در چه بخش یا واحد سازمان هستند و تحلیل‌های بسیار دیگری
برای مثال این نوع رویکرد در سفارشات یک فروشگاه از درخواست تا مرحله تحویل را زیر نظر گرفت برای مثال: -ساخت سبد(0)»افزودن کالا(1)»ثبت سبد(2)»پرداخت(3)»در حال بررسی(4)»تخصیص منابع(5)»ارسال(6)»تحویل(7)-

تجزیه و تحلیل:
بخش هوش تجاری از شما میخواهد در مدل خود برنامه تماس‌های آینده با مشتریان رو فراهم کنید و به این ترتیب با فیلتر این بخش و بخش قبلی به پیش بینی بپردازند، شما باید این پیش بینی رو جایی نگهداری کنید تا بعدا در دسترس باشد، این فرآیند در الگوی CQRS صورت میگرد که در آینده راجب آن حرف خواهیم زد

منبع حقیقت:
برای اینکه الگوی منبع یابی رویداد کار کند، همه تغییرات در وضعیت یک شی باید به عنوان رویداد نشان داده شود و ادامه یابد. این رویدادها منبع حقیقت سیستم می شوند. مجموعه منبع رویداد پایگاه داده ای که رویدادهای سیستم را ذخیره می کند، تنها ذخیره سازی کاملاً سازگار است: منبع حقیقت سیستم است، نام پذیرفته شده برای پایگاه داده ای که برای رویدادهای ماندگار استفاده می شود، ذخیره رویداد است.

ذخیره رویداد:
ذخیره رویداد نباید اجازه تغییر یا حذف رویدادها را بدهد، برای پشتیبانی از اجرای الگوی منبع یابی رویداد، حداقل ذخیره رویداد باید از عملکرد زیر پشتیبانی کند: واکشی همه رویدادهای متعلق به یک نهاد تجاری خاص و پیوست رویدادها.

منبع رویداد مدل دامنه:
مدل اصلی دامنه یک نمایش از حالت تجمیع خود را حفظ می‌کند و رویدادهای دامنه انتخابی را منتشر می‌کند. مدل دامنه منبع رویداد، بطور انحصاری از رویدادهای دامنه برای مدل‌سازی چرخه عمر تجمیع‌ها استفاده می‌کند(تمام تغییرات در وضعیت یک تجمیع باید بعنوان رویدادهای دامنه بیان شوند)

بیایید برخی از مزایای استفاده از منابع رویداد هنگام اجرای منطق پیچیده تجاری نگاهی بیندازیم.

مزایا:
در مقایسه با مدل سنتی تر، که در آن حالت های فعلی مجموع ها در یک پایگاه داده حفظ می شود، مدل دامنه منبع رویداد به تلاش بیشتری برای مدل سازی کل نیاز دارد. با این حال، این رویکرد دارای مزایای قابل توجهی است که باعث می شود الگو در بسیاری از سناریوها مورد توجه قرار گیرد:

#DDD
#domain_driven_design

@code_crafters
4👍1