این مطلب برای خواندن سریع نوشته نشده؛ برای ساختن یک تصمیم روشن و قابل اجراست.
پیش از بازنویسی محصول دیجیتال این پنج سؤال را بپرسید
بازنویسی کامل محصول دیجیتال معمولاً با یک جمله شروع میشود: «این کد دیگر جواب نمیدهد؛ از اول بسازیم.» این جمله ممکن است درست باشد، اما بهتنهایی دلیل کافی برای تصمیمی پرهزینه نیست. بازنویسی، راهحل فنی برای یک مسئله محصولی، عملیاتی یا سازمانی نیست؛ فقط یکی از گزینههای تغییر است. پاسخ کوتاه این است: پیش از تصمیم بازنویسی محصول باید بدانید دقیقاً چه چیزی خراب است، کدام شاهد این ادعا را پشتیبانی میکند، چه بخشی واقعاً باید تغییر کند، در دوره گذار چه ریسکی میپذیرید و موفقیت را با چه علامتی خواهید سنجید. اگر این پنج سؤال بیپاسخ بمانند، احتمال دارد هزینه یک سیستم تازه را بدهید اما همان ابهام، داده بد و تصمیمهای کند را دوباره بسازید.
این راهنما برای بنیانگذار و تصمیمگیر پروژهای است که میان تعمیر تدریجی، بازطراحی محدود، مهاجرت مرحلهای و بازنویسی کامل مردد است. هدف، دفاع از هیچ گزینهای نیست؛ هدف ساختن یک تصمیم قابل توضیح است. اگر محصول شما قابلیتهای زیادی دارد اما نتیجه نمیدهد، ابتدا نشانهها را از علت جدا کنید و بعد سراغ انتخاب مسیر بروید. برای زاویهای نزدیک درباره رشد، مطلب علت رشد نکردن محصول را هم ببینید.
بازنویسی دقیقاً چه مسئلهای را حل میکند؟
بازنویسی یعنی پیادهسازی دوباره بخش مهمی از محصول با منطق، معماری یا فناوری متفاوت، درحالیکه انتظار دارید رفتار ارزشمند محصول حفظ یا بهتر شود. این تعریف با «مرتبکردن کد»، «ارتقای یک کتابخانه» یا «جداکردن یک سرویس» فرق دارد. در تعمیر، تلاش میکنید نقص مشخص را با کمترین تغییر برطرف کنید. در بازطراحی، جریان یا ساختار یک بخش را عوض میکنید. در مهاجرت، مسیر انتقال تدریجی از وضعیت فعلی به وضعیت مطلوب را میسازید. بازنویسی کامل زمانی معنا دارد که محدودیتهای سیستم فعلی مانع جدی و اثباتشدهای برای نتیجه موردنیاز باشند؛ نه زمانی که تیم از کار با آن خسته شده است.
سه نشانه بهتنهایی دلیل بازنویسی نیستند: قدیمیبودن فناوری، شکایت توسعهدهندهها از کد و وجود بدهی فنی. اینها سیگنالاند، نه تصمیم. فناوری قدیمی ممکن است پایدار و قابل نگهداری باشد. کد ناخوشایند ممکن است در یک مرز محدود قابل اصلاح باشد. بدهی فنی هم وقتی مهم میشود که به کیفیت، سرعت تصمیم، امنیت، درآمد یا توان یادگیری ضربه بزند. بنابراین سؤال اصلی «آیا کد زشت است؟» نیست؛ «کدام نتیجه حیاتی بهدلیل این محدودیت محقق نمیشود و شاهد آن چیست؟» است.
سؤال اول: مشکل را با نشانه و اثر قابل اندازهگیری تعریف کردهایم؟
پیش از تشکیل تیم بازنویسی، مشکل را در یک جمله بنویسید: «در مسیر X، برای کاربر یا عملیات Y، محدودیت Z باعث نتیجه W میشود.» جملهای مانند «معماری بد است» قابل آزمون نیست. جملهای مانند «افزودن یک جریان پرداخت جدید، بهدلیل وابستگیهای مشترک، هر بار نیازمند تغییر در چهار ماژول و دو هفته آزمون دستی است و نرخ خطای انتشار را بالا میبرد» نقطه شروع بهتری است.
برای هر ادعا سه چیز ثبت کنید: رخداد مشاهدهشده، اثر کسبوکار یا کاربر و دامنه مسئله. رخداد میتواند زمان تحویل، خطای تولید، کندی پاسخ، شکست داده یا ناتوانی در آزمایش باشد. اثر باید از جنس نتیجه باشد، نه صرفاً فعالیت؛ مثلاً از دسترفتن سفارش، تأخیر در فعالسازی یا افزایش تماس پشتیبانی. دامنه هم مشخص میکند مشکل در یک مسیر است یا در هستهای که چند مسیر را تحت تأثیر قرار میدهد.
اگر تعریف مسئله مبهم باشد، بازنویسی به پروژهای برای «حس بهتر» تبدیل میشود. در این حالت هر پیشرفت فنی را موفقیت مینامیم، حتی اگر کاربر همان مشکل قبلی را داشته باشد. یک تست ساده انجام دهید: آیا دو نفر مستقل میتوانند با خواندن تعریف شما تشخیص دهند چه چیزی باید بهتر شود و چه چیزی خارج از محدوده است؟ اگر نه، هنوز برای تعهد به بازنویسی زود است.
سؤال دوم: چه شاهدی میگوید علت، خودِ ساختار فعلی است؟
آخرین باگ یا سختترین بخش کد همیشه علت اصلی نیست. ممکن است مسئله از تعریف ناقص نیاز، داده ناسالم، قرارداد مبهم بین تیمها، پایش ضعیف یا تصمیمهای دیرهنگام ناشی شود. برای جداکردن علت از نشانه، حداقل چند شاهد مستقل جمع کنید: مسیرهای پرتکرار خطا، زمان و هزینه تغییر، رخدادهای تولید، کیفیت داده، وابستگیهای واقعی، نتایج تست و مصاحبه با کسانی که محصول را نگهداری یا استفاده میکنند. تجربه پروژه ارزشمند است، اما باید به مشاهده قابل بررسی وصل شود.
دو فرضیه رقیب بسازید. فرضیه اول میتواند این باشد که مرزهای معماری مانع تغییرند؛ فرضیه دوم شاید این باشد که مسئله از نبود تصمیم روشن یا تست پذیرش ناشی میشود. سپس ارزانترین بررسی را انتخاب کنید که این دو را از هم جدا میکند. یک تغییر کوچک در یک مرز، یک replay محدود، مقایسه payload، یا ساختن یک تست قرارداد گاهی اطلاعات بیشتری از یک برنامه ششماهه میدهد. اگر اصلاح محدود، اثر مورد انتظار را ایجاد کند، ادعای ضرورت بازنویسی ضعیفتر میشود.
در این مرحله مراقب «فهرست شکایتها» باشید. دهها مورد ناراحتکننده الزاماً یک علت مشترک ندارند. آنها را بر اساس مسیر کاربر، مالکیت، نوع داده و اثر دستهبندی کنید. برای باگهایی که پس از اصلاح برمیگردند، تشخیص ریشه را جداگانه انجام دهید؛ راهنمای ریشه باگهای تکرارشونده محصول برای همین تصمیم مفید است.
سؤال سوم: دقیقاً چه چیزی باید بماند و چه چیزی باید تغییر کند؟
عبارت «از صفر میسازیم» اگر قرارداد حفظشده نداشته باشد، دامنه را بینهایت میکند. ابتدا رفتارهایی را که باید حفظ شوند فهرست کنید: دادههای تاریخی، هویت کاربران، مجوزها، گزارشهای مالی، URLهای مهم، قابلیتهای حیاتی و تعهدات عملیاتی. سپس مواردی را که عمداً تغییر میکنند مشخص کنید. این تفکیک به تیم اجازه میدهد درباره مهاجرت، سازگاری و توقفهای مجاز تصمیم بگیرد.
محصول را به برشهای قابل تحویل تقسیم کنید، نه لایههای فنی. یک برش باید مسیر واقعی کاربر را از ورودی تا نتیجه پوشش دهد و بتواند در کنار سیستم فعلی سنجیده شود. اگر فقط دیتابیس یا backend تازه میسازید اما نتیجهای برای کاربر قابل مشاهده نیست، ماهها هزینه کردهاید بدون اینکه فرض اصلی را آزمایش کنید. الگوهایی مانند strangler، anti-corruption layer، feature flag و مهاجرت دوگانه ممکن است مسیر را کمریسکتر کنند، اما فقط وقتی مالکیت داده، rollback و معیار توقف از ابتدا روشن باشد.
یک ماتریس ساده بسازید: هر قابلیت در یک ستون، گزینه تعمیر، بازطراحی، مهاجرت و بازنویسی در ستونهای بعدی، و برای هر خانه هزینه، ریسک و شواهد. این ماتریس جلوی یک تصمیم احساسی برای کل محصول را میگیرد. گاهی نتیجه حرفهای این است که هسته پرداخت مهاجرت شود، پنل داخلی تعمیر شود و یک جریان کمارزش فعلاً دستنخورده بماند.
سؤال چهارم: دوره گذار را چگونه کنترل میکنیم؟
بیشتر برنامههای بازنویسی روی معماری مطلوب تمرکز میکنند و دوره گذار را کماهمیت میدانند؛ درحالیکه بیشترین ریسک همانجاست. سیستم قدیمی باید مدتی زنده بماند، تیم باید دو مسیر را بفهمد، داده باید همگام شود و پشتیبانی باید بداند هر رخداد متعلق به کدام نسخه است. اگر پاسخ این پرسشها روشن نیست، طرح هنوز آماده اجرا نیست: چه کسی مالک تصمیمهای روزانه است؟ چه زمانی مسیر تازه فعال میشود؟ rollback چگونه انجام میشود؟ اختلاف داده را چه کسی تشخیص میدهد؟ چه علامتی باعث توقف یا بازگشت میشود؟
برای هر برش یک نقشه ریسک و یک برنامه مشاهدهپذیری لازم است. لاگ ساختاریافته، trace، سنجه خطا، زمان پاسخ، نرخ تکمیل مسیر و مقایسه رفتار نسخهها باید پیش از انتقال کاربران آماده باشد، نه بعد از حادثه. انتشار تدریجی، گروه آزمایشی و قابلیت خاموشکردن مسیر تازه، ریسک را حذف نمیکنند اما آن را قابل کنترلتر میسازند. اگر هیچ راه بازگشت عملی ندارید، اسم کار «آزمایش» نیست؛ یک شرطبندی بزرگ است.
همچنین هزینه فرصت را حساب کنید. تیمی که تمام ظرفیتش را صرف بازنویسی میکند، درخواستهای مشتری، اصلاحهای امنیتی و یادگیری بازار را عقب میاندازد. این هزینه باید در تصمیم دیده شود، حتی اگر در بودجه فنی ظاهر نشود.
سؤال پنجم: از کجا بفهمیم تصمیم درست بوده است؟
معیار موفقیت نباید فقط «کد جدید deploy شد» یا «تعداد فایلهای قدیمی کم شد» باشد. برای هر هدف یک معیار نتیجه و یک معیار سلامت انتخاب کنید. اگر هدف افزایش توان تغییر است، زمان رسیدن یک تغییر مشخص به production و نرخ rollback را بسنجید. اگر هدف پایداری است، نرخ خطا، زمان تشخیص و زمان بازیابی را مقایسه کنید. اگر هدف تجربه کاربر است، تکمیل مسیر، فعالسازی یا تماس پشتیبانی را با خط پایه بسنجید.
خط پایه را پیش از تغییر ثبت کنید و برای اندازهگیری بازه زمانی، بخش کاربر و شرایط مقایسه را مشخص کنید. معیارها باید به تصمیم وصل باشند: اگر پس از دو برش، زمان تحویل بهتر نشد، آیا دامنه را عوض میکنیم، کار را متوقف میکنیم یا فرضیه را ردشده میدانیم؟ معیار توقف بهاندازه معیار ادامه مهم است.
یک سناریوی تصمیم برای تیم محصول
فرض کنید یک سامانه سفارش سازمانی هر تغییر را به آزمون دستی چندروزه تبدیل کرده است. مدیر فنی پیشنهاد بازنویسی کامل میدهد، چون ماژولهای قدیمی به هم وابستهاند. تیم محصول اما میبیند بیشترین شکایت در جریان اصلاح سفارش و همگامسازی وضعیت است. بررسی اولیه نشان میدهد بخشی از مشکل از قرارداد مبهم و دادههای ناقص میآید، نه همه معماری. تیم بهجای بازنویسی کامل، یک برش عمودی برای وضعیت سفارش میسازد، قرارداد داده را صریح میکند، پایش را اضافه میکند و مسیر را برای درصد کمی از کاربران فعال میکند.
پس از چند چرخه، زمان تشخیص خطا و تعداد اصلاحهای برگشتی کاهش مییابد، اما یک وابستگی مشترک هنوز مانع افزودن قابلیت خاصی است. حالا شواهد برای مهاجرت همان مرز قویتر شده است. تصمیم مرحلهای هم هزینه اولیه را کنترل کرده و هم معلوم کرده کدام بخش واقعاً ارزش تغییر دارد. این نتیجه نه ضدبازنویسی است و نه طرفدار آن؛ تصمیم را از شعار به آزمایش قابل سنجش تبدیل میکند.
چکلیست تصمیم و اقدام بعدی
پیش از تأیید بازنویسی، پاسخ این موارد را در یک صفحه ثبت کنید:
- مسئله، اثر و دامنه با مثال واقعی و معیار پایه تعریف شده است.
- حداقل دو فرضیه درباره علت بررسی و شواهد آنها ثبت شده است.
- قابلیتها و دادههایی که باید حفظ شوند از موارد قابل تغییر جدا شدهاند.
- کوچکترین برش قابل تحویل و روش مقایسه با سیستم فعلی مشخص است.
- مالکیت داده، rollback، مشاهدهپذیری و معیار توقف دوره گذار روشن است.
- معیار نتیجه، خط پایه، بازه اندازهگیری و تصمیم پس از مشاهده تعیین شده است.
اگر بیشتر پاسخها «نمیدانیم» هستند، اقدام بعدی سفارش بازنویسی نیست؛ یک مرحله تشخیص محدود و زماندار است. اگر شواهد نشان میدهند یک مرز مشخص هم هزینه تغییر را بالا برده و هم نتیجه موردنیاز را مسدود کرده است، مهاجرت مرحلهای یا بازنویسی همان مرز میتواند تصمیم حرفهای باشد. برای بررسی پروژه و انتخاب مسیر متناسب با مسئله، ارزیابی پروژه را شروع کنید.
بازنویسی زمانی ارزشمند است که یک محدودیت واقعی را با ریسک قابل کنترل برطرف کند. پیش از آن، پنج سؤال بالا کمک میکنند بین خستگی از وضعیت موجود و ضرورت تغییر تفاوت بگذارید؛ همین تفاوت، مرز یک تصمیم معماری سالم با یک وصله پرهزینه است.
مطالعه کافی نیست؛
قدم بعدی را انتخاب کنید.
یکی از مسیرهای مرتبط را ادامه دهید یا همین حالا موضوع را به یک اقدام واقعی تبدیل کنید.
ارزیابی پروژه
