الکتروهایو

هوش مصنوعی / الکترونیک / برنامه‌نویسی

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

الگوی Abstract Factory در الگوهای طراحی Creational به همراه پیاده سازی کد

الگوی Abstract Factory در الگوهای طراحی Creational به همراه پیاده سازی کد - الکتروهایو
در این مقاله می‌خوانید:

زمان تخمینی مطالعه: 13 دقیقه

الگوی Abstract Factory در مهندسی نرم‌افزار یک Design Pattern است که راهی برای ایجاد خانواده‌های اشیاء مرتبط بدون تحمیل کلاس‌های Concrete آن‌ها، با کپسوله‌سازی گروهی از کارخانه‌های(Factories) منفرد که دارای یک موضوع مشترک هستند، بدون مشخص کردن کلاس‌های Concrete خود، فراهم می‌کند. بر اساس این الگو که از دسته Creational است، یک جزء نرم افزار مشتری، یک پیاده سازی ملموس از Abstract Factory ایجاد می‌کند و سپس از اینترفیس عمومی کارخانه برای ایجاد اشیاء Concrete که بخشی از خانواده هستند استفاده می‌کند.

Abstract Factory pattern

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

بیان مسئله: تصور کنید که در حال ایجاد یک شبیه ساز مغازه مبلمان فروشی هستید. کد نوشته شده توسط شما شامل کلاس‌هایی است که نشان دهنده:

  1. یک خانواده از محصولات مرتبط شامل Chair + Sofa+ CoffeeTable است.
  2. چندین گونه یا تنوع از این خانواده وجود دارد. به عنوان مثال، محصولات Chair + Sofa + CoffeeTable در این ساختار در انواع و دسته‌های متنوعی موجود هستند که شامل: Modern، Victorian، ArtDeco هستند.
Product families and their variants.

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

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

اولین چیزی که الگوی Abstract Factory پیشنهاد می‌کند این است که به صراحت اینترفیس‌ها را برای هر محصول متمایز از خانواده محصول (مانند صندلی، مبل یا میز قهوه) اعلان(Declare) کنید. سپس می‌توانید کاری کنید که همه انواع محصولات از آن اینترفیس‌ها پیروی کنند. به عنوان مثال، همه انواع صندلی می‌توانند اینترفیس Chair را پیاده سازی کنند و یا همه انواع میز قهوه می‌توانند رابط CoffeeTable و غیره را پیاده‌سازی کنند.

The Chairs class hierarchy

گام بعدی اعلان Abstract Factory است که یک اینترفیس با لیستی از متدهای creation برای همه محصولاتی است که بخشی از خانواده محصول هستند (به عنوان مثال، createChair، createSofa و createCoffeeTable). این متدها باید انواع محصول Abstract را بازگردانند که با اینترفیس‌هایی که قبلا استخراج کرده‌ایم نشان داده می‌شوند: مانند Chair، Sofa، CoffeeTable و غیره.

The _Factories_ class hierarchy

حال، انواع محصولات را چگونه مشخص کنیم؟ برای هر گونه از یک خانواده محصول، ما یک کلاس کارخانه(factory) جداگانه بر اساس اینترفیس AbstractFactory ایجاد می‌کنیم. کارخانه کلاسی است که محصولاتی از نوع خاصی را بر می‌گرداند. به عنوان مثال، ModernFurnitureFactory فقط می‌تواند اشیاء ModernChair، ModernSofa و ModernCoffeeTable ایجاد کند.

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

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

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

برای تشریح بیشتر و روشن شدن موضوع بر اساس اصول مهندسی نرم افزار ساختار این الگوی طراحی را به صورت UML در تصویر زیر نشان داده‌ایم همچنین توضیحات هر گام به طور مشخص در زیر این تصویر نوشته شده است.

  • گام 1: محصولات Abstract اینترفیس را برای مجموعه‌ای از محصولات متمایز اما مرتبط که یک خانواده محصول را تشکیل می‌دهند، اعلام(Declare) می‌کنند.
  • گام 2: محصولات Concrete پیاده‌سازی‌های مختلفی از محصولات انتزاعی(Abstract) هستند که بر اساس انواع مختلف گروه‌بندی می‌شوند. هر محصول انتزاعی (صندلی/مبل) باید در تمام انواع دسته‌های داده شده (ویکتوریایی/مدرن) پیاده‌سازی شود.
  • گام 3: اینترفیس الگوی Abstract Factory مجموعه‌ای از متدها را برای ایجاد هر یک از محصولات انتزاعی اعلام می‌کند.
  • گام 4: کارخانه‌های concrete متدهای ایجاد Abstract Factory را اجرا می‌کنند. هر کارخانه concrete مربوط به یک نوع خاص از محصولات است و تنها آن گونه‌های محصول را ایجاد می‌کند.
  • گام 5: اگرچه کارخانه‌های concrete محصولات concrete را نمونه‌سازی می‌کنند، اما امضای روش‌های ایجاد آنها باید محصولات انتزاعی مربوطه را بازگرداند. به این ترتیب کد مشتری که از یک کارخانه استفاده می‌کند قابلیت جفت شدن با نوع خاصی از محصولی که از یک کارخانه دریافت می‌کند را ندارد. مشتری تا زمانی که با اشیاء آنها از طریق اینترفیس‌های انتزاعی ارتباط برقرار کند، می‌تواند با هر نوع کارخانه/محصول concrete کار کند.

شبه کد(Pseudocode)

در این مثال نشان خواهیم داد که چگونه می‌توان از الگوی Abstract Factory برای ایجاد عناصر رابط کاربری(UI) مستقل از پلتفرم بدون جفت کردن(coupling) کد مشتری با کلاس‌های رابط کاربری مشخص استفاده کرد، در حالی که همه عناصر ایجاد شده را با یک سیستم عامل انتخابی سازگار نگه می‌دارد.

The class diagram for the Abstract Factory pattern example

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

اینترفیس Abstract Factory مجموعه‌ای از متدهای ایجاد را اعلام می‌کند که کد مشتری(Client Code) می‌تواند برای تولید انواع مختلف عناصر UI از آنها استفاده کند. کارخانه‌های concrete با سیستم عامل‌های خاصی مطابقت دارند و عناصر UI را ایجاد می‌کنند که با آن سیستم عامل خاص مطابقت دارد. در واقع نحوه انجام این کار به این صورت است که هنگامی راه اندازی یک برنامه، نوع سیستم عامل فعلی را بررسی می‌کند. سپس برنامه از این اطلاعات برای ایجاد یک شی کارخانه از کلاسی استفاده می‌کند که با سیستم عامل مطابقت دارد. بقیه کدها از این کارخانه(factory) برای ایجاد عناصر UI استفاده می‌کنند. این مکانیزم از ایجاد عناصر اشتباه در طی فرآیند اجرای برنامه جلوگیری می‌کند.

// The abstract factory interface declares a set of methods that
// return different abstract products. These products are called
// a family and are related by a high-level theme or concept.
// Products of one family are usually able to collaborate among
// themselves. A family of products may have several variants,
// but the products of one variant are incompatible with the
// products of another variant.
interface GUIFactory is
    method createButton():Button
    method createCheckbox():Checkbox


// Concrete factories produce a family of products that belong
// to a single variant. The factory guarantees that the
// resulting products are compatible. Signatures of the concrete
// factory's methods return an abstract product, while inside
// the method a concrete product is instantiated.
class WinFactory implements GUIFactory is
    method createButton():Button is
        return new WinButton()
    method createCheckbox():Checkbox is
        return new WinCheckbox()

// Each concrete factory has a corresponding product variant.
class MacFactory implements GUIFactory is
    method createButton():Button is
        return new MacButton()
    method createCheckbox():Checkbox is
        return new MacCheckbox()


// Each distinct product of a product family should have a base
// interface. All variants of the product must implement this
// interface.
interface Button is
    method paint()

// Concrete products are created by corresponding concrete
// factories.
class WinButton implements Button is
    method paint() is
        // Render a button in Windows style.

class MacButton implements Button is
    method paint() is
        // Render a button in macOS style.

// Here's the base interface of another product. All products
// can interact with each other, but proper interaction is
// possible only between products of the same concrete variant.
interface Checkbox is
    method paint()

class WinCheckbox implements Checkbox is
    method paint() is
        // Render a checkbox in Windows style.

class MacCheckbox implements Checkbox is
    method paint() is
        // Render a checkbox in macOS style.


// The client code works with factories and products only
// through abstract types: GUIFactory, Button and Checkbox. This
// lets you pass any factory or product subclass to the client
// code without breaking it.
class Application is
    private field factory: GUIFactory
    private field button: Button
    constructor Application(factory: GUIFactory) is
        this.factory = factory
    method createUI() is
        this.button = factory.createButton()
    method paint() is
        button.paint()


// The application picks the factory type depending on the
// current configuration or environment settings and creates it
// at runtime (usually at the initialization stage).
class ApplicationConfigurator is
    method main() is
        config = readApplicationConfigFile()

        if (config.OS == "Windows") then
            factory = new WinFactory()
        else if (config.OS == "Mac") then
            factory = new MacFactory()
        else
            throw new Exception("Error! Unknown operating system.")

        Application app = new Application(factory)

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

قابلیت‌ها و کاربرد‌ها

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

نحوه پیاده‌سازی

  1. ماتریسی از انواع محصولات متمایز در مقابل انواع این محصولات را نگاشت کنید.
  2. اینترفیس‌های محصول انتزاعی را برای همه انواع محصول اعلام(declare) کنید. سپس تمام کلاس‌های محصول concrete را وادار به پیاده‌سازی این اینترفیس‌ها کنید.
  3. رابط abstract factory را با مجموعه‌ای از متدهای ایجادی برای همه محصولات انتزاعی اعلام کنید.
  4. مجموعه‌ای از کلاس‌های concrete کارخانه، یکی برای هر نوع محصول را اجرا کنید.
  5. کد راه اندازی کارخانه را در جایی از برنامه ایجاد کنید. بسته به پیکربندی برنامه یا محیط فعلی، باید یکی از کلاس‌های concrete کارخانه را نمونه سازی کند. این شی کارخانه را به تمام کلاس‌هایی که محصولات را می سازند منتقل کنید.
  6. کد را اسکن کنید و تمام فراخوان‌های مستقیم با سازنده‌های محصول را بیابید. آنها را با فراخوانی به روش ایجاد مناسب در شی کارخانه جایگزین کنید.

مزایا و معایب الگوی Abstract Factory

این الگوی طراحی دارای مزایا و معایبی به شرح زیر است:

– مزایا

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

معایب

  • کد ممکن است پیچیده‌تر از آن چیزی باشد که باید باشد، زیرا بسیاری از اینترفیس‌ها و کلاس‌های جدید همراه با الگو معرفی می‌شوند.

ارتباط با الگوهای دیگر

  • بسیاری از الگوها با استفاده از متد Factory (کمتر پیچیده‌تر و قابل تنظیم‌تر از طریق زیر کلاس‌ها) شروع می‌شوند و به سمت Abstract Factory، Prototype یا Builder (انعطاف‌پذیرتر، اما پیچیده‌تر) تکامل می‌یابند.
  • الگوی Builder بر ساختن اشیاء پیچیده گام به گام تمرکز می‌کند. Abstract Factory در ایجاد خانواده از اشیاء مرتبط تخصص دارد. Abstract Factory محصول را فوراً برمی‌گرداند، در حالی که Builder به شما امکان می‌دهد قبل از واکشی محصول، مراحل ساخت و ساز اضافی را اجرا کنید.
  • کلاس‌های الگوی Abstract Factory اغلب بر اساس مجموعه‌ای از متدهای Factory هستند، اما شما همچنین می‌توانید از الگوی Prototype برای ترکیب متدهای این کلاس‌ها استفاده کنید.
  • Abstract Factory می‌تواند به عنوان جایگزینی برای الگوی Facade عمل کند که در آن شما فقط می‌خواهید نحوه ایجاد اشیاء زیرسیستم را از کد مشتری پنهان کنید.
  • می‌توانید از الگوی Abstract Factory در کنار الگوی Bridge استفاده کنید. این جفت شدن زمانی مفید است که برخی از انتزاعات تعریف شده توسط Bridge فقط می‌توانند با پیاده‌سازی‌های خاص کار کنند. در این مورد، Abstract Factory می‌تواند این روابط را کپسوله کند و پیچیدگی را از کد کلاینت پنهان کند.
  • الگوهایAbstract Factory، الگوی Builder و الگوی Prototype همگی می‌توانند به‌عنوان الگوهای Singleton پیاده‌سازی شوند.

نمونه کد الگوی Abstract Factory

لوگو الکتروهایو

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

مطالب مرتبط:

داده‌های اسمی Nominal Data - الکتروهایو

داده‌های اسمی Nominal Data چیست؟

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

ادامه مطلب »
مقدمه‌ای بر ژوپیتر نوت‌بوک Jupiter Notebook - سایت الکتروهایو

مقدمه‌ای بر ژوپیتر نوت‌بوک Jupiter Notebook برای یادگیری ماشین

ژوپیتر نوت‌بوک(Jupyter Notebook) یک پلتفرم وب منبع باز است که به توسعه دهندگان اجازه می‌دهد اسنادی را ایجاد و به اشتراک بگذارند که شامل متن روایت، کد زنده، تجسم‌ها و معادلات است. این پلتفرم مبتنی بر تجسم داده‌ها، تمیز کردن

ادامه مطلب »
تفاوت تصویر، عکس و نگاره چیست؟ - سایت الکتروهایو

تفاوت تصویر، عکس و نگاره چیست؟

امروزه، اکثر مردم هنگام بحث در مورد نمایش بصری یک شی در رایانه، تفاوت تصویر، عکس و نگاره را نمی‌دانند و آنها را مترادف هم در نظر می‌گیرند. اما برای ابهام هر یک از این موارد را به صورت زیر

ادامه مطلب »
خزنده وب Web Crawler چیست؟ - سایت الکتروهایو

خزنده وب Web Crawler چیست؟

تعریف خزنده وب خزنده وب یک ربات موتور جستجوی دیجیتال است که از کپی و ابرداده(Metadata) برای کشف و فهرست‌بندی صفحات سایت استفاده می‌کند. این مفهوم همچنین به عنوان ربات عنکبوتی(اسپایدر) نیز نامیده می‌شود، وب کراولرها در وب جهانی (از

ادامه مطلب »
مفهوم SIEM (مدیریت رویداد و امنیت اطلاعات) چیست؟

مفهوم SIEM (مدیریت رویداد و امنیت اطلاعات) چیست؟

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

ادامه مطلب »
داده‌های اسمی Nominal Data - الکتروهایو

داده‌های اسمی Nominal Data چیست؟

داده‌های اسمی(Nominal Data) یکی از اساسی‌ترین انواع داده‌ها در تجزیه و تحلیل داده‌ها است. شناسایی ...

حاشیه‌نویسی متن در هوش مصنوعی - سایت الکتروهایو

حاشیه‌نویسی متن در هوش مصنوعی

حاشیه‌نویسی داده به الگوریتم‌های یادگیری ماشین اجازه می‌دهد تا اطلاعات را درک و تفسیر کنند. ...

هوش مصنوعی در باستان شناسی و کاربردهای آن - سایت الکتروهایو

هوش مصنوعی در باستان شناسی چه کاربردهای می‌تواند داشته باشد؟

مکان‌های باستان‌شناسی ممکن است ثابت باشند، اما فرهنگ‌هایی که آنها را تولید کرده‌اند، پویا و ...

با الگوریتم تشخیص اشیاء FCOS آشنا شوید - سایت الکتروهایو

با الگوریتم تشخیص اشیاء FCOS آشنا شوید: تشخیص اشیاء تک مرحله‌ای کاملاً کانولوشنال

تشخیص اشیاء یک کار مهم در بینایی کامپیوتر است که با رسم کادرهای محدود کننده ...

تصویربرداری چند طیفی، دیدی جدید فراسوی نور مرئی - سایت الکتروهایو

تصویربرداری چند طیفی، دیدی جدید فراسوی نور مرئی

تصویربرداری چند طیفی تکنیکی است که نور را در طیف وسیعی از باندهای طیفی، فراتر ...