بهزاد شعبانی

توسعه دهنده پی‌اچ‌پی و لاراول

چند دیدگاه در مورد مهندسی نرم‌افزار

چند روز پیش داشتم با رضا و مرتضی در مورد مهندسی نرم‌افزار بحث می‌کردیم. بحث از اونجا شروع شد که رضا اومد راجب پروژه Cachet و اینکه چقد ساده و بدون استفاده از دیزاین پترن خاصی همه‌ی منطق برنامه رو تو کنترل‌ها نوشته، صحبت کرد. رضا معتقد بود این روش که بهش Glassy Code میگن برای پروژه‌های کوچیک تا متوسط و پروژه‌هایی که دائما در حال تغییرن مناسبه و بهتره ما هم ازین روش استفاده کنیم و خودمون رو درگیر معماری‌های دیگه نکنیم. من و مرتضی اول بحث با حرف رضا مخالف بودیم و کلی سر این موضوع با هم بحث کردم. در نهایت هر سه تامون به یه نتیجه تقریبا جامع رسیدیم. منم تصمیم گرفتم این نتیجه‌گیری‌ها رو از دیدگاه هرکدوممون با شما به اشتراک بذارم.

دیدگاه رضا و مرتضی به شکل نقل قول بیان شدن.

دیدگاه رضا

مهندسی نرم‌افزار، خیلی جاها خوبه و خیلی جاها چاقو میشه و به خودت آسیب می‌رسونه. بحث‌های مهندسی نرم‌افزار جدا از متودولوژی‌ها، که در تخصص من نیست، خیلی کلی هستن؛ و حتی پیاده سازیشون تو بعضی زبان‌ها ممکنه خیلی سخت باشه. مثلا Repository Pattern تو php.

تجربه کردن خیلی خوبه، حتی اگه به ضرر پروژه‌ای باشه که داریم انجام می‌دیم. شاید نصف کدهایی که من تو آی‌برتر زدم از همین فلسفه پیروی کنه، چون برا من مهمه که برنامه‌نویس بهتری باشم و به اندازه کافی سواد داشته باشم که بتونم نتیجه‌گیری کنم؛ و تا وقتی منطق‌های مختلف رو امتحان نکنی، نمی‌تونی نتیجه‌گیری کنی. دقیقا در مورد ریپازیتوری پترن این اتفاق برام افتاد. یه مدت باهاش کار کردم، باهاش پروژه زدم، حتی سعی کردم با اون پکیجی که تو گیت‌هاب نوشتم کامل پیاده‌سازیش کنم. ولی الان می‌تونم این نتیجه رو بگیرم که استفاده از ریپازیتوری پترن در کنار Eloquent یه کار بیهوده‌ست. چون در نهایت مجبور می‌شی یه Eloquent دیگه کنارش پیاده‌سازی کنی که وابسته به همون دیتا استوریج اصلی هست. همینطور Domain Driven Design رو هم تجربه کردم، و دیدم که واقعا چیزای خوبی داره و هنوزم ازش استفاده میکنم.

بعدش چنتا ویدیو، پادکست و بلاگ پست درباره همین بحثایی که مطرح کردم، خوندم و دیدم اون‌ها هم خیلی بی‌ربط نمی‌گن. از نظر من، الان کامیونیتی خیلی مهمه شده. من با ddd خیلی حال میکنم، ولی واقعا برای یه اپلیکیشنی که 15-16 تا API داره، این چیزا اصلا مهم نیست. اینکه شبیه به چیزی که کامیونیتی پیشنهاد میده کد بزنی مهم‌تره؛ چون هم بقیه می‌فمنش، هم با ابزارایی که در اختیارت می‌ذاره پروژه زودتر تموم میشه.

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

دیدگاه مرتضی

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

دیدگاه من

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

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

عوامل زیادی در انتخاب بهترین معماری و دیزاین پترن، برای یه پروژه، دخیل هستن؛ مثل مهلت انجام پروژه، زمان نگه‌داری پروژه و مقدار تغییرات احتمالی. به عنوان مثال؛ برای پروژه‌ای که احتمال ایجاد تغییرات، در اون زیاد هست، باید معماری‌ای که نسبت به تغییرات انعطاف پذیر هست، رو انتخاب کنیم. و برای پروژه‌ای که مهلت کمی برای تکمیل شدن داره، باید معماری‌ای که سرعت توسعه در اون زیاد هست رو انتخاب کنیم.

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

جمع‌بندی

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

comments powered by Disqus