نویسنده: ابراهیم نبییی (معمار نرم افزار)
داستان یک شکست
شروع یک پروژه نرم افزاری همیشه هیجان انگیز است اما رفته رفته مشکلات چهره خود را به تیم توسعه نرم افزار نشان می دهند. برای بررسی بهتر این مشکلات تجربه واقعی یک شکست که در یکی از تیم های چابک اتفاق افتاده است را مرور می کنیم. این پروژه مانند بسیاری از پروژههای نرم افزاری شروعی امیدوار کننده داشت و عملکرد تیم توسعه در تکرارهای آغازین پایدار و مطلوب بود. متاسفانه پس از گذشت حدود 6 ماه، هزینه تغییرات به شکل نمایی رو به رشد گذاشت. این هزینه به قدری زیاد بود که عملا افزودن هر ویژگی جدید به نرم افزار یا تغییر در ویژگیهای موجود آن را غیر ممکن ساخته بود و حتی اگر تغییرات قابل انجام بودند نیز منجر به بروز تعداد زیادی خطا می شد. بدیهی است که افزایش هزینه تغییرات منجر به کاهش عملکرد تیم توسعه شده بود و برآورد ایشان از ادامه وضعیت موجود به شرح زیر گزارش شده بود:
- تغییر در زمانبندی ارائه محصول غیر قابل اجتناب است.
- تخمین دقیقی از زمان ارائه محصول و حجم کار باقیمانده قابل ارائه نیست.
- تیم توسعه توان تولید ویژگی های جدید و بهبود ویژگی های موجود را ندارد در نتیجه لازم است در معماری نرم افزار، رویکرد طراحی، انتخاب تکنولوژی و … بازنگری جدی صورت گیرد.
سرمایه گذاران پروژه علی رغم نارضایتی، تقریبا قانع شده بودند که آنچه تا کنون از نرم افزار تولید شده است قابل استفاده نیست و برای جلوگیری از زیان های آتی باید پروژه بازنویسی شود. این در حالی بود که تیم توسعه چون قصد ترک کردن یک پروژه Brown field و ورود به یک پروژه Green field را داشتند ابراز خوشنودی میکردند. اما کسی باید به این سوال پاسخ می داد که :
این پروژه هم زمانی در وضعیت Green field بوده است، چه تضمینی وجود دارد که چند ماه بعد دوباره با همین شرایط روبرو نشویم؟
در نهایت تصمیم سرمایه گذاران و تیم توسعه بر آن شد که برای یافتن پاسخ قابل قبول به سوال فوق، دلایل افزایش هزینه تغییرات در نرم افزار تولید شده را مورد بررسی قرار دهند. ایشان با به کارگیری تجربیات و مشاهدات خود در تولید نرم افزار فعلی، نکات بررسی شده در جلسات گذشته نگری، بازخورد مشتریان و دانش مشاوران موفق شدند فهرستی از اشتباهات صورت گرفته در گذشته را فراهم کنند که به شرح زیر است:
- پروژه خیلی سریع شروع شد و ما فقط به تولید ویژگی هایی که در بک لاگ هر اسپرینت وجود داشت توجه داشتیم. ای کاش قبل از شروع فرصتی برای تعیین معماری کاندید نرم افزار و یا فکر کردن به بخش های حیاتی آن داشتیم.
- کیفیت کد پایین بود به طوری که در ابتدای پروژه هر کس فقط بخش هایی از نرم افزار را که خودش نوشته بود درک می کرد. البته بعد از مدتی حتی خود برنامه نویس هم نمی توانست نیت خود را از کد نوشته شده درک کند.
- گاهی به دلیل اولویت پایین و یا فشار کاری برخی از مسائل که معمولا منجر به بهینه کردن کیفیت نرم افزار می شد را به تعویق می انداخیتم اما چون برنامه مدونی برای انجام آن ها در آینده نداشتیم عملا به دست فراموشی سپرده می شدند.
- در بسیاری از مواقع نیاز به باز طراحی برخی از ماژول های نرم افزار احساس می شد، اما گاهی هزینه این باز طراحی بسیار زیاد بود و به بخش های زیادی از سیستم سرایت می کرد در نتیجه ترجیح بر راه حل سرپایی یا موقت بود.
- توسعه دهندگان نرم افزار نیاز به Refactor کردن اکثر مولفه های نرم افزار را به درستی درک می کردند اما نسبت به بروز خطای ناشی از این تغییرات واهمه داشتند و این ترس عملا امکان اعمال هر نوع بهبودی در کد را از ایشان می گرفت.
- برای اینکه بتوانیم یک نسخه قابل انتشار به مشتری بدهیم، روزها و گاهی هفته ها وقت نیاز بود. فرآیند کنترل کیفیت به شدت کند و پر از خطای انسانی بود همچنین آماده کردن بخش های مختلف سیستم از جمله تغییرات دیتابیس برای نصب بسیار پر مخاطره و دشوار بود.
- مستنداتی که در مدت انجام پروژه تولید شده بودند علی رغم زحمت زیادی که برای تولید آن ها کشیده شده بود، پس از اعمال تغییرات به روز نشده بودند و عملا قابلیت استفاده برای هیچ کس را نداشتند.
چرا باید هزینه تغییرات را کاهش دهیم؟
با نگاه دقیق به مشکلات ذکر شده در تجربه شکست مورد بحث، مشخص می شود که برخی از این مشکلات در بین تیم های چابک عمومیت دارد. یقینا تا زمانی که هزینه تغییرات را کاهش ندهیم موفقیتی حاصل نمی شود زیرا همانطور که در بیانیه چابک قید شده است، پاسخگویی به تغییرات یکی از مهم ترین ارزش های تیم های چابک است. در نتیجه اولین گام در کاهش هزینه تغییرات استقرار فرهنگ پذیرفتن تغییرات در تیم های چابک است؛ یعنی باور داشته باشیم که تغییرات رخ می دهند پس بهتر است آغوش خود را برای آن ها باز کنیم. طبق نظر Robert C. Martin ارزش ثانویه نرم افزار به آن است که نیازهای مشتری را برآورده کند و رفتار مورد انتظار وی را به درستی انجام دهد اما ارزش اصلی نرم افزار به آن است که در طول زمان تغییر کند زیرا نیازهای مشتری دائما در حال تغییر است و اگر نرم افزار نتواند خود را منطبق بر آن تغییر دهد قابل استفاده نخواهد بود.
چگونه هزینه تغییرات را کاهش دهیم؟
- قبل از این که مسیر توسعه نرم افزار را هموار نکردیم از شروع کار اجتناب کنیم
یکی از بزرگترین اشتباهات در انجام پروژه های بزرگ، این تفکر است که می توان با داشتن بک لاگ اولیه محصول کار را شروع کرد و در انتهای هر تکرار نرم افزار کارکننده تولید کرد. بسیاری از فریمورک های چابک به مفهومی مانند Kick-off, Take-off, Iteration #0
می پردازند. هدف این مرحله از انجام پروژه یک چیز است؛ هموار کردن مسیر توسعه نرم افزار در آینده. یکی از مهم ترین اقداماتی که در این مرحله باید انجام شود تعیین شکل کلی معماری نرم افزار و مشخص کردن اجزاء اصلی آن به شکل ساده و قابل ارزیابی است. در اینجا می توانید داستان یک Kick-off چابک موفق را بخوانید.
- همه چیز کد است، پس بهترین کد را بنویسیم
در دنیای نرم افزار طراحی چیزی نیست جز کدی که می نویسیم و ما دائما در حال باز طراحی نرم افزار هستیم در نتیجه توجه به شاخص های ارزیابی کیفیت کد همیت بالایی دارد. به کار گیری اصول Clean code، الگوها و اصول طراحی و همچنین پرهیز از پیچیدگی های غیر ضروری و آزار دهنده باعث می شود کد نوشته شده قابل خواندن، قابل درک، قابل توسعه و قابل تغییر باشد. داشتن حجم زیادی کد کثیف یعنی ترس همیشگی از تغییر دادن کدی مکانیزم آن را درک نمی کنیم.
- بهترین رویکرد Emergent design است
عدم قطعیت در ذات نرم افزار وجود دارد لذا همواره باید از افتادن به دام آینده نگری های غیر ضروری اجتناب کرد زیرا سرمایه گذاری روی عدم قطعیت بسیار مخاطره آمیز است. همانطور که سهل انگاری در طراحی و نقض اصول طراحی بدون هزینه نخواهد بود و در آینده مشکل ساز خواهد شد؛ طراحی های پیچیده و over engineering نیز هزینه تغییرات آتی را افزایش می دهد. با به کار گیری اصول Emergent design همانطور که از Big design up front پرهیز می کنیم از No design up front نیز اجتناب می کنیم.
- رویکرد Test-First داشته باشیم
تغییر دادن نرم افزاری که به کاربران خود سرویس می دهد مانند پریدن از هواپیمای در حال پرواز است. تست خودکار تنها چتر نجاتی است که می توانیم به همراه داشته باشیم. یکی از اهداف آرمانی تیم های چابک این است که در فرآیند Manual QA هیچ خطایی گزارش نشود. هر چند دستیابی به این هدف آرمانی است ولی حرکت به سمت این هدف منجر به کاهش هزینه تغییر نرم افزار می شود. هر چه تست های خودکار جامع تر باشند ترس از باز طراحی و Refactoring کد های کثیف کم تر می شود. رویکردهای Test-First مانند TDD, ATDD, BDD نه تنها منجر به تولید تست های جامع می شوند بلکه در رسیدن به اهداف Emergent design بیشترین کمک را می کنند.
- چرخه حیات نرم افزار بدون اشتباه انسانی
یکی از مهم ترین ارزش های تیم های چابک تعامل با مشتری است. تا وقتی خود را در معرض بازخورد مشتری قرار ندهیم نمی توانیم ارزیابی دقیقی از نرم افزار تولید شده داشته باشیم. برای دریافت بازخورد لازم است امکان انتشار پیوسته محصول را داشته باشیم. به منظور کاهش هزینه تغییرات و اطمینان از کیفیت نسخه قابل انتشار لازم است فرآیند های Continues integration, Continues delivery با کارایی بالا مستقر شده باشند.
- بدهی فنی را مدیریت کنیم
اساسا به تعویق انداختن برخی مسائل، مشکلات و برنامه ها رویکرد صحیحی است به شرطی که حاصل تصمیم کارشناسی شده و مبتنی بر استراتژی مدیریت بدهی فنی باشد. به منظور مدیریت بدهی فنی لازم است تا جایگاه آن را در نیاز فعلی و آتی خود پیدا کنیم آنگاه می توان نسبت به آن برنامه ریزی لازم برای مدیریت و پرداخت به موقع آن را انجام داد. برای اطلاعات بیشتر در خصوص مدیریت بدهی فنی می توانید اینجا را مطالعه کنید.
- به مستندات زنده اهمیت بیشتر دهیم
شاید این جمله را شنیده باشید که کد هیچگاه دروغ نمی گوید ولی کامنت ها اغلب دروغ می گویند. اشکال بزرگی که به مستندات تولید شده وارد می شود همین موضوع است. یعنی نرم افزار و اجزاء آن دائما در حال تغییر هستند ولی به روز کردن مستندات برای کسی اهمیتی ندارد. طبیعتا تدوین فرآیندی برای به روز رسانی مستندات در تیم ها می تواند کمی از احتمال بروز این مشکل کم کند اما مطلوب است که رویکرد تیم های چابک تولید مستندات زنده باشد. به طور مثال چه مستندی بهتر از Test case هایی که برای ارزیابی صحت عملکرد منطق کسب و کار نوشته می شود؟ در صورتی که اصول ساده تست نویسی را به کار برده باشیم می توانیم این Test case ها را به عنوان مستندات Acceptance test به مشتری نهایی که دانشی از دنیای نرم افزار ندارد ارائه کنیم و تاییدیه وی را کسب کنیم. همچنین یکی از مدرن ترین و زنده ترین مستندات نرم افزار، کد نوشته شده است.
به قول مارتین فاولر
Any fool can write code that a computer can understand.
Good programmers write code that humans can understand
اگر فکر میکنید تیم شما، یا خودتان نیاز به مرور موارد فنی چابک دارید، پیشنهاد میکنم کاتالوگ دورههای چابک را مشاهده کنید یا اینکه در یکی از دورههای فنی ما ثبت نام کنید.
با عرض سلام و خسته نباشید
من مدتی است در زمینه نرم افزار سی آر ام مایکروسافت فعالیت دارم و بنابراین احساس نیاز داشتم که اطلاعات خودم رو در زمینه های مرتبط افزایش بدم. در طی تحقیقات خودم، با سیستم agile آشنا شدم و متوجه شدم که حتی نرم افزار های crm ای هم در بازار وجود دارن که با توجه به چابک شکل گرفتند. می خواستم ببینم که شما در این زمینه ها اطلاعاتی دارید آیا؟ یک نرم افزاری مثل مایکروسافت سی آر ام که انقدر امکان شخصی سازی داره، می تونه بر اساس اصول چابک شکل بگیره؟
ممنون میشم اگر اطلاعاتی دارید، یکم موضوع رو باز کنید.
مسلما امکانش وجود دارد.
https://www.scrumalliance.org/community/articles/2016/december/agile-for-prepackaged-erp-and-crm-applications
واقعا اینکه برناممون همیشه به روز باشه و با دنیا جلو بیایم باعث حیات کار ما میشه
واقعا باید قسمت تست رو جدی گرفت و براش هزینه داد.
ممنون مقاله قابل تاملی بود… به امید پیشرفت روز به روز ایران