خانه / آموزش‌ها / آموزش جامع الگوهای طراحی (Design Patterns) در پایتون

آموزش جامع الگوهای طراحی (Design Patterns) در پایتون

🐍 HomeOfPython
|
📅 1404/10/18

نمودار کلی الگوهای طراحی

سطح مقدماتی (Beginner Level)

الگوهای طراحی (Design Patterns) راه‌حل‌های استاندارد و اثبات‌شده برای مشکلات رایج در طراحی نرم‌افزار هستند. یادگیری این الگوها نه تنها کد شما را خواناتر و قابل نگهداری‌تر می‌کند، بلکه زبان مشترکی بین برنامه‌نویسان ایجاد می‌کند. در پایتون، به دلیل ماهیت پویا (Dynamic) زبان، پیاده‌سازی این الگوها اغلب ساده‌تر از زبان‌هایی مثل Java یا C++ است.

۱. الگوی Singleton (تک‌نمونه)

این الگو تضمین می‌کند که از یک کلاس تنها یک نمونه (Instance) ساخته شود و یک نقطه دسترسی جهانی به آن وجود داشته باشد. این الگو برای مدیریت منابع مشترک مثل اتصال به دیتابیس یا تنظیمات برنامه (Configuration) مفید است.

مثال اول: ساختار کلاسیک (غیر اجرایی)

در این مثال فقط ساختار را می‌بینیم که چگونه instance_ ذخیره می‌شود.

python
# Static Code (Class definition structure)
class DatabaseConnection:
    _instance = None

    def __init__(self):
        if DatabaseConnection._instance is not None:
            raise Exception("This class is a singleton!")
        else:
            DatabaseConnection._instance = self

مثال دوم: پیاده‌سازی با __new__ (اجرایی)

در پایتون، متد __new__ قبل از __init__ صدا زده می‌شود و مسئول ساخت نمونه است. ما می‌توانیم این متد را بازنویسی کنیم تا کنترل کنیم آیا نمونه جدید ساخته شود یا خیر.

Python

۲. الگوی Factory Method (کارخانه)

الگوی Factory برای ساخت اشیاء بدون مشخص کردن کلاس دقیق آن‌ها استفاده می‌شود. این الگو به شما اجازه می‌دهد تا فرآیند ساخت شیء را از استفاده‌ی آن جدا کنید.

مثال اول: تعریف اینترفیس (غیر اجرایی)

ابتدا ساختار کلی کلاس‌ها را تعریف می‌کنیم.

python
# Static Code
class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

مثال دوم: پیاده‌سازی کامل Factory (اجرایی)

در اینجا یک تابع Factory داریم که بر اساس ورودی، کلاس مناسب را نمونه‌سازی می‌کند.

Python

۳. الگوی Observer (ناظر)

این الگو یک رابطه "یک‌به‌چند" بین اشیاء ایجاد می‌کند. وقتی وضعیت یک شیء (Subject) تغییر کند، تمام اشیاء وابسته به آن (Observers) به صورت خودکار مطلع می‌شوند. مثال بارز آن سیستم‌های اشتراک خبرنامه یا YouTube است.

مثال اول: پیاده‌سازی ساده (اجرایی)

Python

سطح پیشرفته (Professional Level)

در سطح حرفه‌ای، پیاده‌سازی الگوهای طراحی در پایتون با زبان‌های استاتیک متفاوت است. پایتون قابلیت‌هایی مثل Decorators، Metaclasses و First-class functions دارد که پیاده‌سازی الگوها را "پایتونیک" (Pythonic) و مختصر می‌کند. همچنین بحث Performance و Thread-Safety در اینجا مطرح می‌شود.

۱. پیاده‌سازی Pythonic Singleton با Metaclass

استفاده از __new__ روش خوبی است، اما استفاده از Metaclass‌ها کنترل سطح پایین‌تری روی تعریف کلاس به ما می‌دهد و کلاس اصلی را تمیز نگه می‌دارد.

مثال اول: متاکلاس (اجرایی)

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

Python

۲. الگوی Strategy با استفاده از توابع (Functional Strategy)

در زبان‌های شی‌گرا سنتی، برای الگوی Strategy باید کلاس‌های انتزاعی و ارث‌بری ایجاد کنید. در پایتون، چون توابع اشیاء درجه یک (First-class citizens) هستند، می‌توانیم توابع را مستقیماً به عنوان استراتژی پاس دهیم.

مثال اول: ساختار کلاسیک در مقابل پایتونیک (غیر اجرایی)

python
# Static Code (Traditional OOP approach - Verbose)
class Strategy:
    def execute(self): pass

class ConcreteStrategyA(Strategy):
    def execute(self): return "A"

مثال دوم: پیاده‌سازی پایتونیک (اجرایی)

در اینجا به جای کلاس، از توابع ساده برای تغییر رفتار برنامه استفاده می‌کنیم.

Python

۳. الگوی Decorator (ساختاری)

پایتون دکوریتورها را به صورت داخلی (@decorator) پشتیبانی می‌کند. اما درک الگوی طراحی Decorator که هدفش افزودن رفتار به یک شیء به صورت داینامیک است، فراتر از سینتکس پایتون است. ما می‌توانیم با کلاس‌ها دکوریتورهایی بسازیم که وضعیت (State) نگه دارند.

مثال اول: دکوریتور کلاس-محور (اجرایی)

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

Python

۴. الگوی Adapter (تطبیق‌دهنده)

این الگو زمانی استفاده می‌شود که بخواهید دو اینترفیس ناسازگار را به هم متصل کنید. در پایتون به دلیل Duck Typing، نیاز به این الگو کمتر حس می‌شود اما در پروژه‌های بزرگ برای یکسان‌سازی APIها حیاتی است.

مثال اول: آداپتور سوکت (اجرایی)

فرض کنید یک سوکت اروپایی داریم و می‌خواهیم آن را به پریز آمریکایی وصل کنیم.

Python