
وقتی توسعه یک محصول را شروع میکنیم، معمولاً همهچیز ساده است؛ یک وبسایت، یک پنل مدیریت و شاید یک API. در این مرحله فریمورکهایی مانند Laravel یا Symfony تقریباً برای هر نوع اپلیکیشنی انتخابی عالی هستند. آنها سالهاست ساخت نرمافزار را سریعتر، استانداردتر و لذتبخشتر کردهاند.
اما ساخت محصول، فقط انتشار نسخه اول نیست
محصولی که موفق باشد، متوقف نمیشود؛ رشد میکند. قابلیتهای جدید اضافه میشوند، تیم توسعه بزرگتر میشود و بخشهای مختلف محصول کمکم شخصیت مستقلی پیدا میکنند.
فرض کنید در حال توسعه یک پلتفرم آموزش آنلاین هستید؛ در ابتدا شاید فقط یک وبسایت و یک پنل مدیریت داشته باشید. اما با رشد محصول، پنل مدرس، پنل دانشجو، API عمومی، پنل پشتیبانی و سرویس احراز هویت نیز به آن اضافه میشوند.
از نگاه کاربر، همه این بخشها یک محصول واحد هستند. او انتظار دارد یک بار وارد حساب کاربری شود، بدون ورود مجدد بین بخشهای مختلف جابهجا شود و تجربهای یکپارچه داشته باشد.
اما از نگاه تیم توسعه، دیگر با یک اپلیکیشن واحد روبهرو نیستید. اکنون مجموعهای از Appها را مدیریت میکنید که هر کدام Frontend، وابستگیها، تیم توسعه و چرخه انتشار مخصوص خود را دارند.
در این نقطه، مسئله دیگر فقط توسعه یک اپلیکیشن نیست؛ بلکه مدیریت رشد یک محصول است.
وقتی محصول رشد میکند، معمولاً تیمها یکی از این مسیرها را انتخاب میکنند.
ادامه دادن با همان پروژه اولیه، در این روش، همه بخشهای محصول داخل یک پروژه توسعه پیدا میکنند. تا زمانی که محصول کوچک است، این رویکرد سریع و کمهزینه است؛ اما با اضافه شدن بخشهای جدید، وابستگی بین بخشها بیشتر میشود، توسعه موازی سختتر میشود و کوچکترین تغییر میتواند روی قسمتهای دیگر نیز تأثیر بگذارد و اضافه کردن فیچر تبدیل به کابوس تیم توسعه شود.
تفکیک به چند پروژه یا Repository مستقل، بسیاری از تیمها برای افزایش استقلال، هر بخش محصول را به یک پروژه جداگانه تبدیل میکنند. این کار به هر تیم اجازه میدهد مستقلتر توسعه و منتشر کند، اما در مقابل، هماهنگی بین Repositoryها، مدیریت نسخهها، Build، Deploy به چالش جدید پروژه تبدیل میشود.
استفاده از Microservices و Micro Frontends، در محصولات بزرگ، این معماریها انتخابی منطقی هستند و استقلال بالایی بین بخشهای مختلف ایجاد میکنند. اما این استقلال رایگان نیست؛ مدیریت ارتباط بین سرویسها، احراز هویت مشترک، هماهنگی نسخهها، مانیتورینگ و زیرساخت DevOps نیز به بخشی از پیچیدگی محصول تبدیل میشود.
هیچکدام از این رویکردها اشتباه نیستند؛ هر کدام برای حل مسئلهای مشخص طراحی شدهاند. اما با بزرگتر شدن محصول، بخش قابل توجهی از زمان تیم صرف مدیریت معماری و هماهنگی بین بخشها میشود؛ نه توسعه قابلیتهایی که برای کاربر ارزش ایجاد میکنند.
Pinoox تلاش نمیکند Framework بهتری برای ساخت یک app باشد؛ زیرا فریمورکهایی مانند Laravel و Symfony این مسئله را سالهاست بهخوبی حل کردهاند.
ایده Pinoox از سؤال دیگری شروع میشود:
اگر محصول شما از چندین App تشکیل شده است، چرا از همان ابتدا آن را به همین شکل توسعه ندهید؟
در Pinoox، محصول مجموعهای از Appهای مستقل است، برای مثال، یک محصول میتواند از Appهای زیر تشکیل شود:
landing
dashboard
user
api
هر App یک واحد مستقل است؛ ساختار، Routeها، Frontend، Assetها، تنظیمات، وابستگیها و حتی نسخه خودش را دارد. از نظر فنی، هر App یک واحد کامل MVC است؛ یعنی Controller، Model و View و Routeهای خودش را در مسیر مستقل apps/{package}/ دارد. این Appها میتوانند بهصورت موازی و حتی توسط تیمهای مختلف توسعه پیدا کنند، بدون اینکه مرز بین بخشهای مختلف محصول از بین برود.
اما تفاوت اصلی اینجاست که این Appها پروژههای جداگانه نیستند.
همه آنها روی یک Platform مشترک اجرا میشوند و Pinoox مدیریت آنها را بر عهده میگیرد؛ از مسیریابی بین Appها گرفته تا اجرای آنها، اشتراک سرویسهای مشترک و انتشار نسخههای جدید. در نتیجه، هر App استقلال خود را حفظ میکند.
در Pinoox، مسئله فقط توسعه یک App نیست که کار میکند؛ مسئله، ساخت محصولی است که بتواند همراه با رشد تیم، اضافه شدن بخشهای جدید و افزایش نیازهای کسبوکار، بدون افزایش بیرویه پیچیدگی به توسعه سریع خود ادامه دهد.
فرض کنید یک App مسئول کاربران و احراز هویت باشد.
تمام Appهای دیگر میتوانند از همان کاربران، Session و مجوزهای دسترسی استفاده کنند تا کاربر فقط یک بار وارد سیستم شود، در عین حال، اگر بخشی از محصول نیاز متفاوتی داشته باشد، میتواند سیستم کاربران یا احراز هویت کاملاً مستقل خودش را پیادهسازی کند.
استقلال Appها نباید به معنی پیچیدهتر شدن مدیریت محصول باشد.
هر App نسخه و چرخه توسعه خودش را دارد، اما انتشار محصول همچنان از یک نقطه انجام میشود. برای شروع سریع ساخت App، دستورات CLI یکپارچهای مانند php pinoox app:create ساختار استاندارد را بهطور خودکار میسازند؛ یعنی افزودن یک بخش تازه به محصول، چند دستور بیشتر طول نمیکشد.
اینجاست که معنای واقعی HMVC (Hierarchical MVC) در Pinoox روشن میشود. در MVC معمولی، کل پروژه یک Controller، Model و View مشترک دارد که با رشد محصول، همه در یک لایه انباشته میشوند. اما در HMVC، هر App خودش یک واحد کامل و مستقل MVC است؛ Controller، Model و View مخصوص به خودش را دارد و میتواند مثل یک اپلیکیشن کوچک، جدا از بقیه اجرا و توسعه پیدا کند. هسته Pinoox این واحدهای MVC مستقل را در یک سلسلهمراتب (Hierarchy) کنار هم مدیریت میکند؛ مسیر درخواست را به App درست هدایت میکند، سرویسهای مشترک (مثل کاربران یا Session) را بین آنها به اشتراک میگذارد و در نهایت همه را بهعنوان یک محصول واحد منتشر میکند. به همین دلیل، بهجای یک MVC بزرگ و بههموابسته، با چند App کوچک و مستقل روبهرو هستید که هرکدام چرخه MVC خودشان را دارند، ولی زیر یک پلتفرم مشترک هماهنگ میشوند:
pinoox-platform/ ├── apps/ │ ├── com_pinoox_landing/ │ │ ├── controller/ │ │ ├── model/ │ │ ├── view/ # قالبهای Twig │ │ ├── assets/ │ │ ├── route.php │ │ └── app.php # تنظیمات و مشخصات App │ │ │ ├── com_pinoox_dashboard/ │ │ ├── controller/ │ │ ├── model/ │ │ ├── view/ │ │ ├── assets/ │ │ ├── route.php │ │ └── app.php │ │ │ ├── com_pinoox_user/ │ ├── controller/ │ ├── model/ │ ├── flow/ # لایههای احراز هویت و دسترسی │ ├── route.php │ └── app.php │ └── composer.json
هر پوشه داخل apps/ دقیقاً معادل یک App مستقل است؛ فایل app.php هویت، نسخه و وابستگیهای همان App را مشخص میکند و باعث میشود هنگام Build، Pinoox بداند هر بسته Pinx باید از کدام پوشه ساخته شود. به همین دلیل، اضافه یا حذف یک App (مثلاً حذف کامل api در فاز MVP) صرفاً به معنی افزودن یا حذف یک پوشه است، نه دستکاری در بقیه پروژه.
وقتی نسخه جدید منتشر میشود، Pinoox یک بسته نصب یا بروزرسانی برای کل محصول تولید میکند و فقط Appهایی که تغییر کردهاند بروزرسانی میشوند. این کار از طریق بستهبندی سبک Pinx انجام میشود؛ هر App هنگام انتشار در قالب یک بسته فشرده مستقل بستهبندی میشود، بنابراین بهجای انتقال کل پروژه، فقط همان App یا حتی فقط بخشهای تغییریافته منتقل میشود. در نتیجه، تیمها میتوانند مستقل توسعه دهند، بدون اینکه فرآیند نصب، بروزرسانی و نگهداری محصول به مجموعهای از عملیات پراکنده تبدیل شود.
در یک استارتاپ، میتوانید Appهای آماده مارکت را استفاده کنید و فقط روی بخشهایی تمرکز کنید که محصول شما را متمایز میکنند.
با بزرگتر شدن تیم، هر گروه مسئول چند App میشود و بدون ایجاد تداخل با دیگران توسعه را ادامه میدهد.
و اگر چند سال بعد محصول شما از چند App به چند ده App برسد، همان معماری همچنان پاسخگوی نیازهای شما خواهد بود؛ بدون بازنویسی پروژه، بدون مهاجرت به معماری جدید و بدون تبدیل شدن محصول به یک Monolith پیچیده یا مجموعهای از پروژههای پراکنده.
Frameworkهایی مانند Laravel و Symfony ساخت انواع Application را به بهترین شکل ممکن ساده کردهاند و همچنان انتخابی عالی برای بسیاری از پروژهها هستند.
اما وقتی یک محصول به مجموعهای بزرگ تر تبدیل میشود، چالش اصلی دیگر فقط توسعه یک app نیست؛ بلکه مدیریت رشد، هماهنگی و نگهداری کل محصول است.
Pinoox با همین نگاه طراحی شده است. معماری آن به شما کمک میکند از همان روز اول، محصول را به مجموعهای از Appهای مستقل اما یکپارچه تقسیم کنید؛ Appهایی که میتوانند مستقل توسعه پیدا کنند، اما همچنان مانند یک محصول واحد مدیریت، منتشر و نگهداری شوند.
به همین دلیل، مفاهیمی مانند Apps، HMVC، App Router، Flow و Transport صرفاً قابلیتهای فنی نیستند؛ بلکه اجزای معماریای هستند که پیچیدگی رشد محصول را کاهش میدهند تا تیم شما زمان بیشتری را صرف توسعه قابلیتهای محصول کند، نه مدیریت پیچیدگیهای فنی.