الکتروهایو

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

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

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

الگوی Proxy در الگوهای طراحی Structural به همراه کد

الگوی Proxy در الگوهای طراحی Structural به همراه کد - سایت الکتروهایو
در این مقاله می‌خوانید:

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

الگوی Proxy یک الگوی طراحی ساختاری است که به برنامه نویس امکان می‌دهد یک جایگزین یا مکان نگهدار(Placeholder) برای یک شی دیگر تهیه کنید. یک پروکسی دسترسی به شی اصلی را کنترل کرده و به شما امکان می‌دهد قبل یا بعد از ارسال درخواست به شی اصلی، کاری را انجام دهید.

Proxy design pattern

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

Problem solved by Proxy pattern
پرس و جوهای پایگاه داده می‌تواند واقعا کند باشد.

می‌توانید مقداردهی اولیه تنبل(lazy) را پیاده‌سازی کنید: شی را فقط زمانی ایجاد کنید که واقعاً مورد نیاز است. همه کلاینت‌های شی باید مقداری کد اولیه معوق را اجرا کنند. متأسفانه، این احتمالاً باعث تکرار کدهای زیادی می‌شود. در یک دنیای ایده آل، ما می‌خواهیم این کد را مستقیماً در کلاس شیء خود قرار دهیم، اما این همیشه ممکن نیست. به عنوان مثال، کلاس ممکن است بخشی از یک کتابخانه شخص ثالث بسته باشد.

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

Solution with the Proxy pattern
پروکسی خود را به عنوان یک شی پایگاه داده پنهان می‌کند. این روش می‌تواند بدون اینکه مشتری یا شی پایگاه داده واقعی بداند، مقداردهی اولیه و کش نتایج را مدیریت کند.

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

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

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

A credit card is a proxy for a bundle of cash
کارت‌های اعتباری را می‌توان همانند پول نقد برای پرداخت استفاده کرد.


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

در این بخش به بررسی ساختار الگوی پروکسی(Proxy) می‌پردازیم و پیاده‌سازی آن را به صورت UML خواهیم دید. 

  • گام 1: Service Interface، اینترفیس سرویس را تعریف می‌کند. پروکسی باید این اینترفیس را دنبال کند تا بتواند خود را به عنوان یک شیء سرویس پنهان کند.
  • گام 2: Service کلاسی است که منطق تجاری مفیدی را ارائه می‌دهد.
  • گام 3: کلاس Proxy دارای یک فیلد مرجع است که به یک شیء سرویس اشاره می‌کند. پس از اینکه پروکسی پردازش خود را به پایان رساند (به عنوان مثال، تنظیم اولیه تنبل، ورود به سیستم، کنترل دسترسی، ذخیره‌سازی و غیره)، درخواست را به شی سرویس ارسال می‌کند. معمولاً پراکسی‌ها چرخه حیات کامل اشیاء سرویس خود را مدیریت می‌کنند.
  • گام 4: Client باید با هر دو سرویس و پروکسی از طریق یک اینترفیس کار کند. به این ترتیب می‌توانید یک پروکسی را به هر کدی که انتظار یک شیء سرویس را دارد ارسال کنید.

شبه کد(Pseudocode)

این مثال نشان می‌دهد که چگونه الگوی Proxy می‌تواند به معرفی تنظیم اولیه تنبل(lazy initialization) و ذخیره‌سازی پنهان به یک کتابخانه یکپارچه YouTube شخص ثالث کمک کند.

Structure of the Proxy pattern example
کش کردن نتایج یک سرویس با پروکسی

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

// The interface of a remote service.
interface ThirdPartyYouTubeLib is
    method listVideos()
    method getVideoInfo(id)
    method downloadVideo(id)

// The concrete implementation of a service connector. Methods
// of this class can request information from YouTube. The speed
// of the request depends on a user's internet connection as
// well as YouTube's. The application will slow down if a lot of
// requests are fired at the same time, even if they all request
// the same information.
class ThirdPartyYouTubeClass implements ThirdPartyYouTubeLib is
    method listVideos() is
        // Send an API request to YouTube.

    method getVideoInfo(id) is
        // Get metadata about some video.

    method downloadVideo(id) is
        // Download a video file from YouTube.

// To save some bandwidth, we can cache request results and keep
// them for some time. But it may be impossible to put such code
// directly into the service class. For example, it could have
// been provided as part of a third party library and/or defined
// as `final`. That's why we put the caching code into a new
// proxy class which implements the same interface as the
// service class. It delegates to the service object only when
// the real requests have to be sent.
class CachedYouTubeClass implements ThirdPartyYouTubeLib is
    private field service: ThirdPartyYouTubeLib
    private field listCache, videoCache
    field needReset

    constructor CachedYouTubeClass(service: ThirdPartyYouTubeLib) is
        this.service = service

    method listVideos() is
        if (listCache == null || needReset)
            listCache = service.listVideos()
        return listCache

    method getVideoInfo(id) is
        if (videoCache == null || needReset)
            videoCache = service.getVideoInfo(id)
        return videoCache

    method downloadVideo(id) is
        if (!downloadExists(id) || needReset)
            service.downloadVideo(id)

// The GUI class, which used to work directly with a service
// object, stays unchanged as long as it works with the service
// object through an interface. We can safely pass a proxy
// object instead of a real service object since they both
// implement the same interface.
class YouTubeManager is
    protected field service: ThirdPartyYouTubeLib

    constructor YouTubeManager(service: ThirdPartyYouTubeLib) is
        this.service = service

    method renderVideoPage(id) is
        info = service.getVideoInfo(id)
        // Render the video page.

    method renderListPanel() is
        list = service.listVideos()
        // Render the list of video thumbnails.

    method reactOnUserInput() is
        renderVideoPage()
        renderListPanel()

// The application can configure proxies on the fly.
class Application is
    method init() is
        aYouTubeService = new ThirdPartyYouTubeClass()
        aYouTubeProxy = new CachedYouTubeClass(aYouTubeService)
        manager = new YouTubeManager(aYouTubeProxy)
        manager.reactOnUserInput()

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

راه‌های زیادی برای استفاده از الگوی Proxy وجود دارد. در این مجال بیایید به محبوب‌ترین کاربردهای آن بپردازیم:

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

پروکسی همچنین می‌تواند ردیابی کند که آیا مشتری شیء سرویس را تغییر داده است یا خیر. سپس اشیاء بدون تغییر ممکن است توسط مشتریان دیگر مورد استفاده مجدد قرار گیرند.

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

  1. اگر هیچ اینترفیس سرویسی از قبل موجود نیست، یک اینترفیس ایجاد کنید تا اشیاء پراکسی و سرویس قابل تعویض باشند. استخراج اینترفیس از کلاس سرویس همیشه امکان پذیر نیست، زیرا برای استفاده از آن اینترفیس ، باید همه مشتریان سرویس را تغییر دهید. پلن B این است که پروکسی را به یک زیر کلاس از کلاس سرویس تبدیل کند و به این ترتیب اینترفیس سرویس را به ارث می‌برد.
  2. کلاس پروکسی را ایجاد کنید. باید یک فیلد برای ذخیره ارجاع به سرویس داشته باشد. معمولاً پروکسی‌ها کل چرخه عمر سرویس‌های خود را ایجاد و مدیریت می‌کنند. در موارد نادر، یک سرویس از طریق یک سازنده توسط مشتری به پروکسی ارسال می‌شود.
  3. متدهای پروکسی را با توجه به اهداف آنها پیاده‌سازی کنید. در بیشتر موارد، پس از انجام برخی کارها، پروکسی باید کار را به شیء سرویس واگذار کند.
  4. یک متد ایجاد را در نظر بگیرید که تصمیم می‌گیرد مشتری یک پروکسی یا یک سرویس واقعی دریافت کند. این می‌تواند یک روش استاتیک ساده در کلاس پروکسی یا یک روش Factory تمام عیار باشد.
  5. پیاده‌سازی lazy initialization را برای شی سرویس در نظر بگیرید.

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

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

– مزایا

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

– معایب

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

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

  • با الگوی Adapter شما از طریق اینترفیس‌های مختلف به یک شی موجود دسترسی پیدا می‌کنید. با پروکسی، اینترفیس ثابت می‌ماند. با الگوی Decorator شما از طریق یک اینترفیس پیشرفته به شی دسترسی دارید.
  • الگوی Facade شبیه به Proxy است که هم یک موجودیت پیچیده را بافر می‌کند و هم آن را به تنهایی مقداردهی اولیه می‌کند. بر خلاف Facade، Proxy دارای اینترفیس یکسانی با شی سرویس خود است که باعث می‌شود آنها قابل تعویض باشند.
  • Decorator و Proxy ساختارهای مشابهی دارند، اما اهداف بسیار متفاوتی دارند. هر دو الگو بر اساس اصل ترکیب‌بندی(composition) ساخته شده‌اند، جایی که یک شی قرار است بخشی از کار را به دیگری واگذار کند. تفاوت این است که یک Proxy معمولاً چرخه عمر شیء سرویس خود را به تنهایی مدیریت می‌کند، در حالی که ترکیب Decorators همیشه توسط مشتری کنترل می‌شود.

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

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

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

مطالب مرتبط:

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

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

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

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

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