- Log in to post comments
یکی از بزرگترین تغییرات راهبردی در دروپال زمانی رخ داد که از نسخهٔ ۸ به بعد، این سیستم مدیریت محتوا (CMS) یا بهتر بگوییم پلتفرم، معماری خود را از سبک عمدتاً رویهای (procedural) به سمت معماری شیٔگرا و سرویسمحور (object-oriented & service-oriented) تغییر داد. این تحول با هدف بهبود قابلیت نگهداری، گسترشپذیری، خوانایی و تطابق با استانداردهای مدرن زبان PHP و ابزارهای آن انجام شد.
در این مقاله ابتدا دلایل این تحول را بررسی میکنیم، سپس اصول معماری شیٔگرا در دروپال را تشریح مینماییم، پس از آن بخشهای کلیدی این معماری در دروپال را معرفی میکنیم، و در نهایت نکات کاربردی برای توسعهدهندگان و پروژههای سفارشی ارائه خواهیم داد.
بخش اول: چرا معماری شیٔگرا در دروپال؟
تغییراتی که در نسخهٔ ۸ دروپال اتفاق افتاد، نه صرفاً افزودن امکانات جدید، بلکه بازطراحی بنیادین معماری بود. از جمله دلایل این تغییرات میتوان به موارد زیر اشاره کرد:
نیاز به جذب توسعهدهندگان بیشتر با تجربهٔ فریمورکهای مدرن PHP، به طوری که نقشهٔ راه دروپال بتواند با اکوسیستم گستردهتری از ابزارها و استانداردها همخوان شود.
مشکل خوانایی، نگهداری و پیچیدگی در کدهای نسخهٔ پیشین؛ استفادهٔ گسترده از توابع رویهای و آرایههای ساختاری باعث شده بود کدهای ماژولها و هسته سخت قابل توسعه و نگهداری باشند.
میل به تطابق با چارچوبهایی مانند Symfony، استفاده از مفاهیم سرویسمحور، تزریق وابستگی (Dependency Injection) و رعایت PSR- (مثلاً PSR-4) استانداردها.
تمایل به ارائهٔ پلتفرمی مقیاسپذیرتر، قابل نگهداریتر و مناسبتر برای پروژههای بزرگ، سازمانی یا چندسکویی (decoupled).
در نتیجه، از دروپال ۸ به بعد معماری هسته و ماژولها عمدتاً بر پایهٔ کلاسها، سرویسها، فضاینام (namespaces)، تزریق وابستگی، رویدادها، و طراحی ماژولار شکل گرفت.
بخش دوم: اصول معماری شیٔگرا و چگونه در دروپال مطرح شدهاند
در زیر مهمترین اصولی که معماری شیٔگرا را شکل میدهند و در دروپال نیز به کار گرفته شدهاند آورده شده است:
۱. انتزاع (Abstraction)
به معنای جدا کردن مفهوم (interface) از جزئیات پیادهسازی. در دروپال، ماژولها و سرویسها معمولاً رابطهایی (interfaces) دارند که نمیخواهیم کاربران ماژول مجبور به شناخت جزئیات درون آن باشند بلکه با روشهایی سطح بالا تعامل نمایند.
۲. کپسولهسازی (Encapsulation)
نه تنها دادهها بلکه رفتارها نیز درون کلاسهایی قرار میگیرند که وضعیت داخلیشان پنهان است و از طریق متدهای عمومی قابل دسترسی هستند. باعث میشود که تغییرات داخلی کلاس بر مصرفکنندهٔ آن تأثیر کمتری داشته باشد.
۳. وراثت (Inheritance)
کلاسها میتوانند از کلاسهای پایه ارث ببرند، ویژگیها و متدهای مشترک را به اشتراک بگذارند و رفتار را گسترش دهند. در دروپال این معماری بیشتر در بخشهای plugin، entity، و سرویسها مشاهده میشود.
۴. چندریختی (Polymorphism)
به معنا امکان استفادهٔ واحد از روشهایی که در کلاسهای متفاوت پیادهسازی شدهاند. برای مثال، استفادهٔ یک رابط یا کلاس پایه برای سرویسهای مختلف با پیادهسازی متفاوت. این باعث میشود افزونهپذیری ماژولها راحتتر شود.
۵. تزریق وابستگی (Dependency Injection)
بهجای فراخوانی مستقیم سرویسها از کلاسهای دیگر (مثلاً استفاده از تابع جهانی یا Singleton)، سرویسها به صورت وابستگی به کلاس وارد میشوند (مثلاً از طریق سازنده یا setter) که باعث افزایش تستپذیری و کاهش اتصال سخت (tight coupling) میگردد.
۶. طراحی ماژولار و سرویسمحور (Service-Oriented Architecture)
ماژولها در دروپال ۸+ به جای استفاده صرف از هوکهای رویهای برای هر کاری، بیشتر حول سرویسها، رویدادها و پلاگینها شکل میگیرند. سرویسها توسط کانتینر سرویس دروپال مدیریت میشوند و قابل تزریق و جایگزینی هستند.
بخش سوم: معماری کلیدی در دروپال ۸ به بعد
در این بخش نگاهی میاندازیم به اجزای اصلی معماری شیٔگرا در دروپال و چگونگی ارتباط آنها با هم.
سرویسها (Services)
در دروپال ۸ به عنوان یکی از پایههای معماری شیٔگرا، مفهوم سرویس معرفی شد: هر شیء که توسط کانتینر سرویس مدیریت میشود و میتواند در هر نقطه از سیستم فراخوانی شود. ماژولها میتوانند سرویسهای جدید تعریف کنند و یا سرویسهای هسته یا سایر ماژولها را بازتعریف نمایند.
برای مثال، تعریف سرویس در فایل mymodule.services.yml و سپس استفاده از آن در کلاس از طریق تزریق وابستگی.
فضاینام (Namespaces) و PSR-4
به منظور جلوگیری از برخورد نامهاو ساختار ماژولار منظمتر، دروپال از فضاینامها (namespaces) و استاندارد PSR-4 برای بارگذاری اتوماتیک کلاسها استفاده میکند. این باعث میشود کلاسها به صورت منظم در پوشههای ماژول قرار گیرند و بارگذاری کلاسها سادهتر شود.
پلاگینها (Plugins)
یکی از معماریهای بسیار مهم در دروپال ۸+، سیستم پلاگین است. پلاگینها کلاسهایی هستند که براساس تعریف مشخص و annotation یا YAML، در نقطههای توسعه (extension points) قرار میگیرند. این معماری کاملاً شیءگراست و توسعهدهنده به راحتی میتواند پلاگینهای جدید ایجاد یا جایگزین کند.
رویدادها و مشترکین رویداد (Events / Event Subscribers)
با ورود به سبک شیءگرا، دروپال اکنون از سیستم رویدادها (Event Dispatcher) استفاده میکند: رویدادها اشیایی هستند که منتشر میشوند و کلاسهای مشترک (Subscribers) میتوانند به آنها گوش دهند. این معماری باعث کاهش اتصال ماژولها به هم و افزایش افزونهپذیری میشود.
موجودیتها (Entities) و افزونههای فیلد (Field API)
در نسخهٔ ۸، مفهوم entity در سطح عمیق بازطراحی شد. هر موجودیتِ سیستم نظیر نود، یوزر، ترمهای طبقهبندی بهصورت کلاس تعریف شده، و عملیات آنها از طریق متدها انجام میشود نه صرفاً آرایهسازی. این طراحی، بهرهگیری از اصول شیءگرا را امکانپذیر کرده است.
کنترلرها (Controllers) و مسیرها (Routes)
در دروپال ۸ به بعد، مفهوم مسیرها (routing) از Symfony اقتباس شده و کنترلرها به صورت کلاسهایی با متدهایی برای پاسخ به مسیرها نوشته میشوند. این الگو جایگزین بسیاری از کدهای رویهای در نسخههای قدیمیتر شده است.
بخش چهارم: مزایا، چالشها و نکات پیادهسازی
مزایا
نگهداری و خوانایی کد بسیار بهتر است.
امکان نوشتن تستهای واحد (unit tests) و تستهای یکپارچه بالا میرود.
افزونهپذیری افزایش مییابد: سرویسها و پلاگینها به سادگی قابل جایگزینی هستند.
معماری منسجمتر و سازگارتر با ابزارها و فریمورکهای مدرن PHP.
کاهش وابستگیهای سخت (tight coupling) و بهبود جداسازی مسئولیتها (separation of concerns).
چالشها
منحنی یادگیری برای توسعهدهندگانی که با سبک رویهای آشنا هستند ممکن است بالا باشد.
تولید کد ممکن است بیشتر زمان ببرد (طراحی و معماری بهتر نیاز دارد).
اگر بهدرستی شکل نگیرد، ممکن است پیادهسازی بیش از حد پیچیده شود.
برای پروژههای کوچک و سریع شاید بار معماری شیءگرا زیاد به نظر برسد.
نکات کاربردی برای توسعهدهندگان
تا حد ممکن از تزریق وابستگی استفاده کنید و از فراخوانی مستقیم سرویسها (مثلاً
\Drupal::service()) بپرهیزید.در ماژولها سرویسها را در فایل
*.services.ymlتعریف نموده و تنظیم نمایید که قابل جایگزینی باشند.پلاگینها را با دقت و با مستندسازی ایجاد کنید و از annotation یا YAML مناسب استفاده نمایید.
کنترلرها، سرویسها، مشترکین رویداد را در فضاینام مناسب قرار دهید و ساختار پوشهای ماژول را منظم نگه دارید.
اگر پروژه شما بزرگ است، معماری ماژولها را جداسازی کنید: مثلا یک بخش سرویس، یک بخش پلاگین، یک بخش رویداد، یک بخش entity.
از تستنویسی بهره بگیرید: کلاسها به واسطهٔ شیءگرا بودن خیلی بهتر قابل تست هستند.
در مستندسازی ماژولها توجه داشته باشید که سرویسها، پلاگینها، رویدادهای منتشرشده، وابستگیها و رتبهبندی (priority) سرویسها مشخص باشد.
بخش پنجم: روند آینده و توصیهها
معماری دروپال همچنان در حال تکامل است. نسخههای جدیدتر توجه بیشتری به استانداردهایی چون PSR-12، اتوماسیون تست، معماری بدون هوک (hook-less) و کاهش وابستگی به کد رویهای دارند. توصیه میشود توسعهدهندگان جدید دروپال از همان ابتدا با معماری شیءگرا، سرویسمحور، تزریق وابستگی و ساختار پلاگین آشنا شوند تا ماژولها و پروژههایشان آمادهٔ مقیاسپذیری و نگهداری بلندمدت باشند.
نتیجهگیری
ورود معماری شیءگرا در دروپال از نسخهٔ ۸ نشانهٔ مسیر تحول این پلتفرم به سمت پلتفرمی مدرنتر بود. با اتخاذ مفاهیمی چون سرویسها، فضاینامها، پلاگینها، رویدادها و تزریق وابستگی، دروپال امکان ساخت ماژولها و برنامههای قویتر، قابل نگهداریتر و توسعهپذیرتر را فراهم کرده است. اگرچه این تحول چالشهایی نیز دارد، اما بهرهمندی از آن برای پروژههای حرفهای تقریباً اجتنابناپذیر است.