کد تمیز چیست و چرا اهمیت دارد؟

clean the poor codes
clean the poor codes


مقدمه

در این نوشته و نوشته های بعد، می‌خواهیم درباره "کد تمیز" صحبت کنیم.. اما کد تمیز واقعا چی هست؟

من می‌تونم ساعت‌ ها در مورد خصوصیات کد های تمیز باهاتون صحبت کنم و از این کار خیلی هم لذت می‌برم، اما خودم رو در جایگاهی نمی‌بینیم که بخواهم تعریف خودم رو از ماهیت کد تمیز ارائه بدم.. دلیلش هم خیلی ساده است; چون اساتیدی وجود دارند که قبلا این کار رو به نحو احسنت انجام دادند. یکی از این اشخاص آقای "رابرت سی مارتین" (Robert C Martin) هست، که چندین کتاب کامل هم در این باره نوشته..

اسم یکی از بهترین کتابهای آقای مارتین "معماری تمیز" هست; که خوندنش رو به همه کسانی که به شکلی با کد سر و کار دارند، پیشنهاد میکنم.

Clean Architecture: A Craftsman's Guide to Software Structure and Design (Robert C. Martin Series)

اگر وقت یا انگیزه لازمه برای خوندن این کتاب رو دارید، که چه بهتر.. اگر هم نه که اشکالی نداره; چون مطالب این نوشته در واقع چکیده ای از مقدمه این کتاب هست. که با هم بررسی می‌کنیم

مباحثی که مرور خواهیم کرد به شرح زیر است:

  • مهارت چیست؟
  • کد بد یا کثیف چیست؟
  • نشانه های شلختگی
  • طراحی مجدد
  • نگرش
  • مسئله اصلی
  • هنر کد تمیز
  • کد تمیز چیست؟
  • نتیجه ‌گیری

مهارت چیست؟

برای خوب انجام دادن هر کاری نیاز به مهارت داریم، که برنامه نویسی و کد زدن هم از این قاعده مستثنی نیستند. به دست آوردن مهارت در ۲ بخش خلاصه میشه:

  • دانش
  • تمرین

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

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

نوشتن کد های تمیز کار نسبتا مشکلی هست. برای این کار به چیزی بیش از دونستن الگوها و اصول نیاز داریم. باید سخت کار کرد و عرق ریخت. باید تمرین کرد و شکست خورد. باید شکست ها رو دید و تجربه کسب کرد. باید زمین خوردن ها و بلند شدن ها رو تجربه کرد.


به سلسله مراتبی که از اینجا به بعد بررسی میکنیم، دقت کنید:


کد بد یا کثیف چیست؟

برای درک بهتر موضوع که چرا باید تمیز کد نوشت، بگذارید ابتدا از کد کثیف شروع کنیم.

همه ما در مقطعی کد هایی نوشتیم که خودمون هم دوست نداشتیم بهشون دست بزنیم. چون Fragile یا شکننده بوده‌اند.. و با کوچک ترین تغییری خیلی از بخش ها تحت شعاع قرار می‌گرفتند.. چنین برنامه ای کاملا در هم تنیده شده (Coupling) و کوچکترین تغییرات در اون زمان و هزینه زیادی میبره.

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

قطعا با چنین کدی روبرو شدید (یا شاید حتی چنین کدی نوشتید) .. اما واقعا چرا؟

آیا می‌خواستید سریع پیش برید؟ آیا عجله داشتید؟ آیا به دِدلاین پروژه نزدیک بودید و باید کار رو جمع می‌کردید؟ آیا وقتی برای ریفکتور و تمیز کاری نداشتید؟ آیا دپارتمان های دیگر وابسته به پیشرفت کار شما بوده‌اند، و مجبور بودید نیازهای اون ها رو بر آورده کنید؟ دلایل بیشماری می‌تونه وجود داشته باشه.

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



نشانه های شلختگی

تیم‌های توسعه نرم افزار یکی از اجتماعاتی هستند، که شلختگی کد آثار خودش رو به خوبی در اونها نشون میده.

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

با بیشتر شدن شلختگی، بهره‌وری تیم همچنان رو به کاهش میره، و در نهایت به صفر نزدیک میشه. با کاهش بهره وری، مدیریت معقول ترین کار رو انجام میده و به امید افزایش بهره وری، افراد بیشتری رو به پروژه اضافه میکنه..

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

mess-oriented productivity over time
mess-oriented productivity over time



طراحی مجدد

سرانجام تیم توسعه دهندگان نا امید شده و به مدیریت اطلاع می دهند که نمی توانند به توسعه چنین سورس کدی ادامه دهند. آنها خواستار طراحی مجدد هستند.

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

پس تیم جدیدی تشکیل داده می‌شود; از آنجایی که این یک پروژه سبز (green-field project) است، پس همه می‌خواهند بخشی از آن باشند و از ابتدا چیزی زیبا خلق کنند. اما فقط درخشان ترین اعضا برای این تیم جدید انتخاب می‌شوند; و باقی باید به کار کردن روی سیستم قدیمی ادامه دهند.

اکنون دو تیم در یک مسابقه هستند. تیم جدید باید یک سیستم جدید بسازد که همه کارهایی را که سیستم قدیمی انجام می دهد را انجام دهد. نه تنها این ، آنها باید با تغییراتی که به طور مداوم در سیستم قدیمی ایجاد می شوند همگام شوند. مدیریت تا زمانی که سیستم جدید نتواند هر کاری را که سیستم قدیمی انجام می دهد انجام دهد ، سیستم جدید را جایگزین سیستم قدیمی نخواهد کرد.

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



نگرش

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

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

مشکل در سرنوشت ما نیست، بلکه در خودمان است. ما غیر حرفه ای هستیم.

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

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

"غیر حرفه‌ای ترین" رفتار یک توسعه دهنده این است، که به خواسته مدیرانی که ریسک ایجاد شلختگی‌ها را نمی‌فهمند تن در دهد.


مسئله اصلی

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

به عبارتی دیگر: «تنها راه سریع رفتن، تمیز رفتن است.»



هنر کد تمیز

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

اگر ندانیم تمیز بودن کد به چه معناست، تلاشمان برای نوشتن کدهای تمیز بیهوده است...

نوشتن کد تمیز بسیار شبیه به نقاشی کشیدن است. اکثر ما تفاوت یک نقاشی هنری خوب و بد را از هم تشخیص می‌دهیم، اما این قدرت تشخیص بدان معنا نیست که ما میدانیم چگونه نقاشی بکشیم.. و همین ماجرا برای کدهای ما هم صادق است... قدرت تشخیص کد های تمیز از کدهای کثیف، هرگز بدان معنا نیست که ما می‌دانیم "چگونه تمیز کد بنویسیم..."

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

یک برنامه نویس بدون "حس تمیزی" می تواند به یک ماژول به هم ریخته نگاه کند و به هم ریختگی را تشخیص دهد اما نمی داند در مورد آن باید چه کاری انجام دهد. و یک برنامه نویس با "حس تمیزی" به یک ماژول بی نظم نگاه می کند و گزینه ها و دگرگونی ها را جهت تمیز کردن آن مشاهده می کند.

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


کد تمیز چیست؟

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


خالق سی پلاس پلاس - Bjarne Stroustrup

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


گردی بوچ - Grady Booch

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


موسس OTI - آقای Dave Thomas

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


میشل فیدرز - Micheal Feathers

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


نتیجه گیری

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

تنها کاری که می تواند انجام دهد این است که روندهای فکری برنامه نویسان خوب و ترفندها ، تکنیک‌ها و ابزارهایی را که آنها استفاده می کنند را به شما نشان دهد.

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

در طول زمان تجربه به من ثابت کرده که تنها راه پیشرفت، ابتدا دانش و سپس تمرین، تمرین و تمرین برای کسب مهارت هست.

ویالونیست کنسرتی در راه رسیدن به محل اجرا گم شده بود.. وی پیرمردی را در گوشه ای متوقف کرد و از او پرسید: چگونه می توان به سالن کارنگی (محل اجرا) رسید؟ پیرمرد به ویالونیست و ویالونی که زیر بغلش بود نگاهی کرد و گفت: «تمرین کن پسر. تمرین!»


در نوشته های بعد به بررسی بیشتر موضوع می‌پردازیم



منابع:

  • کتاب Clean Architecture
  • ریپازیتوری فارسی Clean Code (استفاده از ترجمه برای بخش نظرات)