قبلا و در این لینک در خصوص الگوی طراحی Factory Method صحبت کردیم.
روش معمولی ایجاد یک شی توسط client از طریق سازنده عمومی آن است. این به خوبی با اشیاء ساده کار
می کند. اما، هنگامی که به اشیاء پیچیده ای مانند Aggregates مربوط می شود، ساخت آنها می تواند پیچیده باشد و فرآیند ایجاد می تواند برای یک شی طاقت فرسا شود.
ایجاد شی ربطی به دامنه ندارد. علاوه بر این، با ایجاد شیء پیچیده، یک شی تمایل به شکستن اصل مسئولیت واحد (SRP) دارد. بنابراین، توصیه می شود منطق ایجاد شی را از آن جدا کنید. در Domain Driven Design (DDD)، یک عنصر برنامه که مسئولیت اصلی آن ایجاد اشیاء و مجموعه های دامنه پیچیده است Factory نامیده می شود.
الگوی Factory شی ای است که مسئولیت ایجاد اشیاء دیگر را به عهده دارد.(زمانی که چیزی مسئولیت ایجاد یک شی دیگر را داشته باشد، به آن Factory می گویند.)
توجه داشته باشید Factoryها قطعا منحصر به طراحی Domain Driven نیستند، اما نقش مهمی در پروژه های طراحی دامنه محور(DDD) دارند.
کارخانه ها اغلب برای ایجاد Aggregateها استفاده می شوند.(Aggregates یک کپسوله سازی و یک consistent boundary در اطراف گروهی از اشیاء را ارائه می دهد.)
آنها به ما کمک می کنند تا عملکرد ایجاد اشیاء را از سایر بخش های یک Domain Object شناسایی و جدا کنیم و اطمینان حاصل می کند که همه قوانین business مورد نیاز برآورده می شوند.
کارخانه ها یک خط واضح بین منطق ایجاد و سایر نگرانی های موجود در کد ترسیم می کنند.
مفاهیم Entities, Value Objects, Aggregates and Roots
پياده سازي Aggregate در Domin Layer - DDD
خوب Aggregateها به این دلیل مهم هستند که internal consistency شیئی را که مسئول آن هستند اعمال می کنند. یک Factory میتواند هنگام ایجاد یک Aggregate جدید مفید باشد، زیرا دانش مورد نیاز برای ایجاد یک Aggregate را در یک consistent state و با اعمال همه invariantها در خود encapsulate میکند.
دلایل مهمی وجود دارد که نشان می دهد چرا می خواهید از یک Factory به عنوان بخشی از برنامه خود استفاده کنید. با افزایش پیچیدگی برنامه ها، Factories رایج تر می شوند.
کارخانه ها یک consistent interface برای ایجاد اشیاء پیچیده در یک برنامه ارائه می کنند. با رشد یک برنامه، قوانین مربوط به ایجاد شیء ممکن است از بین بروند. Factoryها راه استانداردی برای نمونه سازی اشیا ارائه
می دهند تا ایجاد اشیاء جدید در ابهام گم نشود.
یک Factory دانش مورد نیاز برای ایجاد یک شیء پیچیده یا Aggregate را در بر می گیرد. Factory با ارائه رابطی که اهداف client و یک نمای انتزاعی از شی ایجاد شده را منعکس میکند، از این پیچیدگی در برابر دنیای بیرون محافظت میکند.
مصرف کننده یک شیء نباید ملزم به درک درونیات یک شی باشد، بنابراین یک Factory کپسوله سازی را برای اشیاء پیچیده فراهم می کند.
قدرت واقعی برنامه نویسی شی گرا، کپسوله کردن منطق داخلی یک شی است. یک کلاینت باید بتواند از یک شی استفاده کند بدون اینکه نگران پیاده سازی داخلی آن شی باشد.
اشیاء باید یک مسئولیت واحد داشته باشند(اصل SRP). بنابر مواردی که به آن اشاره شد زمان آن است که فرآیند ایجاد را به یک Factory انتزاع کنیم. هیچ ارزش ذاتی در این که یک شی مسئولیت خلق خود را بپذیرد وجود ندارد.
کارخانه ها همچنین می توانند لایه مهمی از انتزاع را فراهم کنند که کلاینت را از وابستگی به یک
concrete class خاص محافظت می کند.
برای مثال، ممکن است یک Factory درگاه پرداخت داشته باشیم که باید کلاسی برای پذیرش پرداخت از سوی مشتریان به هر یک از درگاههای پرداخت متعدد ارائه کند.
در واقع Factory باید با ارائه کلاسی که یک رابط خاص را پیاده سازی می کند از کلاینت محافظت کند. این به Factory بستگی دارد که یک کلاس خاص را بر اساس نوع معین نمونه سازی و برگرداند. این امر از وابستگی داخل Factory محافظت می کند.
طراحی دامنه محور همه چیز در مورد مدل سازی دامنه یک برنامه کاربردی است. Factoryها هیچ ارتباطی با دامنه یک business ندارند، اما بخش مهمی از دامنه یک برنامه کاربردی را تشکیل می دهند.
طراحی اینترفیس یک Factory
اینترفیس یک Factory مهم است زیرا باید اهداف client و یک نمای انتزاعی از شی ایجاد شده را منعکس کند.
هر عملیات یک Factory باید هر چیزی را که برای ایجاد شی جدید در یک تعامل لازم است بپذیرد. این به این معنی است که Factory باید از شما بخواهد که همه چیز مورد نیاز برای ایجاد شی یا Aggregate را ارسال کنید.
و اما Entity Factories و Value Object Factories
دو مورد از مهمترین انواع اشیاء Entity ها و Value Objectها هستند.
موجودیت ها در برنامه دارای هویت هستند و بنابراین به عنوان بخشی از چرخه حیات وجود دارند. از سوی دیگر، Value Objectها تغییر ناپذیر هستند و به راحتی از بین می روند و جایگزین می شوند.
کارخانه ها مسئول ایجاد اشیاء جدید و تأیید اعتبار آنها هستند. آنها به ما کمک می کنند تا این عملکرد را از سایر بخش های دامنه شناسایی و جدا کنیم.
کارخانه ها یک خط واضح بین منطق ایجاد و سایر نگرانی های موجود در کد ترسیم می کنند. با وجود آنها خوانایی کد ما باید بهبود یابد.
از طرف دیگر موجودیت ها اغلب دارای حداقل مجموعه ای از الزامات هستند و سپس ویژگی های اختیاری بیشتری دارند که می توانند در طول چرخه حیات شی تنظیم شوند. یک Entity Factory باید بتواند یک موجودیت با حداقل شرایط لازم برای معتبر بودن آن موجودیت ایجاد کند.
بخش مهمی از یک موجودیت، هویت آن است. هنگامی که از یک Factory برای ایجاد یک موجودیت استفاده می کنید، می توانید هویت را به عنوان آرگومان به متد ارسال کنید، یا به طور متناوب به Factory اجازه دهید هویت(identity) جدید را به عنوان بخشی از فرآیند ایجاد شی ایجاد کند.
کارخانه باید یک محلی برای ساختن اشیاء دامنه باشد. هر بخش دیگری از کد که نیاز به انجام این کار دارد باید از Factory استفاده کند.
به طور معمول، حداقل سه منبع داده وجود دارد که به عنوان ورودی Factory برای ساخت شی دامنه استفاده می شود:
یک Factory شروع زندگی یک شی را مدیریت می کند. اما یک Repository به مدیریت وسط و پایان آن شی کمک می کند.
از آنجایی که Repository اشیایی را بر اساس داده ها ایجاد می کند، برخی از توسعه دهندگان Repository را یک Factory در نظر می گیرند - در واقع از نقطه نظر فنی چنین است. اما در طراحی دامنه محور، Factories و Repositories وظایف مجزایی دارند. Factory اشیاء جدید می سازد. Repository اشیاء قدیمی را بازسازی
می کند.
بنابراین اجازه ایجاد business obectهای جدید از طریق رابط Repository را ندهید، و همچنین اجازه پرس و جو از موارد موجود از طریق رابط Factory را نباید داد.
رابط کارخانه DDD متعلق به دامنه است، زیرا منطق دامنه شما از این برای ایجاد اشیاء دامنه استفاده می کند.
واضح است که در DDD پیادهسازی Factory به لایه infrastructure تعلق دارد.
بیشتر بخوانید : Implementing DDD - Clean Architecture
بیشتر بخوانید : نقشه راه توسعه دهندگان Asp.NET Core\