بدهی فنی

مطلبی که می‌خوانید ترجمه‌ی قسمت ۲۲۴ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.

در این اپیزود که در آوریل ۲۰۱۵ منتشر شده است، سوِن یوهان و ابرهارد ولف در مورد بدهی فنی (Technical Debt) صحبت می‌کنند. آن‌ها در نوشتن مقاله‌ای در مورد بدهی فنی با هم همکاری کرده‌اند. این قسمت به شکل مصاحبه نیست بلکه سوِن و ابرهارد با هم بحث را پیش می‌برند.


سوِن، چند کلمه در مورد خودت به ما بگو.

اسم من سوِن یوهان است و به عنوان توسعه‌دهنده‌ی نرم‌افزار در Trifork در آمستردام کار می‌کنم. همچنین دست‌اندرکار کنفرانس‌های GOTO هستم و خوشحالم که میزبان ریزسرویس‌ها در جلسه‌ی آمستردام هستم.

بله، خیلی جالب به نظر می‌رسد. من ابرهارد ولف هستم. من مستقل کار می‌کنم (Freelance). همچنین رئیس هیأت مشاوره‌ی فناوری در Adesso AG هستم. من در کنفرانس‌ها (اکثراً در آلمان) سخنران هستم و اخیراً کتابی در مورد تحویل مستمر نوشتم. همچنین دست‌اندرکار کنفرانس‌های GOTO و چند کنفرانس دیگر هستم.

اجازه بدهید به موضوع بپردازیم. بدهی فنی به وضوح با کیفیت نرم‌افزار ارتباط دارد. بنابراین قبل از این‌که وارد عمق بحث بدهی فنی بشویم باید در مورد کیفیت صحبت کنیم. انواع مختلفی از کیفیت وجود دارد. یک نوع از آن کیفیت خارجی است. این کیفیتی است که می‌تواند توسط کاربر یا مشتری مشاهده شود. ممکن است کارایی، امنیت، مقیاس‌پذیری، پایداری و ... باشد. [این نوع کیفیت] می‌تواند توسط کاربر اندازه‌گیری و مورد آزمایش قرار بگیرد؛ چون ویژگی‌ای از محصول است. چیزی است که باید توسط مالک محصول یا افرادِ حوزه‌ی کسب و کار مدیریت شود. چون آن‌ها هستند که به کیفیت و چگونگی دریافت آن توسط مشتری علاقه‌مند هستند. مثل خریدن یک خودرو است که ویژگی‌هایی دارد؛ [کیفیت] صرفاً یکی از ویژگی‌های محصول است.

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

سوِن می‌خواهی در این مورد صحبت کنی؟

بله. اساساً می‌توان گفت بدهی فنی تشبیهی برای توصیف کد نامطلوب است. [اصطلاح] بدهی اشاره‌ای به بدهی مالی دارد و از آن استفاده می‌کنیم تا [مفهوم] این کیفیت داخلی و ریسک کد را به افراد غیرفنی منتقل کنیم. توسعه‌دهندگان همواره در مورد کدهای باکیفیت و خوب صحبت می‌کنند اما افراد غیرفنی عموماً فایده‌ی آن را درک نمی‌کنند. به نظر آن‌ها «نرم‌افزار خوب کار می‌کند، چرا باید در کیفیت سرمایه‌گذاری کنم؟!». تشبیه بدهی فنی به ما کمک می‌کند که توضیح دهیم اگر بخواهیم بر اساس کد نامطلوب چیزی بسازیم، این باعث می‌شود توسعه‌های بعدی گران تمام شوند؛ زمان بیشتری صرف پیاده‌سازی یک ویژگی به کدی که خیلی خوب نیست، می‌شود. همچنین دیر یا زود این کیفیت داخلی تبدیل به کیفیت خارجی می‌شود؛ این هم مسئله‌ی است که باید بفهمانیم. مثلاً اگر کد بدی داشته باشیم، باگ‌های بیشتر و بیشتری خواهیم داشت و کند می‌شویم و این مشکل به تدریج به ذی‌نفعان و پروژه هم منتقل می‌شود. بنابراین بدهی فنی در حقیقت مشکل توسعه‌دهنده نیست، یک مشکل در سطح شرکت است. اگر بدهی فنی زیادی داشته باشید، در شرایط بحرانی تمام تیم مهندسی متوقف می‌شود. فکر می‌کنم خیلی از شرکت‌ها این را تجربه کرده باشند؛ فرضاً سامانه‌های [نوشته‌شده] با COBOL که امکان تغییر چیزی را در آن نداشتند.

بنابراین می‌شود ادعا کرد که بدهی فنی یکی از موارد کلیدی در موفقیت تجاری نرم‌افزارهای توسعه‌داده‌شده است. این اصطلاح توسط وارد کانیگهام در سال ۱۹۹۲ ابداع شد. او چنین چیزی گفت: «انتشار اولین کد مثل بدهکار شدن است. کمی بدهی، سرعت توسعه را بهبود می‌بخشد؛ به شرطی که در اولین فرصت با بازنویسی کد، تسویه شود... خطر زمانی رخ می‌دهد که تسویه نشود. هر دقیقه که صرف کد نامطلوب شود به عنوان بهره تلقی می‌شود. تمامی یک سازمان مهندسی می‌تواند تحت بار بدهی این کد نامستحکم، به حالت توقف کشانده شود، [خواه این اشکال] از نوع شئ‌گرایی باشد یا نباشد.» (متن کانینگهام را می‌توانید از این لینک ببینید -مترجم)‌ این به وضوح می‌گوید که تشبیه بدهی فنی ارتباط نزدیکی با بدهی مالی دارد و مربوط به انتشار سریع یک چیز و در نتیجه بدهکار شدن است. بعداً باید این بدهی را با بهبود کیفیت، تسویه کنید و اگر این کار را نکنید مجبور به پرداخت نرخ بهره هستید چون بهره‌وری شما کاهش پیدا می‌کند و توسعه‌تان کند می‌شود. و همان‌طور که سوِن الان گفت این تشبیه مناسبی برای صحبت با مدیریت است چون آن‌ها با اصطلاحات مالی آشنا هستند. با استفاده از این اصطلاحات راحت‌تر است که به آن‌ها بگوییم این مثل رفتن به بانک است. برای مدتی سود دارد اما در نهایت باید آن را بازپس دهید؛ اصل و بهره‌ی آن را. این‌طور بود که این اصلاح ابداع شد. اما تعریف دیگری هم وجود دارد. درست است سوِن؟

دقیقاً، دقیقاً. انجمن محققین ترجیح می‌دهند از تعریف مک‌کانل استفاده کنند. او می‌گوید: بدهی فنی‌ای که رویکردی در طراحی یا ساخت باشد در کوتاه‌مدت عملی است. اما یک زمینه‌ی فنی ایجاد می‌کند که در آینده انجام کار در آن به نسبت الان زمان بیشتری خواهد گرفت، این شامل افزایش هزینه در گذر زمان هم هست. فکر می‌کنم این تعریفی است که اکثر ما از بدهی فنی می‌دانیم. کاری را سریع و کثیف انجام می‌دهیم و چیزی در کوتاه‌مدت به دست می‌آوریم اما می‌دانیم که در درازمدت گریبان‌گیرمان خواهد شد.

این بیش از حد معمول است. فکر می‌کنم بعد از توضیح تشبیه، مهم‌ترین بخش این است که چطور با بدهی فنی برخورد کنیم؟ همان‌طور که گفتم، [بدهی فنی] یکی از کلیدهای کسب و کار موفق در توسعه‌ی نرم‌افزار است. بنابراین سؤال این است که چطور با آن برخورد می‌کنید؟ احتمالاً اولین سؤال این است که آیا اصلاً چیز بدی است؟

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

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

همچنین مدتی پیش گفتگویی با وارد کانینگهام درباره‌ی بدهی فنی داشتیم و او گفت: خب، در واقع بدهی فنی یک راهبرد است. چرا یک راهبرد است؟ چون می‌توانیم با بدهکار شدن به سرعت به هدف کسب و کار برسیم. چون ممکن است به بازار فرستادن چیزی خیلی مهم‌تر از مثلاً داشتن کد بی‌نقص و دیر رسیدن باشد. اما می‌توانیم چیزی را در بازار بفرستیم و اگر اولین بار باشد ببینیم که اصلاً به درد می‌خورد یا نه. فکر می‌کنم جالب است که مثلاً اریک ریس نویسنده‌ی کتاب The Lean Startup در کتابش توضیح می‌دهد که وقتی در استارتاپ کار می‌کرد همیشه خوشحال بود که کد بی‌نقصی نوشته است اما در نهایت هیچ‌کس از آن استفاده نمی‌کرد. بنابراین عملکردی که با کد بی‌نقصش ساخته بود کاملاً بدون استفاده بود. پس بهتر است چیزی را سریع بنویسید و به کاربر برسانید و ببینید که آیا برای کسی مفید است؟ اگر برای کسی مفید است آن وقت است که بدهی فنی را پرداخت می‌کنیم. اگر کد بی‌نقصی برای عملکردی که نمی‌دانیم مفید است یا نه بنویسیم هدر دادن زمان است. هنریک نیبرگ از Spotify حدود یک سال پیش در بلاگش چیزی نوشت: اگر عملکرد کد بی‌نقص «واقعاً» مفید نباشد، ما آن را زباله در نظر می‌گیریم. کاری که آن‌ها می‌کنند این است که یک عملکرد را خیلی سریع راه‌اندازی می‌کنند در حالی که ظاهر خوبی ندارد و آن را به مشتری می‌رسانند. اگر کاربر آن را دوست داشت و خواست از آن استفاده کند آن را Refactor می‌کنند و بهبود می‌دهند. این راهبردها را مدام و مدام می‌بینیم. فکر می‌کنم یک نمونه‌ی مشهور آمازون و تویتر باشد. فکر می‌کنم در تویتر این حس وجود دارد که انگار همیشه دارند سامانه‌شان را بازنویسی می‌کنند :-) چون فکر می‌کنم در ابتدا یک برنامه Ruby on Rails بود و الان یک سامانه‌ی اشتراک پیام است. آمازون هم در ابتدا سامانه‌ی کاملاً متفاوتی به نسبت آن‌چه که الان هست، بود. بله، فکر می‌کنم یک راهبرد باشد.

و ضمناً این چیزی است که وقتی من با معماران نرم‌افزار صحبت می‌کنم، تذکر می‌دهم. به آن‌ها تمرین‌هایی می‌دهم، اغلب آن‌ها راه‌حل‌هایی ارائه می‌دهند که مقیاس‌پذیری را در نظر می‌گیرد و فکر می‌کنند که مقیاس‌پذیری نگرانی اصلی‌شان است در حالی که در واقع باید روی زمان رسیدن به بازار تمرکز بیشتری داشته باشند. در غیر این‌صورت به نقطه‌ای که به مقیاس‌پذیری نیاز داشته باشند، نخواهند رسید. چون احتمالاً قبل از آن شرکت ورشکست می‌شود فرصت کسب و کار از دست خواهد رفت. بنابراین همان‌طور که می‌بینید همیشه بد نیست. با این حال باید به نحوی با بدهی فنی روبرو شوید. یکی از ایده‌های بزرگی که من به آن برخوردم ایده‌ی اریک ایوانز بود که به خاطر کتاب Domain Driven Design مشهور است. بخشی از کتاب هست که تقریباً همه آن را می‌دانند؛ درباره زبان و مخازن کد و … . بخش دیگری هم در کتاب هست که به نظر نمی‌رسد خیلی‌ها آن را خوانده باشند. درباره‌ی طراحی راهبردی و طراحی زمخت‌تر است. اساساً او می‌گوید اولاً نمی‌توانید یک سطح از کیفیت در تمام بخش‌های سامانه داشته باشید. اگر به آن فکر کنید در واقع کاملاً واضح است. چون توسعه‌دهندگان خوب و بد در تیم‌تان دارید. حتی اگر تیم خیلی خوبی داشته باشید باز هم توسعه‌دهندگان بهتر و بدتری خواهید داشت. بنابراین چون افراد متفاوتی در تیم دارید نمی‌توانید کیفیت یکسانی در تمام سامانه داشته باشید. چه کار می‌شود کرد؟ می‌توانید این‌که کدام بخش‌ها کیفیت بهتری داشته باشند را به شانس بسپارید یا این‌که درباره‌ی آن تصمیم آگاهانه‌ای بگیرید. یک راه برای روبرو شدن با بدهی فنی این است که بپرسید چه بخش‌هایی از سامانه واقعاً در تغییرپذیری اهمیت دارند؟ این اطلاعات را می‌شود در داده‌های تاریخی پیدا کرد، مثلاً این‌که تغییرات اخیر در کدام قسمت‌ها بوده است. یا می‌توانید از منظر کسب و کار به آن بنگرید،‌ در کدام بخش‌ها اگر تغییرات سریع‌تری داشته باشیم به ما مزیت رقابتی می‌دهد؟ مثلاً نحوه‌ی ترابری مهم است و در این مورد بخشی از سامانه که کار ترابری را انجام می‌دهد باید دارای کیفیت داخلی بالایی باشد. اریک ایوانز در کتابش تعداد کمی الگو دارد که در این رابطه صحبت می‌کنند. او می‌گوید می‌توانید یک زمینه‌ی کران‌دار (Bounded Context) داشته باشید که در آن یک مدل حوزه‌ی خاص معتبر است. می‌توانید میان زمینه‌های کران‌دار یک لایه ضد فساد داشته باشید. اگر همان سامانه‌ی ترابری را در نظر بگیریم و فرض کنیم یک مدل حوزه‌ی خوب در آن دارید که خیلی پیشرفته است و کد آن کیفیت بالایی دارد و بخش دیگری هم در سامانه هست که مثلاً با مشتریان سر و کار دارد و نرم‌افزاری عادی است که کیفیت پایینی دارد و مدل حوزه‌ی خیلی زشتی دارد. برای این‌که مطمئن شوید که این مدل حوزه‌ی زشت به سامانه‌ی ارزشمند ترابری شما نشت نمی‌کند، بهتر است یک لایه‌ی ضد فساد داشته باشید که این دو مدل را از هم جدا می‌کند و تفسیر بین آن‌ها را انجام می‌دهد. او در این مورد سلول‌ها را مثال می‌زند؛ مثل موجودات که از سلول‌ها ساخته شده‌اند، سامانه‌ی شما هم از تعدادی زمینه‌ی کران‌دار متفاوت تشکیل شده است. هر سلول غشائی دارد که مثل لایه‌ی ضد فساد است. [این غشاء] اطمینان حاصل می‌کند مشکلات خارجی به سلول (زمینه‌ی کران‌دار) نشت نمی‌کنند و آن‌ها به وضوح از هم جدا هستند. می‌توانید سلول‌ها (زمینه‌های کران‌دار) را با کیفیت بالایی داشته باشید و اگر مشکل کیفیت داشته باشید، در کد پخش نخواهد شد. این راه مناسبی برای توسعه‌ی راهبردی کیفیت در بدهی فنی است. تصمیم می‌گیرید کدام بخش‌ها مهم هستند، از آن‌ها مراقبت می‌کنید و بهترین توسعه‌دهندگان‌تان روی آن کار می‌کنند. کیفیت آن را از نزدیک پایش می‌کنید و ... بخش‌های دیگری هم هستند که ممکن است برای آن‌ها حتی از نرم‌افزارهای متداول، نرم‌افزارهایی که خریده‌اید یا از سامانه‌های میراثی خود (Legacy Systems) یا هر چیز دیگر استفاده کنید. فکر می‌کنم این راه جالبی برای توسعه‌ی راهبردی کیفیت یک سامانه‌ی نسبتاً پیچیده باشد.

البته یک سؤال این است که اصلاً چرا بدهی فنی داریم؟ آیا نمی‌شود از همان ابتدا یک نرم‌افزار بی‌نقص داشته باشیم؟ فکر می‌کنم تقریباً هر توسعه‌دهنده‌ای بخواهد کار عالی ارائه دهد. فکر نکنم نگرش کسی این باشد که کار کم کیفیت ارائه دهد. منظورم این است که همه‌ی ما می‌خواهیم کارهای خوب انجام دهیم. [پس] چرا کار کم کیفیت ارائه می‌دهیم در حالی که می‌خواهیم کار با کیفیت ارائه دهیم؟ چند دلیل برای آن وجود دارد. واضح‌ترین دلیل برای اکثر ما توسعه‌دهندگان فشار زمانی است. ما می‌خواهیم که کار خیلی خوبی انجام دهیم، اما زمان نداریم. باید انتشار دهیم و ضرب‌العجل داریم. بنابراین برای این که سریع‌تر باشیم کیفیت را قربانی می‌کنیم. تست کردن را از قلم می‌اندازیم، یا فقط تست‌های خودکار را. به طراحی خوب به طرز عمیقی فکر نمی‌کنیم. در اکثر مواقع این منجر به کیفیت نامطلوب می‌شود. نکته‌ی دیگر این است که ما داریم آگاهی از نحوه‌ی انجام کار را از دست می‌دهیم. اگر از یک فناوری جدید برای نخستین بار استفاده می‌کنیم و از آن درک کمی داریم، به ناچار از آن به طرز اشتباهی استفاده خواهیم کرد حتی اگر نیت‌مان خیر باشد. همچنین اگر حوزه‌ی کسب و کار را خیلی خوب نشناسیم منجر به طراحی‌های عجیب می‌شود. چیزی هم مثل پوسیدگی نرم‌افزار وجود دارد. اگر یک نرم‌افزار عالی داشته باشیم مثلاً EJB 2.0 که شاید ۱۵ سال پیش خوب بود. اما الان کمی تاریخ مصرف گذشته است.

فکر می‌کنم یک مطالعه‌ی برآوردی جالب در دانشگاه Turku بود که از افراد در فنلاند پرسیدند بدهی فنی شما از کجا سرچشمه می‌گیرد؟ خیلی جالب بود. چون نگفتند فشار زمانی. همچنین نگفتند که فناوری را نمی‌شناختیم. آن‌ها گفتند نیازمندی‌ها را درک نکردیم‌یا اساساً فهم درستی از حوزه‌ی کسب و کار نداشتیم بنابراین بدهی فنی از نیازمندی‌های درک نشده نشأت می‌گیرند. البته آن‌ها این‌ را هم گفتند که معماری بدی داشتیم، یا معماری [به خوبی] انتقال داده نشده بود. این‌ها دلایل اصلی بدهی فنی برای آن‌ها بود.

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

بله. نمی‌دانم. اخیراً از فیلیپه کوچتن مبدع RUP شنیدم که درباره‌ی آن صحبت می‌کرد. او برای بسیاری کارهای معماری شناخته شده است. او گفت حتی اگر تعداد زیادی موارد تست (Test Case) داشته اما معماری بدی داشته باشید، نمی‌توانید فرض کنید که می‌توانید کیفیت بهتر را با پیرایش کردن (Refactor) در سامانه وارد کنید. چون اگر معماری اشتباه باشد، مثلاً سبک اشتباهی را انتخاب کرده باشید، پیرایش کردن به شما کمکی نمی‌کند. واقعاً باید سامانه را از نو بنا کنید. در واقع من نمی‌دانم، سؤال خوبی است: کدام بدتر است؟ معماری بد با موارد تست یا معماری بهتر بدون موارد تست؟

این یکی از چیزهایی است که می‌توانید در مورد آن به تفصیل بحث کنید. در ارتباط با منشأ بدهی فنی، مدل دیگری هم هست که مارتین فاولر آن را معرفی کرده است. واضح است که او برای چیزهای زیادی در صنعت ما شناخته شده است. او بدهی فنی را در چهار ربع‌دایره تقسیم کرد. این ربع‌دایره‌ها بر اساس این‌که بدهی فنی، به طرزی غیرمسئولانه یا معقول تحمیل شده است، از هم جدا می‌شوند. اساساً سؤال این است که به اندازه‌ی کافی زمان برای فکر کردن به بدهی فنی وجود داشت؟ آیا صرفاً [تصمیمی] غیرمسئولانه بود و افراد تحت فشار زیادی بودند یا این‌که معقولانه بود؟ حتی در مواردی که زمان زیادی داشته باشید هم -همان‌طور که کمی بعد خواهیم دید- می‌توانید بدهی فنی داشته باشید. و [سؤال دیگر این‌که] آیا عمدی بود یا غیرعمدی؟ این‌که آیا تصمیمی آگاهانه بود که افراد گفتند ما بدهی فنی را می‌پذیریم و کار را انجام می‌دهیم یا این‌که به نحوی [خود به خود] اتفاق افتاد؟ ما زمان برای طراحی نداریم بنابراین به هر نحوی شده آن را انجام می‌دهیم. سرانجام سامانه‌ای به جای می‌ماند که بد طراحی شده است. اما شما می‌دانستید با این شرایط مواجه خواهید شد؛ بنابراین، این تصمیمی آگاهانه بود. اما اگر این تصمیم گرفته شد چون زمان کافی وجود نداشت، غیرمسئولانه‌ی عامدانه است. در مقابل، [تصمیم] معقول عامدانه یعنی این‌که الان باید انتشار دهیم و با پیامدهای آن مواجه شویم. بنابراین هر چند زمان کافی وجود داشت، باز هم این کار را کردیم و تصمیمی عامدانه بود، می‌دانستیم به لحاظ فنی بدهکار خواهیم شد و این کار را انجام دادیم. بدهی غیرمسئولانه‌ی غیرعمدی [چیزی مثل این است:] لایه بندی یعنی چه؟! واضح است که [این نوع بدهی فنی] چیزی است که در آن شما وقت کافی برای فکر کردن به تصمیم و عواقب آن صرف نمی‌کنید. تصمیم‌تان آگاهانه نبود چون حتی نمی‌دانستید که این یک مشکل است، شما اصلاً لایه بندی را نمی‌شناختید و در نتیجه یک سامانه‌ی بدون لایه‌بندی و شلوغ دارید. چون در واقع خیلی به آن فکر نکردید. بدهی عاقلانه‌ی غیرعامدانه این است که سامانه‌ای دارید و در بازنگری متوجه می‌شوید باید آن را به شکل دیگری می‌ساختید. معماری‌ای که استفاده کردید در زمانی خود مناسب بود اما بعداً در حین پیاده‌سازی به طراحی کاملاً متفاوتی درباره‌ی سامانه رسیدید که بهتر بود. در بازنگری روشن می‌شود که بدهی فنی زیادی دارید و مسئله این است که این فکر قبلاً به ذهن شما نرسیده بود. بنابراین زمان کافی داشتید و تصمیم عاقلانه بود اما در عین حال غیرعمدی هم بود چون نحوه‌ی عملکرد و واقعیت‌های معماری در آن زمان واضح نبود.

چیزی که فکر می‌کنم در این مورد خیلی جالب است این است که در ابتدای بحث در مورد تعریف بدهی فنی صحبت می‌کردیم؛ در این مورد که بدهی فنی را متحمل می‌شویم تا سریع‌تر انتشار دهیم. بنابراین این تصمیمی آگاهانه است. بنابراین تعریف اصلی بدهی فنی می‌گوید که تصمیمی آگاهانه است. بدهکار می‌شویم و در عوض برای مدتی سریع‌تر انتشار می‌دهیم و بعداً بدهی را تسویه می‌کنیم. چیزی که فکر می‌کنم در مورد مدل ربع‌دایره‌های مارتین فاولر جالب است -اگر کمی در آن دقیق‌تر شوید- این است که او می‌گوید این همیشه درست نیست. برخی مواقع برای شما واضح است که باید کار را به نحو دیگری انجام می‌دادید، چون در بازنگری وقتی به مسئله و نحوه‌ی حل مسئله‌تان، و نتیجه‌ی کار بنگرید، همه چیز واضح است. همچنین من برداشتی متفاوتی از بدهی فنی پیدا می‌کنم چون او می‌گوید غیرمسئولانه است. او نمی‌گوید که زمان کافی نداریم، مسئله صرفاً این است که شما برای پیشبرد کار به حدی تحت فشارید که بدهی فنی انباشت می‌شود. این تصمیمی آگاهانه نیست، این صرفاً اتفاقی است که می‌افتد، چون زمان زیادی تحت فشار هستید. فکر می‌کنم بخش جالب قابل برداشت در اینجا این است که منشأهای متفاوتی برای بدهی فنی وجود دارد و مدل ساده‌ای که می‌گفت ما کیفیت را فدای سرعت می‌کنیم در واقع چیزی نیست که همیشه اتفاق می‌افتد. فکر می‌کنم مسئله‌ای که سوِن مطرح کرد نکته‌ی مهمی است. اگر کار را با سامانه‌ای شروع کنید و از فناوری‌ای نظیر EJB 2.0 استفاده کنید در حالی که نسخه‌ی جدیدتری از EJB وجود دارد یا کتابخانه‌ی دیگری وجود دارد که مورد علاقه‌ی شما است، قطعاً به لحاظ فنی خود را بدهکار کرده‌اید. چون راه‌های راحت‌تری برای انجام کارها وجود دارد و راهی که شما انتخاب کرده‌اید بدهی فنی محسوب می‌شود. [در گذشته] هیچ راهی برای جلوگیری از این بدهی فنی وجود نداشت چون فناوری، جدید و در حال پیشرفت است. بنابراین به نظر این نشانه‌ای است که این تشبیه شکست می‌خورد. البته سؤال بعدی این است داشتن یک سامانه‌ی بدون بدهی واقع‌بینانه است؟ فکر کنم شما بخواهید در این مورد صحبت کنید. درست است سوِن؟

دقیقاً. آیا امکان دارد که سامانه‌ای بدون بدهی فنی داشته باشیم؟ منظورم این است که خیلی اوقات به چیزهایی از قبیل «بدهی فنی بس است»، «چطور بدهکار نباشیم، در ۱۰ مرحله»، «چه کنیم تا بدهکار نباشیم؟» و ... بر می‌خورم. فکر می‌کنم دستیابی به سامانه‌ای بدون بدهی غیر ممکن است. فکر می‌کنم باید بپذیریم که بدهی فنی همواره وجود خواهد داشت. حتی اگر سامانه‌ای بدون بدهی وجود داشت، چطور به آن دست می‌یابید؟ احتمالاً باید زمان و پول زیادی صرف کنید که لزوماً به موفقیت پروژه منجر نخواهد شد.

در ارائه‌ای که در آمازون و تویتر داشتیم، آن‌ها به شدت موفق بودند در حالی که مقدار زیادی بدهی فنی وجود داشت. بنابراین فکر می‌کنم یکی از چیزهای جالب این است که بدهی فنی به هیچ وجه به موفقیت تجاری محصول گره نخورده است؛ می‌توان پروژه‌ای یا کسب و کاری از لحاظ تجاری موفق داشت که بر اساس نرم‌افزاری پر از مشکل استوار شده است؛ می‌شود بعداً آن را بازنویسی کرد. Extreme Programming این ایده را مطرح کرد که کیفیت را حداکثر قرار دهید و به هیچ وجه آن را فدا نکنید. این ممکن است ایده‌ی خوبی نباشد چون مقادیر زیادی منابع، پول و نیرو صرف بالا نگه‌داشتن کیفیت می‌کنید در حالی که ضرورتی ندارد و ممکن است اصلاً موفقیت تجاری را تحت تأثیر قرار ندهد. چون ممکن است چیزی باشد که کاربر اصلاً آن را نمی‌بیند. بنابراین بدهی فنی ممکن است بهترین تشبیه نباشد. سؤال همچنان این است که چرا به آن اهمیت می‌دهیم؟ چون در دراز مدت ممکن است بهره‌وری را تحت تأثیر قرار دهد و بدهی فنی صرفاً چیزی است که برای بهبود انتقال مطلب از آن استفاده می‌کنیم. ممکن است بهترین تشبیه نباشد، چون می‌توانید بگویید سیستم بدون بدهی غیر ممکن است و یا می‌توانید بگویید در بسیاری موارد حتی تصمیم آگاهانه‌ای در مورد بدهکار شدن وجود ندارد مثلاً در برخی موارد به علت فناوری جدید است که بدهی فنی رخ می‌دهد و نمی‌شود کاری در قبال آن کرد. بنابراین این تشبیه تاحدی معیوب است که شاید نیاز باشد به دنبال تشبیه دیگری باشیم. این موضوعی است که فلیکس مولر و من سعی داریم در حین پروژه‌ی کارشناسی ارشد روی آن کار کنیم (در این مقاله راجع به آن صحبت شده است -مترجم). ایده‌ی اصلی این است که اگر نمی‌توانیم از [تشبیه] بدهی فنی استفاده کنیم چون همیشه وجود دارد و چون گاهی تصمیم‌گیری آگاهانه در مورد آن وجود ندارد، پس چرا از تشبیه متفاوتی استفاده نمی‌کنیم؟ تشبیهی که ما پیشنهاد کردیم «بهبود در کیفیت» است. به جای این‌که در مورد بدهی صحبت کنیم...

بهبود در کیفیت است یا سرمایه‌گذاری در کیفیت؟

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

آخرین مسئله در این مورد مدل کیفیتی است که به نظر من مشابه آن است. مدلی به نام SQALE وجود دارد که در آن چیزی به نام هزینه‌های مداوا (Remediation Costs) دارند که به معنی نیروی لازم برای برطرف کردن مشکلات کیفیت است و همچنین هزینه‌های مداوا نکردن (Non-remediation Costs) را دارند که نیرویی است اگر مشکلات را برطرف نکنید نیاز دارید. بنابراین اگر پوشش کد بدی داشته باشید، هزینه‌ی مداوا برابر با بهبود پوشش تست‌ها خواهد بود و هزینه‌ی مداوا نکردن، بهره‌وری کم‌تر است چون باید زمانی بیشتری صرف برطرف کردن خطاها و ... کنید. فکر می‌کنم این مسئله‌ی جالبی باشد. فکر می‌کنم در اصل این مربوط به طرز فکر باشد. طرز فکر باید این باشد که اگر در چیزی سرمایه‌گذاری می‌کنم، مثلاً پوشش تست را بهبود می‌دهم، اگر خط‌ لوله‌ی تحویل مستمر را بهبود می‌دهم، یا اگر در کیفیت کد سرمایه‌گذاری می‌کنم، نباید آن را زر اندود کنم. باید کارهایی را انجام دهم که بهره‌وری را بالا نگاه می‌دارند و هزینه‌ی صرف‌شده را پس می‌دهند. اگر به کیفیت به این شکل بنگرید فکر می‌کنید راه مناسبی برای رسیدگی به بدهی فنی و کیفیت داخلی و همچنین انتقال مطلب به تصمیم‌گیرندگان و مدیران باشد.

یکی از انتقادهایی که به این مدل هست این است که توسعه‌دهندگان باید همواره کیفیت را بالا نگاه دارند اما فکر می‌کنم هنوز مشکلات بزرگ‌تری هست که باید برطرف شوند و توسعه‌دهنده به تنهایی نمی‌تواند این کار را انجام دهد. آن‌ها باید با [بخش] تولید محصول هماهنگ باشند و چیزهایی از این قبیل. برای مثال اگر بخواهید خط‌لوله‌ی تحویل مستمر (Continuous Delivery Pipeline) داشته باشید چون می‌خواهید سریع به انتشار برسید، این نیروی خیلی زیادی می‌طلبد. این چیزی نیست که توسعه‌دهنده به تنهایی بتواند زیر بار آن برود و برای متقاعد کردن مدیریت برای سرمایه‌گذاری در آن، تشبیهی مثل سرمایه‌گذاری در کیفیت نیاز است که می‌گوید اگر این خط‌ لوله را داشته باشید کیفیت بهتری خواهیم داشت و خطاهای کمتر و بهره‌وری بیشتری خواهیم داشت. به این شکل، در گفتگویی که با مدیریت دارید به راه‌حل بهتری خواهد رسید. سؤال دیگر این است که چطور می‌توان بدهی فنی را تشخیص داد؟ شما در اینجا نظراتی دارید. درست است؟

بله. در حقیقت برخی نظرات افراد دیگر را دزدیده‌ام :) برخی نشانه‌های واضح وجود دارند. مثلاً اگر کد پر از TODO و FixMe هاست این نشان می‌دهد که افراد برای تحویل عملکرد عجله داشتند اما در همین حال بسیاری موارد فرصت بهبود را می‌دیدند. یا اگر می‌خواهید کدی را تغییر دهید و توسعه‌دهنده می‌گوید: «من نمی‌توانم این کد را تغییر دهم چون این کد فلانی است!» شما به دردسر بزرگی افتاده‌اید. چون این بدین معنی است که شما خواستید که سریع پیش بروید و تنها یک توسعه‌دهنده همه چیز را در ذهنش دارد و آن را به اشتراک نگذاشته است و یک جزیره دانش شکل گرفته است. اگر آن توسعه‌دهنده با اتوبوسی تصادف کند دیگر هیچ کس نمی‌تواند چیزی را در کد تغییر دهد. اگر بخشی از کد فقط توسط افراد خاصی قابل تغییر باشد نشان‌دهنده‌ی این است که یک بدهی بزرگ فنی وجود دارد. همچنین اگر در راهروها می‌شنوید که بله ما هم عملکرد مشابه را داریم اینجا و آنجا داریم، پس بیایید کد را کپی کنیم و برخی قسمت‌های آن را تغییر دهیم. ممکن است بتوانید این کار را یکی دو بار انجام دهید اما اگر زیادی این کار را انجام دهید مخزن کدتان کاملاً غیر قابل نگه‌داری خواهد شد و تبدیل به یک کد اسپاگتی می‌شود. نشانه‌ی دیگر این است که توسعه‌دهنده‌ای می‌گوید: «دوست ندارم به این کد دست بزنم چون مطمئن نیستم اگر این کار را بکنم کلی چیز خراب نشود». این بدین معنی است که طراحی خیلی بدی دارید و نمی‌توانید تغییرات محلی برای نیازمندی‌های محلی انجام دهید چون همه چیز به نوعی به هم گره خورده است. شما در خطر هستید و در پیاده‌سازی نیازمندی‌های جدید خیلی کند عمل می‌کنید و رفع یک خطا، خطاهای دیگری را ایجاد می‌کند. تنها راه جلوگیری از آن تست گسترده است. نشانه‌ی دیگر در تیم‌های اسکرام است. آن‌ها [مفهومی به نام] سرعت (Velocity) دارند. اگر سرعت تیم مدام کاهش پیدا کند در حالی که تیم پایدار است باید از خود بپرسید چرا سرعت در حال کاهش است؟ در اکثر مواقع این به خاطر بدهی فنی است. و نکته‌ی دیگری هم که قبلاً گفتیم این است که نرم‌افزار پیر می‌شود: کتابخانه‌های قدیمی، JDK های قدیمی یا هر چیز قدیمی دیگر. اگر یک سیستم با طراحی بی‌نقص داشته باشید، ده سال دیگر به همان بی‌نقصی نخواهد بود. باید کتابخانه‌های آن را به‌روزرسانی کنید و ارتقاء دهید تا نیازمندی‌های جدید را برآورده کند و بتوان موفق بود. همچنین به نظر من بد است که بشنوید: «می‌توانیم این خطای مهم را رفع کنیم و فقط یک خط است یکی دو هفته طول می‌کشد تا منتشر شود». آن‌چه که واقعاً می‌خواهید این است که وقتی خطایی را برطرف می‌کند ده دقیقه یا یک ساعت بعد بتوانید نسخه‌ی جدید را انتشار دهید. اما اگر چرخه‌ای دو سه هفته‌ای دارید که بخش کوچکی از کد را تغییر دهید و آن را انتشار دهید، مشکل دارید. [مسئله دیگری که] خیلی مهم نیست اما جالب است این است که تست‌های کندی دارید که واضح است زمان می‌گیرد. اگر سیاستی دارید که می‌گوید حتماً باید تمامی تست‌ها را اجرا کنید قبل از این که کد خود را ثبت کنید -که به نظر من هر پروژه‌ای باید این سیاست را داشته باشد- خیلی فرق می‌کند که مجبور باشید یک دقیق صبر کنید، یا ده دقیقه، یا بیست دقیقه. تعدادی نشانه‌ی دیگر هم هست که شاید شما بخواهید در موردش صحبت کنید. مثل SonarQube یا Structure101

اگر بخواهید به کیفیت کد نگاه کنید، SonarQube ابزار خوبی برای تحلیل کد است که کارهای متفاوتی انجام می‌دهد. تحلیل ایستای کد انجام می‌دهد، پوشش کد تست‌ها را بررسی می‌کند و خیلی کارهای دیگر. نکته‌ی جالب درباره‌ی آن این است که ابزارهای زیادی را ادغام می‌کند و به شما گزارش خوبی از میزان خوبی کدتان می‌دهد. اطلاعات تاریخی در اختیارتان می‌گذارد تا بفهمید که در حال بهبود هستید یا خیر. ابزارهای دیگر هم مثل Structure101 وجود دارند که من دوست‌شان دارم. همین‌طور Sonargraph که به شما اجازه می‌دهد معماری کدتان را تحلیل کنید. فقط کدتان را به آن می‌دهید -گاهاً کد کامپایل شده- و سپس می‌توانید معماری را ببینید، این‌که چقدر خوب است، چقدر وابستگی دارد، چقدر پیچیدگی دارد و می‌توانید بر اساس آن واکنش نشان دهید. این‌ها ابزارهایی هستند که می‌توانید از آن استفاده کنید. باز هم من فکر می‌کنم که مهم‌ترین چیز این است که کدی داشته باشیم که به سهولت قابل تست باشد. و اگر می‌خواهید بدهی فنی را تشخیص دهید، چیزی که باید به آن فکر کنید این است که چه چیزی بیشترین تأثیر را بر قابلیت نگه‌داری دارد؟ چه چیزی بیشترین تأثیر را بر تغییرپذیری دارد؟ چطور می‌توانم این‌ها را بهبود دهم؟ و این [مسائل] لزوماً وابسته به کد نیست. ممکن است مربوط به تست‌ها باشد، به خاطر پوشش پایین تست‌ها، تغییر آن سخت است چون نمی‌توانید از تغییرات‌تان مطمئن باشید. ممکن است چیزی را خراب کرده باشید و تا زمان انتشار متوجه آن نشوید. یا همان‌طور که گفتیم اگر استقرار یا تست‌های کندی داشته باشید، تغییرات کم‌تری می‌توانید در کد اعمال کنید چون قرار دادن آن تغییرات در محصول زمان زیادی می‌گیرد.

ما در مورد شناسایی بدهی فنی صحبت کردیم. حالا سؤال این است که در قبال آن چه کار می‌توانیم انجام دهیم؟ فکر می‌کنم موضوع جالبی باشد. یکی از راه‌هایی که می‌توانید با بدهی فنی روبرو شوید این است که یک فعالیت حائل (‌Buffer Task) در هر دوره‌ی انتشار ایجاد کنید. مثلاً می‌گویید ده درصد از زمان را به تیم اختصاص دهیم تا روی مسائل فنی کار کند. چیزهایی که آن‌ها فکر می‌کنند باعث بهبود می‌شود. حتی می‌توانید مقدار بیشتری از بودجه‌تان را صرف بدهی فنی کنید. می‌توانید انتشار فنی (Technical Release) داشته باشید که صرفاً در آن کد را بهبود داده‌اید. این به این معنی است که نیروی صرف شده برای بدهی فنی به صورت متوازن پخش نشده است-مانند آن‌چه که در فعالیت حائل داشتیم که ده درصد هر اسپرینت را می‌گرفت، در اینجا یک اسپرینت کامل از هر دو یا سه اسپرینت است. ممکن است یک انباره‌ی فنی (Technical Backlog) (اشاره به انباره‌ی نیازمندی‌ها در Scrum -مترجم) از چیزهایی که باید بهبود داده شوند، داشته باشید. راه دیگر این است که اگر برای ویژگی‌های کسب و کار، یک وظیفه (Task) یا داستان کاربری (User Story) داریم در همان حال می‌توانیم بخشی از نیرو را در رسیدگی به بدهی فنی سرمایه‌گذاری کنیم. اساساً هدف این است که وقتی داستان جدیدی داریم و مثلاً می‌خواهیم فرایند ثبت‌نام را تغییر دهیم، در حین انجام تغییرات، کیفیت را بهبود دهیم به نحوی که پیاده‌سازی فرایند ثبت نام آسان‌تر شود. به این طریق بودجه‌ی بهبود کیفیت را در بخش‌هایی صرف می‌کنیم که تغییرات در آن‌ها انجام می‌شود. این چیزی است که بر هر مورد کاربرد تأثیر می‌گذارد و مدیریت می‌تواند در مورد آن تصمیم بگیرد. او می‌تواند بگوید من این داستان را نمی‌خواهم چون خیلی گران است، چون کیفیت خیلی پایین است و از این طریق به مدیر اجازه می‌دهید این‌گونه تصمیمات را بگیرد.

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

بله. فکر می‌کنم اعتماد نکته‌ی مهمی است چون اغلب مواردی هست که توسعه‌دهندگان شکایت زیادی از کیفیت بد و چارچوب‌های بد دارند و می‌گویند باید این را بهبود دهیم، باید این چارچوب را عوض کنیم و ... حرفشان توسط مدیر شنیده می‌شود ولی مدیر می‌گوید این خیلی مهم نیست. اما اگر یک توسعه‌دهنده‌ی خیلی خوب داشته باشید که کسب و کار را بشناسد و این را ثابت کرده باشد و وقتی او می‌گوید: «باید مشکل آن‌ها را حل کنیم چون با این کد به جایی نمی‌رسیم، باید آن را پاک‌سازی کنیم» اگر افراد حوزه‌ی کسب و کار به این فرد یا گروه اعتماد داشته باشند آن وقت است که می‌توانیم ادامه دهیم. اگر مدیران به این افراد اعتماد داشته باشند می‌گویند: «اگر فلانی و بهمانی می‌گویند، پس مهم است و باید این کار را بکنیم. آن‌ها کسب و کار را به طور کلی می‌شناسند؛ شاید باید به آن‌ها گوش دهیم و به آن‌ها اجازه دهیم تصمیم بگیرند.»

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

منظور من این بود که توسعه‌دهندگانی هستند که در حوزه‌ی مسئله خبره هستند و به نوعی راهبرد کسب و کار را می‌شناسند و این‌که سامانه به کجا رهنمون است. اگر افراد حوزه‌ی کسب و کار به این توسعه‌دهندگان اعتماد داشته باشند که می‌گویند باید در کیفیت سرمایه‌گذاری کنیم معمولاً حرفشان شنیده می‌شود. اما اگر کسب و کار را نفهمید خیلی دشوار است که این اعتمادسازی را انجام دهید.

بله درست است. اگر چنین توسعه‌دهندگانی در تیم داشته باشید خیلی خوش‌شانس هستید. اما این مسئله همچنین انتظارات را از توسعه‌دهندگان تا حدی افزایش می‌دهد که من مطمئن نیستم خیلی‌ها بتوانند این کار را انجام دهند. چون شما فقط به دنبال افراد فنی خوب نیستید، بلکه کسانی که در مورد کسب و کار هم اطلاع دارند و یک فرد فنی خوب بودن به خودیِ خود به اندازه‌ی کافی دشوار است. اگر قرار باشد در مورد کسب و کار هم بدانید واقعاً سخت خواهد شد. برای همین است که من فکر می‌کنم در برخی موارد باید افراد حوزه‌ی کسب و کار و تیم فنی با هم در این مورد کار کنند که به همین علت خیلی سخت است.

فکر می‌کنم یک نکته‌ی مهم دیگر باقی مانده باشد. این سؤالی است که فرانک بوشمان چندی پیش مطرح کرد. فرانک بوشمان بیشتر به خاطر کتاب معماری نرم‌افزار مبتنی بر الگو شناخته شده است. او می‌پرسد: بدهی فنی را باید تسویه کرد یا نه؟ به نظر من این مقاله خیلی جالب بود ولی متأسفانه به صورت رایگان در دسترس نیست و باید آن را از IEEE خریداری کنید. اما او می‌گوید: ما همواری بدهی فنی داریم؛ غیرقابل پیش‌گیری است. چطور با آن مواجه شویم؟ یعنی آیا آن را تسویه می‌کنیم یا نه؟ او سه پاسخ به این سؤال می‌دهد. حالت اول پرداخت بدهی است (Debt-free Payment). ما یک قطعه کد یا مؤلفه‌ی بد در سامانه داریم و تصمیم می‌گیریم کاملاً آن را Refactor کنیم یا ممکن است آن را جایگزین کنیم،‌ آن را دور بریزیم و از نو بسازیم یا به یک طراحی پایدار و خوب پیرایش کنیم. فقط زمانی باید این کار را بکنید که کد واقعاً بد است و شما می‌دانید که باید بر اساس آن در آینده به دفعات عملکردهای جدیدی بسازید. حالت دومی که پیشنهاد می‌کند تبدیل بدهی است. شما مؤلفه‌ای یا بخش از سامانه را دارید که بدهی فنی زیادی دارد اما جایگزینی آن راه‌حل عملی نیست. مثلاً یک برنامه‌ی میراثی سی ساله دارید که نمی‌توانید آن را دور بریزید، چون خیلی گران است، یا ریسک زیادی دارد اما می‌توانید بدهی را تبدیل کنید. یعنی سامانه را به چیزی بهتر اما نه بی‌نقص تبدیل کنید. این راه‌حل بهتر و نه بی‌نقص، نرخ بهره‌ی پایین‌تری دارد. بنابراین هنوز هم بی‌عیب نیست، هنوز هم باید برای توسعه‌ی آن هزینه کرد، اما خیلی خیلی بهتر از سامانه‌ی قبلی است و ما استطاعت ساختن راه‌حل بی‌نقص را نداریم چون زیادی گران است و زیادی ریسک دارد. و آخرین حالت که آن را زیاد می‌شنوم و فکر می‌کنم نکته‌ی درستی باشد این است که با آن کنار بیاییم و بهره‌ی آن را بپردازیم. می‌دانیم که کد خوبی نیست، اما آن را تحمل می‌کنیم. چون هر چند خیلی خوب نیست ولی نباید زمانی زیادی را هدر دهیم و هزینه‌ی پیرایش کد نامطلوب به کد بهتر از تحمل کردن آن بیشتر است. فکر می‌کنم این چیزی است که باید همیشه در ذهن داشته باشیم. آیا باید آن را بهبود دهیم؟ یا این‌که هزینه‌ی آن از تحمل کردن آن بیشتر است؟ فکر می‌کنم این مشارکت خیلی خوبی بود. فکر می‌کنم این همه چیز باشد. درست است؟

بله، سوِن. خیلی ممنونم که وقت گذاشتی و با من در مورد بدهی فنی صحبت کردی.