Model View Controller یا به اختصار MVC نوعی روش معماری نرمافزار است که در توسعهٔ وب اپلیکیشنها بسیار پرکاربرد است و ورود آن به صنعت توسعهٔ نرمافزار به دههٔ 1970 بازمیگردد. امروزه فریمورکهای مطرحی که در توسعهٔ نرمافزارهای کوچک و بزرگ مورد استفاده قرار میگیرند مبتنی بر این معماریاند که برخی از مهمترین آنها عبارتند از:
Ruby | PHP | JavaScript | Python |
Ruby on Rails | Laravel | Express | Django |
Sinatra | Zend | Angular | Flask |
به طور خلاصه، میتوان گفت که هدف از معماری سهلایهٔ امویسی مجزاسازی بخشهای مختلف نرمافزار از یکدیگر است به طوری که بتوان هر کدام از این بخشها یا ماژولها را به صورت مستقل توسعه داد و در نهایت مابین آنها ارتباط برقرار ساخت. به عبارت دیگر، چندین و چند دولوپر مختلف میتوانند روی پروژههایی با این نوع معماری کار کنند بدون آنکه در کار یکدیگر تداخلی ایجاد نمایند.
درآمدی بر تاریخچهٔ معماری MVC
Trygve Reenskaug یک دانشمند علوم کامپیوتری نروژی است که به عنوان خالق اصلی معماری MVC شناخته میشود به طوری که وی در سال 1979 به منظور توسعهٔ GUI با استفاده از زبان Smalltalk از این معماری استفاده کرد و در سالهای بعد این معماری به مرور در میان توسعهدهندگان مختلف رواج پیدا کرد تا جایی که الگوهای دیگری من جمله HMVC ،MVA ،MVP و MVVM بر این اساس شکل گرفتند.
ورود این معماری به توسعهٔ وب به سال 1996 بازمیگردد که در آن کمپانی NeXT به معرفی WebObjects پرداخت که با استفاده از زبان آبجکتیوسی نوشته شده بود و این در حالی بود که پس پورت شدن WebObjects به زبان جاوا، معماری امویسی در میان توسعهدهندگان جاوا نیز جای خود را باز کرد و از آن زمان به بعد فریمورکهایی همچون Spring اصول این معماری را حفظ کردند.
همانطور که پیش از این اشاره کردیم، عرضهٔ فریمورکهایی مبتنی بر این معماری همچون Django و Ruby on Rails که با شعار توسعهٔ سریع اپلیکیشن در اختیار توسعهدهندگان قرار گرفتیند، کمک بسیاری به محبوبیت این معماری کرد و امویسی که ابتدا به ساکن برای توسعهٔ اپلیکیشنهای دسکتاپ معرفی شده بود را به بخش لاینفک توسعهٔ وب مبدل ساخت.
آیا MVC یک Design Pattern است؟
پیش از پاسخگویی به پرسش فوق، ابتدا نیاز است تا بدانیم «دیزاین پترن چیست؟» که در همین راستا توصیه میکنیم برای کسب اطلاعات بیشتر به دورهٔ آشنایی با الگوهای طراحی مراجعه نمایید. به طور خلاصه، در پاسخ به این سؤال باید گفت که:
دیزاین پترن به مجموعه راهکارهایی گفته میشود که میتوانند برای حل مسائلی تکراری استفاده شوند که معمولاً در حین کدنویسی پروژههای نرمافزاری ایجاد میگردند. در واقع، دیزاین پترن یا «الگوی طراحی» راهکاری است تضمینی که پیش از این توسط توسعهدهندگان حرفهای ابداع گردیده و آزمایش خود را پس دادهاند و این در حالی است که سایر دولوپرها با خیال راحت میتوانند با پیروی از آنها اپلیکیشنهایی توسعه دهند که انعطافپذیر، قابلتوسعه، ساختاریافته و همچنین اصولی باشند.
حال که با مفهوم Design Pattern آشنا شدیم، نیاز است تا به بررسی MVC بپردازیم که زیرشاخهٔ مفهومی تحت عنوان Architectural Pattern به معنی «الگوی معماری» است. اساساً میتوان گفت که منظور از الگوی معماری نحوهٔ چیدمان بخشهای مختلف نرمافزار در کنار یکدیگر و همچنین نحوهٔ تعامل چنین بخشهایی با یکدیگر است.
برای درک بهتر این موضوع، میتوان به مفهوم رایج معماری در ساختوساز توجه کرد. در واقع، همانطور که یک معمار در طرحریزی ساختمانی که میسازد دقیقاً مشخص میکند که محل قرارگیری بخشهای مختلف یک ساختمان کجا باشند، یک دولوپر (معمار نرمافزار) نیز با پیروی از اصول امویسی دست به مشخصسازی نوع، چیدمان و چگونگی ارتباط کامپوننتهای مختلف در یک نرمافزار میزند.
آشنایی با مفهوم Model در معماری MVC
Model را به نوعی میتوان به منزلهٔ مغز اپلیکیشن در نظر گرفت به طوری که اصطلاحاً Business Logic یا به عبارتی «آنچه اپلیکیشن به خاطرش توسعه یافته است» در این لایه طرحریزی میشود. مسلماً نیاز به توضیح نیست که مثلاً در یک وب اپلیکیشن بخشی از منطق نرمافزار مرتبط با ارتباط با دیتابیس به منظور انجام عملیات CRUD است که تَسکهایی از این دست در مدل عملی میگردند.
نکته
سرواژهٔ CRUD برگرفته از کلمات Update ،Read ،Create و Delete است که به ترتیب به منظور «ثبت»، «فراخوانی»، «بهروزرسانی» و «حذف» دادهها از دیتابیس مورد استفاده قرار میگیرند.
کنترلر که در ادامه بیشتر با مفهوماش آشنا خواهیم شد، همواره ارتباط تنگاتنگی با مدل دارا است به طوری که میتوان گفت ارتباط مدل با ویو از طریق کنترلر امکانپذیر خواهد بود.
آشنایی با مفهوم View در معماری MVC
View، همانطور که از نام آن مشخص است، این وظیفه را دارا است تا دیتایی که در مدل ساخته و پرداخته شده را در معرض دید کاربران وب اپلیکیشن قرار دهد و به عبارتی میتوان گفت که همان User Interface یا به اختصار UI است.
ویو به طور معمول حاوی کدهای اچتیامال و سیاساس است و دادههای دینامیک (پویا) نیز از روشهای مختلفی که یکی از آنها Template Engine است در ویو بارگزاری میشوند (به طور مثال، در فریمورک لاراول از تِمپلیت اِنجینی تحت عنوان Blade استفاده میشود تا در نهایت کدهای پیاچپی داخل کدهای اچتیامال قرار داده شده و خروجی آنها در معرض دید کاربران قرار گیرند.)
آشنایی با مفهوم Controller در معماری MVC
Controller در این معماری سهلایه نقش واسط را دارا است به طوری که ریکوئستها را از بخش ویو گرفته و در اختیار مدل قرار میدهد و پس از آنکه مدل پردازشهایش را روی ریکوئست (درخواست) ورودی انجام داد، ریسپانس (پاسخ) را مجدد در اختیار کنترلر قرار داده و کنترلر هم پاسخ نهایی را در اختیار ویو میگذارد تا در معرض دید کاربران قرار دهد.
آشنایی با ارتباطات مابین View ،Model و Controller
به منظور درک بهتر این موضوع، میتوان فرم لاگین سایتها را مد نظر قرار داد به طوری که در بخش ویو فرمی در اختیار کاربران قرار میگیرد تا بتوانند نام کاربری و رمزعبور خود را وارد کنند.
همانطور که در تصویر فوق مشخص است، پس از آنکه کاربر دکمهٔ سابمیت را فشرد (مرحلهٔ اول)، درخواستی از جنس POST برای کنترلر ارسال میگردد و کنترلر هم درخواست ورودی را گرفته و در اختیار مدل قرار میدهد (مرحلهٔ دوم) که در این فاز مدل یک کوئری به دیتابیس میزند (مرحلهٔ سوم) تا ببیند آیا نام کاربری و رمزعبور درست هستند یا خیر؛ خواه اطلاعات درست وارد شده باشند و خواه اشتباه، در مرحلهٔ بعد مدل پاسخی را در اختیار کنترلر قرار میدهد (مرحلهٔ چهارم) و کنترلر هم پاسخ دریافتی را در اختیار ویو گذاشته (مرحلهٔ پنجم) سپس ویو نیز خروجی کار را در معرض دید کاربر قرار میدهد (مراحل ششم و هفتم).
در همین راستا، مفهومی که ارتباط نزدیکی با این معماری دارد تحت عنوان Routing شناخته میشود. به طور خلاصه، منظور از این اصطلاح آن است که ما ابتدا به ساکن نیاز به تعریف یکسری Route یا URL و یا Link داریم که مشخص میکنند کاربر به چه لینکهایی در وب اپلیکیشنما دسترسی دارد و هر چیزی به غیر از لینکهایی که از قبل تعریف شدهاند را وارد سازد، با ارور 404 مواجه خواهد شد.
در حقیقت، Routing مشخص میسازد که ویوها از چه مسیرها یا لینکهایی در معرض دید کاربران قرار میگیرند و همان لینکها در نهایت به کنترلرهای مشخصی ختم میشوند که ریکوئستهای کاربران را گرفته و در اختیار مدل میگذارند و پس از دریافت ریسپانس از مدل، مجدد نتیجهٔ نهایی را در اختیار ویو میگذارند.
درآمدی بر مزایا و معایب استفاده از معماری MVC
با توجه به حداقل وابستگی که مابین لایههای مختلف یک اپلیکیشن نوشتهشده مبتنی بر معماری MVC وجود دارد، دولوپرها بدون آنکه در کار یکدیگر تداخلی ایجاد کنند قادر خواهند بود تا روی کامپوننتهای مختلف کار کنند. به طور مثال، دولوپرهای بکاند حتی بدون آنکه بخش رابط کاربری سایت تکمیل شده باشد میتوانند دست به توسعهٔ Business Logic اپلیکیشن بزنند و بر همین منوال دولوپرهای فرانتاند نیز میتوانند ابتدا ساختار اصلی صفحات را به صورت استاتیک طراحی کرده سپس با تکمیل بخش بکاند اقدام به دینامیک کردن صفحات نمایند.
با استفاده از معماری امویسی به سادگی میتوان بخشهایی از اپلیکیشن که مرتبط با یکدیگر هستند را در قالب یک ماژول یا کامپوننت قرار داد و از آنجا که در این معماری کامپوننتها دارای وابستگی حداقلی به یکدیگر هستند، به سادگی این امکان در اختیار توسعهدهندگان قرار میگیرد تا از کامپوننتهایی که نوشتهاند در سایر پروژهها نیز استفاده نمایند.
با توجه به ماهیت Loose Coupling که در این معماری به کار گرفته میشود (به عبارتی وابستگی حداقلی مابین بخشهای مختلف نرمافزار وجود دارد)، افزودن فیچرهای جدید و یا تغییر در کدهای قبلی به مراتب آسانتر خواهد شد و به عنوان آخرین مزیت معماری MVC هم میتوان به این نکته اشاره کرد که دیتایی که کنترلر از مدل گرفته را میتوان به روشهای مختلفی در معرض دید کاربران قرار داد. به طور مثال، در یک وب اپلیکیشن میتوان این دیتا را در قالب صفحات اچتیامال رِندِر کرده و به کاربران نشان داد و یا میتوان دیتا را به صورت جیسون در اختیار یک API قرار داده و از طریق یک اپ موبایل دادهها را در اختیار کاربران گذاشت (جهت آشنایی با این اصطلاح میتوانید به آموزش API چیست؟ مراجعه نمایید.)
در کنار تمامی مزایایی که برای این معماری برشمردیم، یکسری نقاط ضعف هم در ارتباط با امویسی وجود دارد که آگاهی از آنها خالی از لطف نیست. به طور مثال، با توجه به ماهیت Abstraction یا «انتزاع» که در این معماری وجود دارد، وقتی دولوپر جدیدی بخواهد روی چنین پروژههایی کار کند ممکن است در ابتدا کمی سردرگم گردد اما در عین حال میتوان گفت که این سردرگمی پس از مدتی کار با پروژه به مرور مرتفع خواهد شد.
جمعبندی
در پایان لازم به یادآوری است که معماری امویسی تحت هیچ عنوان حاوی یکسری اصول و استانداردهای سختگیرانه نیست که عدم تبعیت از آنها منجر به ایجاد مشکل در اپلیکیشن گردد بلکه امویسی را میتوان به منزلهٔ یک راهنما به منظور طراحی معماری اپلیکیشن در نظر گرفت که با رعایت آن میتوان این تضمین را ایجاد کرد که اپلیکیشنی با حداقل پیچیدگی، انعطافپذیری بالا و قابلتوسعه خواهیم داشت.
همچنین نیاز به ذکر یکسری آنتی پترن یا به عبارتی روش غیرحرفهای توسعهٔ نرمافزار در ارتباط با معماری امویسی است و آن هم اینکه برخی دولوپرها به اشتباه بخشی از لاجیک (منطق) نرمافزار را داخل کنترلر مینویسند! به عبارتی، برخی وظایفی که اصولاً بر عهدهٔ مدل میباشد را به کنترلر محول میکنند و این در حالی است که کنترلر صرفاً نقش یک میانجی را دارا است و از نوشتن هرگونه الگوریتمی در این لایه باید خودداری کرده و کلیهٔ مواردی از این دست را داخل مدل هندل کرد.
به علاوه، گاهی اوقات میبینیم که برخی دولوپرها اصل عدمِ وابستگی را مابین ماژولهای مختلف یک وب اپلیکیشن را رعایت نمیکنند و همین مسئله منجر بدین خواهد شد تا ماژولهایی که نوشتهایم قابلیت استفادهٔ مجدد نداشته باشند!