حدود دو سال پیش، کدهای مربوط به بکاند (یعنی بخش مربوط به سمت سرور) آچاره رو از اول بازنویسی کردیم، یعنی تقریبا همه کدهایی که طی حدود ۲ سال و نیم برای پیادهسازی منطق و کارهای سمت سرور آچاره نوشته بودیم را (با کمی اغراق) ریختیم دور و از اول همان کاربری را به همراه یک سری ویژگیهای جدیدتر به صورت تمیزتر و با کاربری سریعتر و بهتر نوشتیم، کاری که برای محصولی که همزمان در حال سرویسدهی به کاربران است بسیار سخت است چرا که همزمان باید هم سرویس را بالا نگه داشت، هم در کدهای جدید به اینکه توجه داشت که کاربرانی که از اپلیکیشنهای با ورژن قدیمیتر استفاده میکنند به مشکل برنخورند (backward compatibility)و هم اینکه مطمئن شد که دوره گذار از کد و بانک داده قبلی به سیستم (نظام) جدید بدون دردسر و مشکل در سریعترین زمان ممکن طی میشود. این پروسه حدود شش ماه بسیار طاقت فرسا طول کشید، حدود دو برابر تخمین اولیه و در سه ماه آخر با میانگین روزی ۱۶ ۱۷ ساعت کار.
اما اصلا چرا تصمیم به انجام این کار گرفتیم؟ در طول فرآیند توسعه نرمافزار، خیلی عجیب نیست که طی گذر زمان ساختار کد نیاز به تغییر، اصلاح و تمیزکاری داشته باشد. این امر وقتی توسعه نرمافزار در یک استارتاپ رخ میدهد احتمالا شدیدتر هم هست، چرا که ابتدا که کار شروع میشود خیلی از مسائل مربوط به ویژگیهای مورد نیاز محصول، نحوه رشد، تمرکز و … چندان مشخص نیست و کار با «فرضیات» شروع میشود. وظیفه اصلی نرمافزار در این مقطع شاید فراهم آوردن بستری برای تست این فرضیات باشد و به مرور زمان برخی از فرضیات رد، برخی تایید و برخی تعدیل میشوند. به تبع آن نیاز است که کدهای مربوطه حذف یا اصلاح شوند.
اما خیلی اوقات این اتفاق به دلایل مختلف رخ نمیدهد (و به اصطلاح بدهی فنی ایجاد میشود). این اتفاق دلایل مختلفی میتواند داشته باشد که شاید سادهترینش این است که صف ویژگیهای مورد نیاز که میبایست به کد اضافه شود اینقدر زیاد است که افراد تصمیمگیر بین دوراهی اینکه زمان روی اصلاح سیستم صرف کنند و یا اینکه از مزایای ویژگیهای جدید بهره ببرند، گزینه دوم را انتخاب میکنند (طبعا گزینه اول احتمالا سلامت کد را در درازمدت تامین میکند، ولی گاهی اوقات و به خصوص در یک استارتاپ نوپا، بدون انتخاب گزینه دوم و تمرکز بر کوتاه مدت، آینده دراز مدتی نخواهد بود که سلامت کد در آن مهم باشد یا نباشد). اما علت هر چه باشد، پس از مدتی نظام کد اینقدر پیچیده و در هم تنیده میشود که اصلاحش هم بیشتر و بیشتر زمان و هزینه خواهد برد و در برخی موارد عملا تقریبا ناممکن خواهد شد.
درست به همین دلیل ما نیز تصمیم به بازنویسی کد آچاره گرفتیم، هم به این دلیل که احساس میکردیم با سیستم فعلی مقیاسپذیری درازمدت خیلی سخت خواهد بود، هم اینکه تخمین میزدیم که سیستم جدید به نسبت زود آماده خواهد شد. فرضیاتی که در عمل چندان صحیح نبودند و در گذر زمان آن را فهمیدیم. اما در نهایت خروجیاش که سیستم سریعتر، خواناتر و کارآمدتر بود.
با گذشت نزدیک به دو سال، هر از گاهی از خودم میپرسم که آیا این بازنویسی تصمیم درستی بود؟ (شاید چون هنوز دردش تازه است)! یا اینکه مثلا آیا استراتژی بهتری وجود نداشت؟
اما اخیرا به این فکر میکنم که این سوال در درجه دوم اهمیت قرار میگیرد. چرا که ساختار کد را در سطح خرد توسعهدهندگان نرمافزار، و در سطح کلان استراتژیها و تصمیمات مجموعه (شرکت/استارتاپ/…) میسازند. با بازنویسی کلی، برای مدتی یک کد نظاممند خیلی خوب خواهیم داشت. ولی مادامی که نگرش افراد درگیر و نوع تصمیمها در هنگام مواجهه با دوراهیها تغییر نکند، پس از مدتی دوباره با همان وضعیت سابق روبرو خواهیم بود: یک سیستم کند، پیچیده و مقاوم در برابر تغییر، که در نهایت دوباره باید با صرف کلی وقت و انرژی بازنویسی شود.
این دفعه که داشتم به این موضوع فکر میکردم، به نظرم رسید این دوگانه خیلی شبیه مقایسه انقلاب و اصلاح در نظامهای سیاسی است: انقلاب ساختار را دگرگون میکند و تلاش میکند نظمی «نو» در اندازد و اصلاح دل به تغییر تدریجی ساختار موجود میدهد. اینکه کدام روش در چه شرایطی مناسبتر و مطلوبتر است بحث جداگانهای است که شاید تمامی هم نداشته باشد. ولی نکتهای که از این مقایسه برایم جالب به نظر رسید این است که حتی در صورت انقلاب و ریست کردن یک سیستم، اگر روشها و نحوه تصمیمگیریهایی که بر سر دوراهیهای و بزنگاههای حساس انجام میشود تغییر نکند، پس از مدتی دوباره با همان وضع سابق روبرو خواهیم شد. البته که افراد تصمیمگیر احتمالا تغییر کردهاند و ظاهر دوراهیهای حساس هم شاید عوض شده باشد، ولی در نهایت اگر جنس روشها همان باشد، مثلا ترجیح همیشگی کوتاه مدت به دراز مدت، «خودی» به غیر خودی، تمرکز انجام دادن صرف کار به جای تلاش برای ایجاد ساختار پایدار و … سرنوشت آن نظم و نظام جدید احتمالا همان سیستم قدیمی خواهد بود، با ظاهری متفاوت.
پس شاید مهمتر از تمرکز بر خود ساختار، تمرکز بر روشها، ایدهآلها و چگونگی بهبود آنها باشد.
پینوشت: در رابط با این سوال که آیا بازنویسی کد را پیشنهاد میکنم یا نه، جوابم معمولا این است که به عنوان آخرین آخرین راه حل ممکن! چون معمولا بسیار بیش از تخمین اولیه وقت، انرژی و هزینه میبرد و معمولا راههای جایگزین بهتری هستند که اگر آدمی به انرژی مصرفی واقف میشد،حتما با دقت بیشتر میگشت تا پیدایشان کند (این یافته خیلی مختص تجربه ما در آچاره نیست و در خیلی از شرکتهای نرمافزاری تجربههای مشابهی وجود دارد).
به طور مشخص اگر به عقب برگردم احتمالا سراغ گزینه بازنویسی نمیرفتم، و یا حداقل با رویکرد متفاوتی در این راه قدم میگذاشتم که توزیع فشار روی اعضای تیم یکنواختتر باشد. چون بعد از گذشت دو سال فکر میکنم شاید میشد مثلا با ۵۰ درصد هزینه/وقت/انرژی صرف شده برای بازنویسی، به ۸۰ درصد دستاوردهای مثبت آن رسید.
اولین نفری باشید که نظر می دهد.