الکتروهایو

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

2 پاسخ

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

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

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

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

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

الگوی طراحی Prototype یک الگوی طراحی Creational است که امکان ایجاد اشیاء(object) جدید را با کپی کردن یک شی موجود فراهم می‌کند. الگوی Prototype به برنامه نویس امکان می‌دهد پیچیدگی ایجاد نمونه‌های جدید را از مشتری پنهان کند. در واقع مفهوم اصلی این الگو، کپی کردن یک شی موجود به جای ایجاد یک نمونه جدید از ابتدا است، فرآیندی که ممکن است بسیار پرهزینه باشد. شی موجود به عنوان یک نمونه اولیه عمل می‌کند و شامل وضعیت object است. این الگوی طراحی با نام کلون(Clone) نیز شناخته می‌شود.

Prototype Design Pattern

بیان مسئله: فرض کنید یک Object دارید و می‌خواهید یک کپی دقیق از آن ایجاد کنید. نحوه انجام این کار چگونه است؟ برای انجام این کار ابتدا باید یک شی جدید از همان کلاس ایجاد کنید. سپس باید تمام فیلدهای شی اصلی را مرور کنید و مقادیر آنها را در شی جدید کپی کنید. با انجام این مراحل شاید تصور شود کار به خوبی پیش رفته است، اماهنوز یک مشکل دیگر وجود دارد. همه اشیاء را نمی‌توان به این روش کپی کرد زیرا برخی از فیلدهای شی ممکن است خصوصی(Private) باشند و از خارج از خود Object قابل مشاهده و دسترسی نباشند.

What can go wrong when copying things “from the outside"?” width=

یک مشکل دیگر در استفاده از رویکرد مستقیم وجود دارد. از آنجایی که برای ایجاد یک کپی باید کلاس شی را بشناسید، کد نوشته شده شما به آن کلاس وابسته می‌شود. اگر بوجود آمدن وابستگی بیشتر ایرادی نداشته باشد، با این حال یک مشکل دیگر باز وجود دارد. گاهی اوقات شما فقط اینترفیسی را می‌شناسید که شی از آن پیروی می‌کند و اطلاعی از کلاس آن ندارید، به عنوان مثال پارامتری در یک متد را در نظر بگیرید، این پارامتر هر Object ای را که از یک اینترفیس پیروی می‌کند می‌پذیرد .

الگوی Prototype فرآیند شبیه‌سازی را به اشیاء واقعی که در حال شبیه‌سازی هستند واگذار می‌کند. این الگو یک اینترفیس مشترک را برای تمامی اشیایی که از شبیه‌سازی پشتیبانی می‌کنند، اعلان می‌کند. این اینترفیس به برنامه نویس امکان می‌دهد یک شی را بدون وابسته کردن کد نوشته شده با کلاس آن شی، کلون کنید. معمولاً چنین اینترفیسی فقط شامل یک متد clone می‌شود. پیاده‌سازی متد clone (الگوی Prototype) در همه کلاس‌ها بسیار شبیه است. در این تکنیک ابتدا متد، یک شی از کلاس فعلی ایجاد می‌کند سپس تمام مقادیر فیلد شی قدیمی را به شی جدید منتقل می‌کند. در طی این فرآیند حتی می‌توانید فیلدهای خصوصی(Private) را کپی کنید زیرا اکثر زبان‌های برنامه‌نویسی به اشیا اجازه می‌دهند به فیلدهای خصوصی دیگر اشیاء متعلق به همان کلاس دسترسی پیدا کنند.

بر اساس این مفاهیم Object ای که از شبیه‌سازی(Cloning) پشتیبانی می‌کند، Prototype نامیده می‌شود. هنگامی که اشیاء شما دارای ده‌ها فیلد و صدها پیکربندی ممکن هستند، کلون کردن آنها ممکن است به عنوان جایگزینی برای طبقه‌بندی فرعی(subclassing) باشد.

Pre-built prototypes

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

نمونه قابل قیاس در دنیای واقعی

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

The cell division

از آنجایی که Prototype های صنعتی واقعاً خود را کپی نمی‌کنند، مثال بسیار نزدیک‌تر و شبیه‌تر به الگوی Prototype، فرآیند تقسیم سلولی میتوزی است (تصویر بالا). پس از تقسیم میتوزی، یک جفت سلول یکسان تشکیل می‌شود. سلول اصلی به عنوان نمونه اولیه(Prototype) عمل کرده و نقش فعالی در ایجاد کپی بر عهده دارد.

ساختار الگوی Prototype

در این بخش به بررسی ساختار الگوی prototype می‌پردازیم و دو نوع پیاده‌سازی آن را به صورت UML خواهیم دید.

– پیاده‌سازی پایه(Basic)

  • گام 1: اینترفیس Prototype متدهای کلون کردن را اعلان می‌کند. در بیشتر موارد، آن یک متد clone تک است.
  • گام 2: کلاس Concrete Prototype روش کلون را پیاده‌سازی می‌کند. علاوه بر کپی کردن داده‌های شی اصلی در کلون، این روش ممکن است برخی از موارد لبه‌ای(edge) فرآیند شبیه‌سازی(Cloning) مربوط به شبیه‌سازی اشیاء مرتبط، باز کردن وابستگی‌های بازگشتی و غیره را نیز انجام دهد.
  • گام 3: کلاینت می‌تواند یک کپی از هر شی که از اینترفیس Prototype پیروی می‌کند تولید کند.

– پیاده‌سازی Prototype رجیستری

  • گام 1: روش Prototype Registry راه آسانی برای دسترسی به Prototype های پرکاربرد فراهم می‌کند. در واقع این روش مجموعه‌ای از اشیاء از پیش ساخته شده را که آماده کپی هستند در خود ذخیره می‌کند. ساده‌ترین Prototype Registry یک نقشه هش(Hash map) name → prototype است. با این حال، اگر به معیارهای جستجوی بهتری نسبت به یک نام ساده نیاز دارید، می‌توانید نسخه بسیار قوی‌تری از رجیستری را بسازید.

شبه کد(Pseudocode)

در مقال ذکر شده در ادامه الگوی Prototype به شما امکان می‌دهد کپی‌های دقیقی از اجسام هندسی تولید کنید، بدون اینکه کد را به کلاس‌های آنها وابسته کنید. برای فهم بیشتر شبه کد به UML زیر دقت کنید:

The structure of the Prototype pattern example

همه کلاس‌های شکل از یک اینترفیس یکسان پیروی می‌کنند که یک متد شبیه‌سازی(Clone) را ارائه می‌دهد. یک زیر کلاس ممکن است قبل از کپی کردن مقادیر فیلد خود در شیء به دست آمده، روش شبیه‌سازی(Cloning) والد را فراخوانی کند. در ادامه به شبه کد توجه کنید:

// Base prototype.
abstract class Shape is
    field X: int
    field Y: int
    field color: string

    // A regular constructor.
    constructor Shape() is
        // ...

    // The prototype constructor. A fresh object is initialized
    // with values from the existing object.
    constructor Shape(source: Shape) is
        this()
        this.X = source.X
        this.Y = source.Y
        this.color = source.color

    // The clone operation returns one of the Shape subclasses.
    abstract method clone():Shape


// Concrete prototype. The cloning method creates a new object
// in one go by calling the constructor of the current class and
// passing the current object as the constructor's argument.
// Performing all the actual copying in the constructor helps to
// keep the result consistent: the constructor will not return a
// result until the new object is fully built; thus, no object
// can have a reference to a partially-built clone.
class Rectangle extends Shape is
    field width: int
    field height: int

    constructor Rectangle(source: Rectangle) is
        // A parent constructor call is needed to copy private
        // fields defined in the parent class.
        super(source)
        this.width = source.width
        this.height = source.height

    method clone():Shape is
        return new Rectangle(this)


class Circle extends Shape is
    field radius: int

    constructor Circle(source: Circle) is
        super(source)
        this.radius = source.radius

    method clone():Shape is
        return new Circle(this)


// Somewhere in the client code.
class Application is
    field shapes: array of Shape

    constructor Application() is
        Circle circle = new Circle()
        circle.X = 10
        circle.Y = 10
        circle.radius = 20
        shapes.add(circle)

        Circle anotherCircle = circle.clone()
        shapes.add(anotherCircle)
        // The `anotherCircle` variable contains an exact copy
        // of the `circle` object.

        Rectangle rectangle = new Rectangle()
        rectangle.width = 10
        rectangle.height = 20
        shapes.add(rectangle)

    method businessLogic() is
        // Prototype rocks because it lets you produce a copy of
        // an object without knowing anything about its type.
        Array shapesCopy = new Array of Shapes.

        // For instance, we don't know the exact elements in the
        // shapes array. All we know is that they are all
        // shapes. But thanks to polymorphism, when we call the
        // `clone` method on a shape the program checks its real
        // class and runs the appropriate clone method defined
        // in that class. That's why we get proper clones
        // instead of a set of simple Shape objects.
        foreach (s in shapes) do
            shapesCopy.add(s.clone())

        // The `shapesCopy` array contains exact copies of the
        // `shape` array's children.

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

  • از الگوی Prototype زمانی استفاده کنید که کد شما نباید به کلاس‌های concrete اشیایی که باید کپی کنید بستگی داشته باشد. این اتفاق زمانی که کد نوشته شده شما با اشیایی که از کدهای فردی دیگر از طریق برخی از اینترفیس‌ها به شما ارسال می‌شود سر و کار دارد این اتفاق زیاد می‌افتد. کلاس‌های concrete این اشیاء ناشناخته هستند و حتی اگر بخواهید نمی‌توانید به آنها وابسته باشید. الگوی Prototype کد کلاینت را با یک اینترفیس کلی برای کار با تمام اشیایی که از شبیه‌سازی پشتیبانی می‌کنند، فراهم می‌کند. این اینترفیس کد کلاینت را از کلاس‌های concrete اشیایی که شبیه‌سازی می‌کند مستقل می‌کند.
  • زمانی که می‌خواهید تعداد زیرکلاس‌هایی را که فقط در نحوه مقداردهی اولیه اشیاء مربوطه خود متفاوت هستند، کاهش دهید، از الگو استفاده کنید. فرض کنید یک کلاس پیچیده دارید که قبل از استفاده از آن نیاز به یک پیکربندی پر زحمت دارد. چندین راه متداول برای پیکربندی این کلاس وجود دارد و این کد در برنامه شما پراکنده است. برای کاهش تکرار، چندین زیر کلاس ایجاد می‌کنید و هر کد پیکربندی مشترک را در سازنده(Constructor) آنها قرار می‌دهید. با این روش شما مشکل تکثیر را حل کردید، اما اکنون زیر کلاس‌های ساختگی زیادی دارید. الگوی Prototype به شما امکان می‌دهد مجموعه‌ای از اشیاء از پیش ساخته شده را که به روش‌های مختلف به عنوان Prototype پیکربندی شده‌اند را استفاده کنید. به جای تولید اولیه(instantiating) یک زیر کلاس که با برخی از تنظیمات مطابقت دارد، مشتری می‌تواند به سادگی به دنبال prototype مناسب باشد و آن را شبیه‌سازی کند.

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

  1. اینترفیس prototype را ایجاد کنید و متد clone را در آن اعلان کنید. یا فقط متد را به تمام کلاس‌های سلسله مراتب کلاس موجود اضافه کنید، این در حالتی است اگر فقط یک مورد دارید.
  2. یک کلاس prototype باید سازنده جایگزینی را تعریف کند که شیء آن کلاس را به عنوان آرگومان می‌پذیرد. سازنده باید مقادیر تمام فیلدهای تعریف شده در کلاس را از شی ارسال شده متعلق به prototype کپی کند. اگر در حال تغییر یک کلاس فرعی هستید، باید سازنده والد را فراخوانی کنید تا به ابرکلاس(Superclass) اجازه دهید کلونینگ فیلدهای خصوصی خود را انجام دهد. اگر زبان برنامه نویسی شما از overloading متد پشتیبانی نمی‌کند، نمی‌توانید یک سازنده «prototype» جداگانه ایجاد کنید. بنابراین کپی کردن داده‌های شی در کلون جدید ایجاد شده، باید در متد clone انجام شود. با این حال، داشتن این کد در یک سازنده معمولی امن‌تر است، زیرا شی به‌دست‌آمده دقیقاً پس از فراخوانی با اپراتور new، کاملاً پیکربندی شده برگردانده می‌شود.
  3. روش شبیه‌سازی معمولاً از در یک خط واحد نوشته می‌شود: اجرای یک اپراتور new با نسخه prototype سازنده. توجه داشته باشید که هر کلاس باید صراحتاً متد شبیه‌سازی را بازنویسی کند و از نام کلاس خود همراه با پراتور new استفاده کند. در غیر این صورت، روش شبیه‌سازی ممکن است یک شی از یک کلاس والد تولید کند.
  4. به صورت اختیاری، یک رجیستری prototype مرکزی برای ذخیره کاتالوگ نمونه‌های اولیه پر کاربرد ایجاد کنید. می‌توانید رجیستری را به‌عنوان یک کلاس Factory جدید پیاده‌سازی کنید یا آن را با یک متد استاتیک برای واکشی نمونه اولیه در کلاس نمونه اولیه قرار دهید. این روش باید یک نمونه اولیه را بر اساس معیارهای درخواستی جستجو کند که کد مشتری به متد ارسال می‌کند. معیارها ممکن است یک تگ رشته ساده یا مجموعه پیچیده‌ای از پارامترهای جستجو باشد. پس از یافتن نمونه اولیه مناسب، رجیستری باید آن را شبیه‌سازی کند و کپی را به مشتری برگرداند. در نهایت، فراخوانی‌های مستقیم سازنده‌های کلاس‌های فرعی را با فراخوانی به روش factory رجیستری نمونه جایگزین کنید.

مزایا و معایب الگوی Prototype

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

– مزایا

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

– معایب

  • شبیه‌سازی اشیاء پیچیده که دارای ارجاعات حلقه‌ای هستند ممکن است بسیار مشکل باشد.

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

  • بسیاری از الگوها با استفاده از روش Factory (کمتر پیچیده‌تر و قابل تنظیم‌تر از طریق زیر کلاس‌ها) شروع می‌شوند و کم کم به سمت Abstract Factory، Prototype یا Builder (انعطاف‌پذیرتر، اما پیچیده‌تر) تکامل می‌یابند.
  • کلاس‌هایAbstract Factory اغلب بر اساس مجموعه‌ای از متد‌های Factory هستند، اما شما همچنین می‌توانید از Prototype برای ترکیب متدهای این کلاس‌ها استفاده کنید.
  • هنگامی که نیاز به ذخیره کپی از الگوی Command در تاریخچه دارید، نمونه اولیه می‌تواند به شما کمک کند.
  • طرحی‌هایی که به شدت از Composite و Decorator استفاده می‌کنند اغلب می‌توانند از نمونه اولیه بهره ببرند. استفاده از الگو به شما این امکان را می‌دهد که ساختارهای پیچیده را به جای بازسازی مجدد از ابتدا شبیه‌سازی کنید.
  • الگوی Prototype مبتنی بر وراثت نیست، بنابراین اشکالات آن را ندارد. از سوی دیگر، Prototype به یک مقداردهی اولیه پیچیده از شی کلون شده نیاز دارد. Factory Method بر اساس وراثت است اما نیازی به مرحله اولیه سازی ندارد.
  • گاهی اوقات Prototype می‌تواند جایگزین ساده‌تری برای Memento باشد. اگر شیء، وضعیتی که می‌خواهید در تاریخچه ذخیره کنید، نسبتاً ساده باشد و پیوندی به منابع خارجی نداشته باشد، یا پیوندها به راحتی دوباره برقرار شوند، کار می‌کند.
  • Abstract Factory، Builder و نمونه‌های اولیه همگی می‌توانند به‌عنوان Singletons پیاده‌سازی شوند.

نمونه کد الگوی Prototype

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

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

مطالب مرتبط:

داده‌های اسمی 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 آشنا شوید: تشخیص اشیاء تک مرحله‌ای کاملاً کانولوشنال

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

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

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

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