پرش به مطلب اصلی

مستند بی‌صاحب از بی‌مستندی بدتر است

· ۱۳ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

حافظه‌ی فنی تیم

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

منظور از مستند بی‌صاحب، سندی است که معلوم نیست چه کسی مسئول درستی امروز آن است، از چه مسیری باید اصلاح شود، و آیا هنوز می‌شود برای تصمیم گرفتن به آن تکیه کرد یا نه.

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

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

این نوشته از همین نقطه شروع می‌کند: کد چه چیزی را می‌گوید، مستند چه چیزی را باید بگوید، و هر نوع دانش فنی کجا باید بماند تا با تغییر سیستم از واقعیت عقب نیفتد.

حافظه‌ی شفاهی با رشد تیم دوام نمی‌آورد

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

اما با رشد تیم، همین الگو تبدیل به ریسک می‌شود. نفر جدید برای یک تغییر ساده باید چند نفر را پیدا کند. کسی که دلیل تصمیم را می‌دانست جابه‌جا شده. کد تغییر کرده، اما توضیح تصمیم نه. نتیجه این است که تغییرهای آینده نه بر پایه‌ی فهم مشترک، بلکه بر پایه‌ی حدس انجام می‌شوند.

نکته

دانشی که فقط در ذهن آدم‌هاست، مستند نیست؛ وابستگی عملیاتی است.

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

پس مسئله فقط نوشتن چند صفحه‌ی بیشتر نیست؛ مسئله تبدیل دانش فردی به حافظه‌ای است که تیم بتواند به آن تکیه کند.

معیار مستند خوب: کاهش هزینه‌ی فهم و تغییر

مستند فنی برای رسمی‌تر شدن پروژه نیست. معیار خوب بودن آن این است که هزینه‌ی فهم، استفاده، تغییر و نگهداشت سیستم را کم کند. اگر مستند این هزینه را کم نکند، حتی اگر کامل و مرتب به نظر برسد، ارزش مهندسی کمی دارد.

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

اصل مهم

مستند خوب سرمایه‌گذاری روی تغییرهای آینده است، نه کاری برای قشنگ‌تر کردن ظاهر پروژه‌ی امروز.

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

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

پس مستند خوب فقط «درست» نیست؛ باید پیدا شود، سریع خوانده شود، و خواننده را به تصمیم درست برساند.

چرا مستندها از واقعیت عقب می‌افتند؟

مستند معمولاً به دو دلیل خراب می‌شود: یا از جایی که تغییر رخ می‌دهد دور است، یا مسئول و مسیر بازبینی ندارد. در هر دو حالت، سند یک روز درست بوده، اما تضمینی برای درست ماندنش وجود ندارد.

ویکی و ابزارهایی مثل Confluence در شروع کار جذاب‌اند: نوشتن در آن‌ها سریع است، لینک دادن آسان است و همه می‌توانند چیزی اضافه کنند. این مزیت مهمی است. ویکی برای دانش بین‌تیمی، تصمیم‌های سازمانی، پرسش‌های پرتکرار، مسیرهای شروع و لینک دادن به سندهای معتبر جای خوبی است.

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

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

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

در سازمان‌های بزرگ، این وضعیت معمولاً به چند نسخه از یک واقعیت ختم می‌شود: چند راهنما برای یک کار، چند توضیح برای یک رفتار، و چند صفحه که معلوم نیست کدام هنوز معتبر است. راه‌حل این نیست که سند بیشتری بنویسیم؛ باید یکی منبع قابل اتکا باشد و بقیه حذف، ادغام یا صریحاً قدیمی اعلام شوند.

خطر

سندی که بیرون از مسیر تغییر می‌ماند، کم‌کم از حافظه‌ی تیم به بایگانی حدس‌ها تبدیل می‌شود.

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

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

کد چه می‌گوید، مستند چه باید بگوید؟

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

کد چه می‌گوید، مستند چه باید بگوید؟

کامنت بد چیزی را تکرار می‌کند که از خود کد پیداست:

# Check if the error code is final.
if error_code in FINAL_ERROR_CODES:
return False

کامنت خوب، زمینه‌ای را ثبت می‌کند که برای تغییر امن لازم است:

# These errors are final for the old payment provider.
# Retrying them can create duplicate settlement records.
if error_code in FINAL_ERROR_CODES:
return False
قاعده‌ی ساده

اگر توضیح فقط رفتار آشکار کد را تکرار می‌کند، حذفش کن. اگر نیت، قرارداد، محدودیت یا دلیل تصمیم را روشن می‌کند، کنار کد نگهش دار.

نتیجه این نیست که هر خط کد باید توضیح داشته باشد. نتیجه این است که هر دانشی که برای تغییر امن لازم است و از خود کد روشن نیست، باید ثبت شود.

حافظه‌ی فنی چه شکل‌هایی دارد؟

مستند یک چیز واحد نیست. بخشی از حافظه‌ی فنی در کامنت تابع و قرارداد API می‌ماند، بخشی در README و راهنمای راه‌اندازی، بخشی در سند طراحی، و بخشی در صفحه‌ی شروع یا ویکی. خطا از جایی شروع می‌شود که همه‌ی این‌ها را در یک ظرف بریزیم.

اول باید مخاطب روشن باشد. استفاده‌کننده‌ی API دنبال قرارداد استفاده است. نگه‌دارنده دنبال دلیل پیاده‌سازی و نقاط خطر است. تازه‌وارد مسیر شروع می‌خواهد. تصمیم‌گیر فنی دنبال گزینه‌های ردشده و هزینه‌های هر انتخاب است.

هر مخاطب چه می‌خواهد؟

از زاویه‌ی رفتار خواننده هم دو حالت مهم داریم. گاهی خواننده جست‌وجوگر است؛ سؤال مشخصی دارد و جواب سریع و دقیق می‌خواهد. گاهی رهگذر است؛ تازه با سیستم روبه‌رو شده و هنوز نمی‌داند باید دنبال چه چیزی بگردد. مستند مرجع برای اولی خوب است، صفحه‌ی شروع و آموزش گام‌به‌گام برای دومی.

پرسش قبل از نوشتن

این سند قرار است تصمیم چه کسی را ساده‌تر کند؟ اگر جواب روشن نیست، خود سند هم روشن نخواهد شد.

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

هر نوع مستند کار خودش را دارد

خطای رایج

مستند چندمنظوره معمولاً ظاهراً کامل است، اما در عمل برای خواننده‌ی مشخص کند و مبهم می‌شود.

مرجع API بهتر است تا حد ممکن از نزدیک‌ترین جای معتبر ساخته شود؛ مثلاً از کامنت و قرارداد کنار خود کد. اگر همان قرارداد را یک‌بار کنار کد و یک‌بار دستی در ویکی بنویسیم، از همان لحظه دو جای بالقوه برای اختلاف ساخته‌ایم.

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

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

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

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

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

قاعده‌ی کامنت خوب

کامنت خوب یا قرارداد را روشن می‌کند، یا دلیل تصمیم را، یا محدودیتی را که تغییر آینده باید به آن وفادار بماند.

پس شکل مستند را نباید از روی سلیقه انتخاب کرد. باید دید خواننده دنبال چیست و آن دانش با چه چیزی تغییر می‌کند.

وقتی خواننده فقط انسان نیست

امروز بخشی از خواندن کد و مستند را ابزارهای مبتنی بر مدل زبانی بزرگ (LLM) انجام می‌دهند: برای توضیح کد، تولید تست، بازبینی و بازنویسی. این ابزارها وقتی زمینه‌ی درست ندارند، همان محدودیت انسان را دارند؛ مسیر اجرا را می‌بینند، اما دلیل تصمیم را نمی‌فهمند.

خطای خطرناک

وقتی زمینه‌ی درست کنار کد نیست، ابزار هوشمند هم ممکن است با اعتمادبه‌نفس پیشنهاد اشتباه بدهد.

LLM جای مستند را نمی‌گیرد؛ نبود مستند خوب را پرهزینه‌تر و آشکارتر می‌کند. پس مستند نزدیک به کد فقط برای آدم‌ها نیست. زمینه‌ای است که کیفیت فهم ابزارها را هم بالا می‌برد و احتمال پیشنهادهای ظاهراً منطقی اما نادرست را کم می‌کند.

حافظه‌ی فنی چطور زنده می‌ماند؟

مستند مهم، مثل کد، باید نگه داشته شود. یعنی مسئول داشته باشد، در تغییرهای مرتبط دیده شود، نسخه بخورد، بازبینی شود و وقتی قدیمی شد، یا به‌روز شود یا روشن کنار گذاشته شود.

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

قاعده‌ی نگهداشت

هر سند مهم باید یک مسئول، یک جای رسمی و یک راه روشن برای تغییر داشته باشد.

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

این حافظه کجا باید زندگی کند؟

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

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

هر نوع دانشی جای خودش را دارد

قاعده‌ی جای درست

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

پس سؤال درست این نیست که از چه ابزاری استفاده کنیم؟ سؤال درست این است: این دانش با چه چیزی تغییر می‌کند و خواننده کجا دنبالش می‌گردد؟ جواب این دو پرسش معمولاً جای درست سند را نشان می‌دهد.

جمع‌بندی: حافظه‌ی فنی باید زنده بماند

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

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

جمع‌بندی

مستند خوب قرار نیست جای کد را بگیرد؛ قرار است کمک کند کد، تصمیم‌ها و تغییرهای آینده درست‌تر فهمیده شوند.

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