Design Patternها راه حل هایی برای مشکلات طراحی نرم افزار است که شما بارها و بارها در توسعه برنامه های کاربردی با آن ها برخورد می کنید. Patternها مربوط به reusable design و تعامل اشیاء هستند.
الگوی طراحی Abstract Factory جزو الگوهای طراحی سازنده (Creational) است که برای مدیریت ساخت اشیا توسعه داده شده است. Abstract Factory به شما اجازه می دهد که مجموعه ای از اشیا مرتبط را بدون نیاز به ساخت کلاس های جداگانه و متعدد ایجاد کنید. Abstract Factory معمولا زمانی استفاده می شود که کاربر به صورت دقیق از نوع شی ای که می خواهد ایجاد کند اطلاع نداشته باشد.
Problem
تصور کنید که شما یک نرم افزار فروشگاه مبلمان را ایجاد می کنید. در این شبیه ساز محصولاتی از قبیل انواع مبلمان، میز و... طراحی می شوند که خانواده ای از محصولات مرتبط هستند. کد شما شامل کلاس هایی برای محصولات زیر است:
صندلی، مبل و میز قهوه
در این حالت کلاس های مورد نیاز در نرم افزار عبارتند از صندلی، مبل و میز قهوه. همچنین محصولات در سه سبک ساده، هنری و مدرن طراحی و ایجاد می شوند. از آنجایی که محصولات یک سبک معمولا با یکدیگر سفارش داده می شوند، باید آن ها به صورت خانواده ای از محصولات مرتبط در نظر گرفته شوند.
همچنین باید در نرم افزار راهی برای فروش محصولات مرتبط با یکدیگر در نظر گرفته شود تا آن ها با سایر محصولات خریداری شده از یک نوع و سبک باشند. زیرا مشتریان هنگام دریافت محصولات غیر همسان ، کاملاً عصبانی می شوند. فرض کنید که مشتری یک صندلی، مبل و میز قهوه سفارش داده است و صندلی از سبک ساده، مبل از سبک هنری و میز از سبک مدرن برای آن ارسال شوند. برای جلوگیری از چنین مشکلاتی در نرم افزار، باید راه حلی در نظر گرفت.
از طرفی هنگام افزودن محصولات جدید، نباید کد موجود را تغییر دهید. فروشندگان مبلمان بارها کاتالوگ های خود را به روز می کنند و شما نمی خواهید هر بار که این اتفاق می افتد کد اصلی را تغییر دهید.
راه حل الگوی طراحی Abstract Factory
راه حلی که الگوی طراحی Abstract Factory برای اینگونه مسائل پیشنهاد می دهد این است که یک Interface برای هر نوع محصول صرف نظر از سبک های آن ایجاد شود. مثلا در این مثال باید سه Interface برای صندلی، مبل و میز قهوه به صورت جداگانه تعریف شود. سپس سبک های مختلف باید از این Interface ها پیروی کنند. به عنوان مثال، تمام مبل ها با هر سبکی که دارند باید Interface مبل را implement کنند.
اقدام بعدی تعریف یک interface با عنوان Abstract Factory است که شامل لیستی از روش های ایجاد برای کلیه محصولاتی است که بخشی از خانواده محصول هستند. مثلا اگر نام کارخانه اصلی را کارخانه ساخت مبلمان در نظر بگیریم، در این Interface توابع مربوط به ایجاد صندلی، مبل و میز قهوه تعریف می شوند.
حال برای هر نوع خانواده یک محصول ، ما یک کلاس Factory جداگانه بر اساس اینترفیس AbstractFactory ایجاد می کنیم. Factory Class کلاسی است که محصولاتی از یک نوع خاص را برمی گرداند. به عنوان مثال، FurnitureFactory فقط می تواند اشیاء ModernChair ، ModernSofa و ModernCoffeeTable ایجاد کند.
نرم افزار باید به گونه ای طراحی شده باشد که کارخانه ها و محصولات حتما از Interface ها پیروی کنند. با این کار شما می توانید بدون اینکه نیازی به تغییر در کدهای اصلی نرم افزار داشته باشید، به راحتی در کارخانه و محصولات تغییر ایجاد کنید. از طرفی با این کار هر محصولی که توسط مشتری سفارش داده می شود، همیشه از لحاظ سبک با یکدیگر سازگار خواهند بود زیرا کارخانه ها از لحاظ سبک تولیدی از یکدیگر متمایز شده اند.
پیاده سازی الگوی طراحی abstract Factory
مراحل پیاده سازی الگوی Abstract Factory عبارتند از :
- ابتدا باید لیست انواع اشیای مورد نظر در نرم افزار تهیه شود.
- برای هر نوع یک Interface تعریف شود و تمام کلاس های این اشیا از این Interface ها پیروی کنند.
- در مرحله بعد اینترفیس Abstract Factory ایجاد شود. در ایناینترفیس مجموعه ای از حالت های ایجاد اشیا Abstract تعریف می شود.
- باید برای هر یک از اشیا که سبک مشابهی دارند کلاس هایی به عنوان کارخانه سازنده آن ها ایجاد شود. این کارخانه ها که اشیا مرتبط را تولید می کنند باید از اینترفیس Abstract Factory پیروی کنند.
برای درک الگوی طراحی Abstract Factory درC# ، مثالی را پیاده سازی می کنیم.
بیان مسأله
سناریویی را در نظر بگیرید که در آن ما باید موبایل های معمولی و هوشمندی را تولید کنیم که توسط سازنده های مختلف ساخته شده اند. در این مثال، ما فقط برای دو نوع موبایل و سازنده آن ها کد خواهیم نوشت.
در اینجا ما یک اینترفیس به نام IMobilePhone داریم که شامل متدهایی است که می تواند یک شی تلفن هوشمند و یک شی تلفن معمولی ایجاد کند.
در مورد "نوکیا" ، خانواده ای از اشیاء نوکیا (SmartPhone و NormalPhone) ایجاد می کند و در مورد "سامسونگ" ، خانواده ای از اشیاء سامسونگ (SmartPhone و NormalPhone) ایجاد می کند.
کلاس ها و اشیاء شرکت کننده در این مثال به صورت زیر است:
- AbstractFactory- IMobilePhone
- ConcreteFactory - Nokia, Samsung
- AbstractProduct- ISmartPhone, INormalPhone
- Product- NokiaPixel, Nokia1600, SamsungGalaxy, SamsungGuru
- Client- MobileClient
در اینجا بلوک های کد برای هر شرکت کننده آورده شده است.
AbstractProduct
ISmartPhone
INormalPhone
AbstractFactory
Product
NokiaPixel
Nokia1600
SamsungGalaxy
SamsungGuru
ConcreteFactory
Nokia
Samsung
Client
خروجی مثال بالا به شکل زیر می باشد: