جلسه پنجم دوره آموزشی domain driven design به تدریس مهندس علیرضا ارومند با موفقیت برگزار شد.
مباحثی که در این جلسه مطرح شد به شرح ذیل است:
جلسه پنجم دوره DDD آخرین جلسهای بود که الگوهای طراحی نرم افزار پرداختیم و الگوهای باقی مانده را در این جلسه مورد بررسی قرار دادیم. در ادامه به بررسی الگوهایی که در این جلسه مورد بررسی قرار دادیم میپردازیم.
الگوی Adapter
ابتدا به سراغ یکی از الگوهای پرکاربرد یعنی الگوی Adapter رفتیم. حتما در دنیای واقعی هم برای شما اتفاق افتاده که نیاز به آداپتور داشته باشید. مثلا زمانی که گوشی موبایل خود را شارژ میکنیم نیاز به برق ورودی با ولتاژ و جریانی متفاوت از برق شهر داریم. پس از ابزاری استفاده میکنیم که کار تبدیل ولتاژ برق شهری به ولتاژ مورد انتظار ما را انجام میدهد. همین اتفاق هنگام توسعه برنامهها نیز میافتد و مواردی داریم که عملکرد ما در یک شی دیگر وجود دارد ولی کمی متفاوت و نیاز داریم که ساختارها را یکی کنیم. اینجا الگوی Adapter به کار میآید و به کمک این الگو میتوانیم مشکلات را برطرف کنیم که نحوه طراحی و پیاده سازی این الگو را در این قسمت بررسی کردیم.
الگوی Composit
الگوی بعدی که به سراغ آن رفتیم الگوی Composit بود. به جرات میتوان گفت یکی از پرکاربرد ترین الگوهای طراحی نرم افزار همین الگوی Composit است. معمولا در برنامه ها با ساختارهای درختی سر و کار داریم. برای مثال زمانی که منوی سایت را درست میکنیم یا هنگام پیاده سازی چارت سازمانی با ساختارهای درختی سر و کار داریم. نکتهای که در این ساختارها وجود دارد این است که هر سطح از این درخت میتواند قواعد منحصر به فرد خود را داشته باشد اما در انتها احتمالا ساختارهایی وجود دارد که بین تمامی این موارد یکی است و میخواهیم کارهایی را به صورت مشترک بین تمامی سطوح درخت به اشتراک انجام دهیم. در صورت عدم استفاده از الگوی Composit احتمالا پردازش این ساختارها میتواند سخت و پیچیده باشد. اما به کمک الگوی Composit این پیچیدگیها کاهش یافته و به یک راه حل تمیز و اصولی برای پیاده سازی این موارد میرسیم. الگوی Composit را به طور کامل بررسی کردیم و انواع کاربردهای آن را خدمت دوستان معرفی کردیم.
الگوی Flyweight
سومین الگویی که در این جلسه مورد بررسی قراردادیم الگوی Flyweight بود. هنگام طراحی اشیا دادهها و عملکردهای مختلفی را برای آنها در نظر میگیریم. اما هنگامی که با حجم وسیعی از نسخههای یک کلاس مواجه میشویم بعضا به مشکلاتی مانند مدیریت حافظه برمی خوریم. با یک بررسی کلی در میابیم که کلاسهای ما میتوانند به دو قسمت تشکیل شوند. بخشی که بین تمام نمونهها میتواند مشترک باشد و بخش اختصاصی به هر نسخه از کلاس. الگوی Flyweight راهنمای ما جهت جداسازی بهینه این قسمتها از هم میباشد.
کنترل دسترسی به اشیا یکی از نیازهای همیشگی توسعه میباشد. این کنترل دسترسی میتواند دلایل مختلفی داشته باشد. مثلا میخواهیم بررسی کنیم در صورت وجود نسخه ای از اطلاعات در کش از نسخه کش شده استفاده کنیم و در غیر این صورت از دیتابیس برای واکشی و ذخیره در کش استفاده کینم. خوب در صورتی که این عملکرد را در تابع واکشی اطلاعات پیاده سازی کنیم تابع ما اصول SOLID را رعایت نکرده و قابلیت توسعه و نگهداری سیستم به شدت کاهش مییابد. الگوی Proxy راهکاری را برای حل این مشکلات برای ما ارائه میکنید که در این قسمت از کلاس این الگو و مزایا و معایب آن را بررسی کردیم و دسته بندیهای مختلفی از آن مثل Remote proxy, Virtual proxy, Protection proxy و Smart proxy را مورد بررسی قرار دادیم.
الگوی Mediator
یکی دیگر از الگوهایی که در این جلسه بررسی کردیم الگوی Mediatorبود. حتما در دنیای برنامه نویسی مشاهده کرده اید که اشیا نیاز دارند با هم تعامل کنند و اطلاعات رد و بدن کنند. خوب هر تبادل اطلاعاتی ۲ طرف دارد یک ارسال کننده و یک دریافت کننده. تا اینجای کار مشلکلی وجود ندارد. اما وقتی طرف سومی وارد کار میشود حالا هر کدام از اشیای موجود باید برای برقراری ارتباط به ۲ شی مرتبط باشند. به همین روش شما فرض کنید که تعداد رابطه ها تا N مورد بتواند افزایش یابد. خوب با این شرایط حجم زیادی از تلاش برنامه نویسی ما صرف مدیریت ارتباطات می شود. ما میتوانیم این پیچیدگی را با معرفی یک شی واسط و سپردن مسئولیت مدیریت این روابط به این شی کنترل کنیم. کاری که الگوی Mediator استاد انجام آن است و یک نمونه از این الگو را در کلاس با هم پیاده سازی کردیم.
سناریوی دیگری که با آن زیاد سر و کار داریم ذخیره و بازیابی اطلاعات داخلی یک شی است به نحوی که اصل encapsulation زیر سوال نرود. با توجه به اینکه دادههای درونی به سادگی در دسترس نیستند نیاز به راه حلی داریم که بتوانیم از دادهها را از داخل شی واکشی کنیم و در هنگام نیاز دادهها را در شی تنظیم مجدد کنیم. الگوی Memento در این شرایط راهگشا است و به روشی اصولی کمک میکند تا وضعیت داخلی اشیا را ذخیره و بازیابی کنیم.
الگوی بعدی که دراین جلسه با هم بررسی کردیم State Pattern نام دارد. شاید در دنیای واقعی معادل این الگو را زیاد دیده باشید. مثلا وقتی راننده اتوبوس یک دکمه را فشار میدهد در صورت باز بودن درب بسته میشود و برعکس اگر درب باز باشد با فشردن دکمه درب اتوبوس بسته میشود. یا کنترل تلوزیون با یک دکمه هم تلوزیون را روشن میکند و هم تلوزیون را خاموش میکند. این دقیقا همان کاری است که State Pattern در پیاده سازی آن به ما کمک میکند. یعنی تغییر عملکرد برنامه با تغییر در وضعیت داخلی آن. در این قسمت با هم بررسی کردیم چگونه میتوان به کمک State Pattern عملکرد شی را با تغییر در وضعیت داخلی آن عوض کرد.
الگوی Observer
احتمالا برای شما هم پیش آمده که هنگام توسعه با شرایطی مواجه شوید که نیاز داشته باشید تغییر وضعیت یک شی را فوری به اطلاع مجموعهای از اشیا برسانید. راهکارهای مختلفی برای پیاده سازی این عملکرد وجود دارد و راهکاری که GO4 برای این سناریو در نظر گرفته است الگوی Observer است که در ادامه این جلسه این الگو و مزایا و معایب آن و انواع روشهای پیاده سازی آن را با هم بررسی کردیم.
الگوی Iterator
آخرین الگویی که در این جلسه با هم بررسی کردیم الگوی Iterator بود. فرض کنید مجموعه ای از اشیا داریم و نیاز داریم که اعضای این مجموعه را تک به تک مورد بررسی قرار دهیم. خوب اگر ساختار داده ثابت داشته باشیم مشکل کمتر است اما اگر داده ها در ساختارهای داده ای مختلفی ذخیره شوند مشکل بیشتر میشود. باید راهکاری برای دسترسی به اعضا داشته باشیم بدون نیاز به دقت در مورد ساختمان داده مورد استفاده. الگوی Iterator راهکاری برای این مشکل ارائه میکند که به جزئیات پیاده سازی این الگو پرداختیم.
جهت کسب اطلاعات بیشتر میتوانید به دوره بسیار کاربردی Domain Driven Design مراجعه کنید.