در این قسمت در مورد مدل دیگه از الگوهای ایجادی یا Creational صحبت خواهیم کرد. در قسمت قبلی الگوی Factory رو توضیح دادم.الگوی دیگه ای که در این قسمت میخوام بهش بپردازم بی ارتباط با الگوی Factory نیست و اسمش هست Abstract Factory.
این الگو به Super Factory یا Factory of Factories هم شناخته میشه و ایده اش شبیه به همون ایده Factory هست.با این تفاوت که ما اینجا در مورد تنها یک کلاسی به اسم Factory، که بیاد بر اساس پارامتر ورودی که بهش پاس میدیم، به ما یک شی تحویل بده، اونم از یکی از Concrete کلاس های ارث برده شده از یک اینترفیس واحد، صحبت نمیکنیم.
داریم در مورد یک لایه انتزاع برای خود اون کلاس Factory هم صحبت میکنیم.
حالا سوال مهم اینه که در چه شرایطی من باید تشخیص بدم که از Abstract Factory باید استفاده کرد؟
یکی از نشانه ها اینه که در اینجا هم باز ما داریم رد پای یک اینترفیس رو میبینیم، که یک تعدادی Concrete کلاس ازش ارث بردند. اما این کلاسها با هم دیگه از نظر نوع و کارکرد در سامانه متفاوت هستند.
بیاین یک مثال Real یا واقعی بزنیم.
فرض کنید یک سامانه آموزشی داخل یک ERP سازمانی نوشتید. قبلا این سامانه آموزشی، داخلش همه کلاس های از نوع حضوری بودن. ولی خب از تایپ های مختلف:
حالا کرونا شده! و کارفرما توی جیرا براتون یک تیکت توسعه زده که "آقا، من بعد یک مدل کلاس های دیگه هم دارم که اینا مجازیه!.یعنی یک سری کلاس دارم که آنلاین برگزار میشه، یک سری کلاس دارم که مدرس ها فیلم هاشو آپلود میکنه و یک عده افراد خاص مجوز دانلود دارند و ..."
الان خب یک سری موجودیت های جدید داره به سامانه شما افزوده میشه که اینا واقعا کلاس هستند. رفتار همون کلاس رو دارن. همون ویژگی ها رو دارند:
مدرس دارن، ارزشیابی دارن، چاپ نمرات دارن، دانشجو دارند و ...
به همون اینترفیس شما که برای کلاس ایجاد کردید، پایبند خواهند بود و ملزم به پیاده سازی Api همون متد ها هستند.
ولی واقعیت با اون Concrete کلاس ها دیگه که از این اینترفیس ارث بردند، یک فرق هایی هم دارند.
اینجاست که شاخک های ما باید روی الگوی Abstract Factory حساس بشه.
مخصوصا اگر شما قبلا یک کلاس Factory داشتید. بهترین کار اینه که نیاید اون رو دست ببرید توش و بهش پارامتر اضافه کنید و ایف و الس بزنید.
بلکه یک Super Factory بسازید که اون بیاد باز براتون تشخیص بده که از کدوم Factory شی قراره ایجاد بشه، از Factory کلاس های حضوری ، یا از Factory کلاس های غیر حضوری.
_________________________________________________________________________ public interface ICourse { CourseDTO GetCourse(); } کلاس های حضوری ____________________________________________________________ public class FaceToFaceClass: ICourse { #region ICourse Members public CourseDTO GetCourse() { ... } #endregion } //--------------------------------- public class SeminarClass : ICourse { #region ICourse Members public CourseDTO GetCourse() { ... } #endregion } کلاس های غیر حضوری ________________________________________________________ public class OnlineClass: ICourse { #region ICourse Members public CourseDTO GetCourse() { ... } #endregion } //-------------------------------- public class OfflineClass: ICourse { #region ICourse Members public CourseDTO GetCourse() { ... } #endregion }
حالا میریم سر وقت Factory سازی:
____________________________________________________________________________________________ public class AbstractFactory { abstract ICourse GetCourse(string courseType); } فکتوری کلاس های حضوری ____________________________________________________ public class InPersonClassFactory : AbstractFactory { public ICourse GetCourse(string courseType) { if (courseType == "Seminar") return new SeminarClass(); if (courseType == "FaceToFace") return new FaceToFaceClass(); else return null; } } فکتوری کلاس های غیر حضوری ________________________________________________ public class RemoteClassFactory : AbstractFactory { public ICourse GetCourse(string courseType) { if (courseType == "Online") return new OnlineClass(); if (courseType == "Offline") return new OfflineClass(); else return null; } }
حالا یک کلاسی میسازیم به اسم FactoryProducer :
public class FactoryProducer { public static AbstractFactory GetFactory(bool isRemote) { if (isRemote) return new RemoteClassFactory(); else return new InPersonClassFactory(); } }
کاره ما تمومه. وقته اونه که از این کلاس ها در بیزنس ها استفاده کنیم :
AbstractFactory courseFactory = FactoryProducer.GetFactory(false);
ICourse course = courseFactory.GetCourse("FaceToFace")