افکار و نگرش‌هایِ یک برنامه‌نویسِ خوب

نویسنده : سید ایوب کوکبی ۱۱ مرداد ۱۳۹۸
افکار و نگرش‌هایِ یک برنامه‌نویسِ خوب

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

این جملات برایتان آشنا نیست؟

در هر گوشه‌ای از دنیا، برنامه‌نویسان حداقل یا یکی از موارد بالا درگیر هستند یا لااقل به آن فکر می‌کنند. اما چرا؟

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

برای فرو نرفتن در این منجلاب باید چند اصلِ مهمِ مهندسی نرم‌افزار را رعایت کنید. شما باید ذهنیت و نگرش‌های یک برنامه‌نویس خوب را در خودتان بیدار کنید. این ذهنیت به شما کمک می‌کند تا تصمیمات بهتری بگیرید. کمک می‌کند تا نرم‌افزار خود را در نهایت سادگی حفظ کنید و از پیچیدگی‌های ناخواسته جلوگیری به عمل آورید. در ادامه این نگرش‌ها را به صورت کوتاه توضیح می‌دهیم.

هدف از ساخت برنامه را مشخص کنید

پیش از هر چیز باید هدف از ساختِ برنامه را مشخص کنید. تمامِ محصولات نرم‌افزاری یک هدفِ مشترک دارند: کمک به مردم.

به خاطر داشته باشید: هدف از نرم‌افزار پز دادنِ مهارت‌هایتان نیست.

Max Kanat-Alexander, Code Simplicity

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

هنگام تصمیم‌گیری در مورد ساختِ نرم‌افزار همیشه به این سوالِ کلیدی پاسخ دهید: چگونه می‌توانم به مردم کمک کنم؟ پاسخ به این سوال حتی کمک می‌کند فیچرهای درخواستی را به درستی اولویت‌بندی کنید.

درست طراحی کنید

هر برنامه‌نویسی طراح هم هست.

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

طوری کدنویسی کنید که توسعه‌دهنده به راحتی بتواند با آن ارتباط برقرار کند و از این طریق زمانِ بیشتری برای کمک به کاربران اختصاص دهد. طراحیِ خوب باعث می‌شود تا یک برنامه برای مدتِ بیشتری در خدمتِ کاربران باشد.

اما طراحیِ بد باعث کوتاه شدن چرخۀ عمر نرم‌افزار می‌شود. پس هدفِ اصلی طراحیِ برنامه عبارت از:

طراحی سیستمی که به راحتی توسط برنامه‌نویسان ساخته و نگه‌داری شود و برای همیشه مفید باقی بماند.

Max Kanat-Alexander, Code Simplicity

مسائل را درست بفهمید

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

یک روشِ خوب برای بهبود مهارت «درست فهمیدن» این است که درکِ درستی از سیستم و ابزارهایی که با آن‌ها کار می‌کنید داشته باشید.

تفاوت یک برنامه‌نویس خوب و بد در سطح ادراک و فهم آن‌هاست.

Max Kanat-Alexander, Code Simplicity

برنامه‌نویسان بد اصلاً نمی‌دانند در حالِ انجام چه کاری هستند؛ اما برنامه‌نویسانِ خوب به روندِ کارشان واقف هستند. این تفاوت را به سادگی می‌توان فهمید.

ساده کد بنویسید

سادگی نهایتِ پیچیدگی است.

لئوناردو داوینچی

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

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

بقیۀ دولوپرها خواهند فهمید که این کارها را من انجام داده‌ام. بهتر است کدهای پیچیده و هوشمندی بنویسم تا بقیه فکر کننن خیلی آدمِ باهوشی هستم.

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

اینکه شما چقدر زرنگ هستید به افرادی که کدِ شما را می‌خوانند کمکی نمی‌کند. توسعه‌دهنده‌ای که قرار است از کدِ شما استفاده کند هیچ پیش‌زمینه‌ای در موردِ آن ندارد. آن‌ها ناچارند که زمان بگذارند تا کدهای شما را درک کنند.

بنابراین بهتر است این سوال را از خودتان بپرسید: «آیا می‌خواهم دیگران کدهایم را بفهمند و از سادگی‌اش لذت ببرند یا گیج و ناامید شوند؟».

حقیقت این است که اگر سایرین کدهای شما را به آسانی درک کنند کارتان را درست انجام داده‌اید.

پیچیدگی، هوشمندی نیست. هوشمندی، سادگی است.

Larry Bossidy

چقدر ساده کد بنویسیم؟ تا جایی که راه دارد.

پیچیدگی‌ها را کاهش دهید

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

Brian Kernighan

منشأ بسیاری از اشکالات نرم‌افزاری پیچیدگی است. پروژه در ابتدا ساده است و ظرفِ یک ماه به پایان می‌رسد. سپس کمی پیچیدگی به برنامه اضافه می‌کنید و زمان به ۳ ماه افزایش پیدا می‌کند. بعداً قابلیت‌هایی به برنامه اضافه می‌کنید که متناسب با اهدافِ آن نیست. این کار به شدت پروژه را پیچیده می‌کند؛ چون بدون هیچ دلیلی دامنۀ فعالیت نرم‌افزار را گسترش داده‌اید. حالا هر تغییری ۶ ماه طول می‌کشد. ولی این پایان ماجرا نیست…

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

چطور باید از مبتلا شدن به این عاقبتِ دردناک جلوگیری کرد؟

بخوانید  چند کلام حرف حساب با برنامه‌نویسان تازه‌وارد

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

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

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

هدفِ اصلیِ شما کنترلِ پیچیدگی است نه ایجاد کردن آن.

نگهداری کدها را جدی بگیرید

نگهداری، یکی از مهم‌ترین مباحثِ نرم‌افزاری است. متأسفانه بسیاری از توسعه‌دهنده‌ها اهمیتی به این موضوع نمی‌دهند. در نظر آن‌ها کدنویسی و تحویل سریعِ برنامه اهمیتش بیشتری از نگهداریِ برنامه است. نادیده پنداشتن یا سهل‌انگاری در مورد نگهداری کد، کارِ بسیار اشتباهی است و در آینده حتماً کار دستتان می‌دهد.

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

تمام تغییرات نیاز به نگهداری دارند.

سادگی و پیچیدگی دو فاکتور تأثیرگذار در فرایند نگهداری هستند. میزان سهولتِ هر بخشی از نرم‌افزار به سادگی آن بخش وابسته است. این سهولت به میزان پیچیدگی برنامه ارتباط دارد.

قاعده‌ای جالب در مورد نگهداری برنامه:

کاهشِ تلاش برای نگهداری پروژه از کاهشِ تلاش برای پیاده‌سازی آن مهم‌تر است.

Max Kanat-Alexander, Code Simplicity

ثبات و یکنواختی (Consistency)

ثبات، بخشِ مهمی از سادگی است. هنگامِ کدنویسی باید از یک قاعدۀ مشخص پیروی کنید. مثلاً اگر آرایه‌ای را name_array گذاشتید همه جا برای آرایه‌ها باید از همین الگو پیروی کنید. بنابراین اسامی nameArray, names, nameList و … قابلِ قبول نیستند. جورواجور نوشتنِ کد خواندنش را سخت می‌کند. نباید طوری کد بنویسید که توسعه‌دهندگان هربار که به آن مراجعه می‌کنند احساس کنند با یک کدِ جدید مواجه هستند.

اولویت‌بندی کنید

چگونه تصمیم می‌گیرید که از بین چند مسیرِ مختلف یکی را انتخاب کنید؟ فیچرهای درخواست شده را بر اساس چه اولویت‌هایی پیاده‌سازی می‌کنید؟

سه فاکتورِ مهم به تصمیم‌گیری شما کمک می‌کند. این معادله به خوبی در کتاب Code Simplicity توضیح داده شده است:

  • میزان مطلوبیت (D): چقدر خواستار پیاده‌سازی تغییر هستید؟
  • ارزشِ تغییر (V): ارزش این تغییر برای کاربران چقدر است؟
  • تلاشِ لازم برای انجامِ تغییر (E): انجامِ این تغییر چقدر تلاش لازم دارد؟

معادلۀ نهایی به این صورت است: D=V/E

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

هنگامِ اولویت‌بندیِ کارهایتان از قاعدۀ زیر پیروی کنید:

تغییراتِ ارزشمندی که تلاش کمی برای پیاده‌سازی‌شان لازم دارند بهتر از تغییراتی است که ارزشِ کمی داشته و در عین حال تلاشِ زیادی برای پیاده‌سازی‌شان لازم است.

مسائلِ بزرگ را به مسائل کوچکتر بشکنید

اولین قدم «فهمیدن» است. اغلبِ مسائلِ سخت به این خاطر سخت هستند که درست درکشان نکرده‌ایم. وقتی می‌خواهید مسئله‌ای حل کنید ابتدا به زبان خودتان و در ساده‌ترین شکل ممکن روی کاغذ بنویسید؛ انگار که می‌خواهید این سوال را از یک نفرِ دیگر بپرسید.

وقتی نمی‌توانید چیزی را به زبانِ ساده بیان کنید یعنی آن را نفهمیده‌اید.

Richard Feynman

قدمِ دوم برنامه‌ریزی است. فوراً سراغ حلِ مسئله نروید. آن را از زوایای مختلف تحلیل کرده تا درکِ کاملی از مسئله پیدا کنید. البته زمانِ زیادی را برای برنامه‌ریزی صرف نکنید.

قبل از هر اقدامی فکر کنید.

قدمِ سوم تقسیمِ مسئله به مسائل کوچکتر است. هیچگاه سعی نکنید مسئلۀ بزرگی را در همان مقیاس بزرگ حل کنید. بزرگیِ یک مسئله عاملی برای ترس و دستپاچگی شماست. ابتدا مسئله را به تسک‌های کوچکتر بشکنید و از حلِ مسائل کوچکتر به جواب مسئلۀ بزرگتر برسید. مسائلِ کوچک مثلِ قطعات پازل به یکدیگر متصل شده و جواب مسئلۀ بزرگتر را آشکار می‌کنند.

کمال‌گرا نباشید

کمال دشمنِ خوبی است.

Voltaire

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

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

مشکلِ کمال‌طلبی چیست:

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

دوست دارید این اتفاقات بیفتند؟ قطعاً باید جوابتان منفی باشد. پس…

کوچک شروع کنید، بهبود دهید و به ‌تدریج توسعه دهید.

طراحی تدریجی (incremental design) را سرلوحۀ کارتان قرار دهید. مثلاً برای ساخت یک ماشین‌حساب اینگونه عمل کنید:

  1. ابتدا فقط روی عمل جمع تمرکز کنید؛
  2. آن را پیاده‌سازی کنید؛
  3. کدِ فعلی را بهینه‌سازی کنید تا بتوانید بقیۀ عملیات را هم اضافه کنید؛
  4. روی تفریق کار کنید. مراحل ۲ و ۳ را تکرار کنید؛
  5. بروید سراغ ضرب و مجدداً مراحل ۲ و ۳؛
  6. نهایتاً تقسیم و تکرارِ مراحل ۲ و ۳٫

آینده را پیش‌بینی نکنید

پیش‌بینی یعنی پیشگویی در مورد اتفاقات آینده. این کار هم می‌تواند بر اساسِ داده‌های واقعی باشد و هم بر اساس فرضیات.

برخی از دولوپرها با این دید که کدِ من در آینده تغییر می‌کند طوری آن را می‌نویسند که در همه جا قابل استفاده باشد. به عنوان مثال می‌خواهید تعداد ۱۰ کاراکتر ستاره (**********) ذیلِ نام خانوادگی طرف قرار دهید. یک برنامه‌نویس کل‌نگر با این تصور که شاید در آینده به جای ۱۰ ستاره بخواهم ۲۰ ستاره قرار دهم متدی می‌نویسد که با دریافت تعداد ستاره‌ رشتۀ مورد نظر را تولید می‌کند. دوباره عمومی‌تر فکر می‌کند و با خودش می‌گوید که شاید بعدها بخواهم به جای ستاره از خط تیره یا کاراکتر دیگری استفاده کنم. دوباره پارامترِ دیگری برای دریافتِ کاراکتری که باید تکرار شود تعریف می‌کند. و این موضوع همینطور پیچیدگی برنامه را زیاد و زیادتر می‌کند بی آنکه واقعاً در آینده نیازی به این تغییرات داشته باشد.

بخوانید  Junior | Mid-Level | Senior

ثمرۀ کلی‌نگری، کدهای فراوان و بلااستفاده است.

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

هیچگاه آینده را پیش‌بینی نکنید. به اندازه‌ای generic (کلی‌نگر) باشید که هم‌اکنون به آن نیاز دارید. نه بیشتر نه کمتر.

چه اتفاقی می‌افتد اگر این موضوع را رعایت نکنیم؟

با یک مثال توضیح دهیم: توسعه‌دهنده‌ای می‌داند که ویژگی X را باید پیاده‌سازی کند. این کار را انجام می‌دهد و با خودش فکر می‌کند ویژگی Y هم به عنوان مخلفات باید پیاده‌سازی کند. او هزاران خط کد برای پیاده‌سازی ویژگی ناضروری Y می‌نویسد. در آینده نیازمندی‌های پروژه تغییر می‌کند و توسعه‌دهنده ناچار است کدهای اضافه را پاکسازی کند. اکنون او باید زمانِ زیادی را صرف ریفکتور کند. و نهایتاً به این فکر می‌افتد که پروژه را از اول درست کند!

برای اینکه شما هم به سرنوشتِ این توسعه‌دهنده مبتلا نشوید قاعدۀ زیر را رعایت کنید:

کدها را بر اساس نیازمندی‌های امروز و آنچه اکنون در موردِ آن علم دارید بسازید، نه برای آیندۀ نامعلوم که معلوم نیست از راه برسد یا نه.

 Max Kanat-Alexander, Code Simplicity

چرخ را دوباره اختراع نکنید

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

فقط زمانی می‌توانید چرخ را دوباره اختراع کنید که:

  • اصلاً چرخی وجود ندارد؛
  • چرخ‌های موجود نامناسب و ناپایدار هستند؛
  • چرخ‌های موجود به خوبی مستند و نگهداری نشده‌اند.

قاعده بسیار ساده است:

چرخ را دوباره اختراع نکنید؛ مگر اینکه مجبور به این کار شوید.

در برابر تغییراتِ جدید مقاومت کنید

به عنوانِ یک برنامه‌نویس اولین پاسختان به تغییرات جدید باید منفی باشد.

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

چگونه تشخیص دهیم تغییر ضروری است یا نه؟

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

اتوماسیونِ کارهای تکراری

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

اگر می‌توانید کاری را به صورت خودکار انجام دهید حتماً خودکار انجام دهید.

پیشرفتِ برنامه ≠ تعداد خطوطِ برنامه

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

بیل گیتس

تعدادی از برنامه‌نویس‌ها کیفیت برنامه را با شمردن تعداد خطوط آن اندازه می گیرند. این افراد به نوشتنِ کدهای بیشتر افتخار می‌کنند.

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

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

عملکردتان را ارزیابی کنید

عملکردتان را چگونه ارزیابی می‌کنید؟ با نوشتن تعداد خطوط بیشتر یا حذفِ هزاران خط کد؟

هدف اصلی‌تان این باشد که کدبیس پروژه را تا حد امکان کوچک نگه دارید. دنبالِ این نباشید که کدِ بیشتری بنویسید. دنبالِ این باشد که چطور می‌توانید کدهای اضافه را حذف کنید.

سودمندترین روزِ من روزی است که هزاران خط کد حذف کنم.

کن تامپسون

هیچ کدی را بدون تست رها نکنید

چه زمانی باید لاگینگ خطاها و Exception handling به پروژه اضافه کنم؟

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

منشاء بسیاری از مشکلاتِ برنامه‌نویسی تست نکردن کدهاست. مثلاً یک دستور شرطی if-else را در نظر بگیرید. توسعه‌دهنده، بخش if را تست و کامیت می‌کند ولی بخشِ دیگر یعنی else را بدون تست رها می‌کند. این برنامه به محیط Production وارد می‌شود و همان else ای که بدون تست رها شده کار دستشان می‌دهد. بنابراین وقتی کدی را به مخزن ارسال می‌کنید باید تمامِ بخش‌های آن را تست کرده باشید.

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

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

کدِ تست نشده کدی است که کار نمی‌کند!

خوشبین نباشید

توسعه‌دهنده‌ها خیلی بد تخمین می‌زنند.

آن‌ها اغلب خوشبینانه به مسائل نگاه می‌کنند. مثلاً برای پیاده‌سازی یک قابلیت یا نوشتن مقداری کد، زمانِ بسیاری اندکی تخمین می‌زنند. این تخمین نادرست باعث بر هم خوردن برنامۀ کاری و ددلاین‌ها می‌شود.

راهکار: مسائل بزرگ را به مسائل کوچکتر بشکنید. هر چقدر مسئله‌ای کوچکتر باشد میزان خطا در تخمین کمتر می‌شود. تخمینِ اشتباهِ یک مسئلۀ کوچک قطعاً آسیبش کمتر از تخمین یک مسئلۀ بزرگ خواهد بود.

بخوانید  تجربۀ سال‌ها برنامه‌نویسی

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

از دوباره نوشتنِ کد پرهیز کنید

در صورتِ رعایتِ مبانی بیان شده بعید است به نقطه‌ای برسید که نیاز پیدا کنید کد را بازنویسی کنید ولی به هر حال اگر این اشتباهِ بزرگ را مرتکب شدید بدانید که:

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

چرا خودگول‌زنی؟

چون خواندن کد از نوشتنِ آن سخت‌تر است. به همین دلیل استفادۀ مجدد از کدها سخت است. همین موضوع باعث می‌شود تا هنگام خواندن کدِ سایرین جبهه بگیریم و به خودمان القاء کنیم: «ول کن بابا، خودم از اول بنویسم بهتره!».

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

همیشه این نکتۀ ساده را به خاطر بسپارید:

ریفکتور اولین انتخابتان باشد.

مستندسازی کنید

یکی از اشتباهات رایج در کامنت‌گذاری این است که به جای بیانِ دلیل وجودِ فلان کد، عملکردِ آن را توضیح می‌دهیم. این کار اشتباه است. توسعه‌دهنده خودش با بررسی کد متوجه عملکردش می‌شود. چیزی که بیشتر برای او مهم است دلیل استفاده از آن قطعه کد است. به بیانِ دیگر نیازی نیست که بگویید متد remove فلان چیز را حذف می‌کند. این را حتی بدون توضیح و از روی نامِ متد می‌شود فهمید. آنچه مهم است بیانِ حکمتِ وجودیِ این قطعه کد است. چرا در این شرطِ if تابع remove فرخوانی شده است؟

کامنتی بنویسید که به جای «چیستی»، «چرایی» را توضیح دهد. ( به زبان خودمان کامنتی که فلسفۀ وجودی یک قطعه کد را بیان کند).

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

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

وابستگی‌ها را کم کنید

اولین چیزی که هنگامِ شروعِ یک پروژه باید به آن فکر کنید این است:

به تکنولوژی‌های بیرونی وابسته نباشید. تا حدِ امکان میزان وابستگی (dependency) را کاهش دهید.

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

قبل از استفاده از تکنولوژی‌های جدید به موارد زیر توجه داشته باشید:

  • آیا توسعه‌دهندگانِ فعال دارد؟
  • کماکان در حال نگه‌داری است؟
  • سوئیچ کردن از آن تکنولوژی به موارد مشابه آسان است؟
  • دیگران در موردش چه می‌گویند؟

پاسخ به این سوالات کمک می‌کند تا در انتخاب‌هایتان ریسک و اشتباه کمتری مرتکب شوید.

همیشه در حال پیشرفت باشید

مدام در حال یادگیری باشید. زبان‌ها و ابزارهای جدید را امتحان کنید. کتاب‌هایی در حوزۀ توسعۀ نرم‌افزار مطالعه کنید. این کارها افقِ دیدِ شما را گسترش داده و کمک می‌کند تا از زوایای مختلفی به مسائل نگاه کنید. همینکه روزانه کمی وقت صرف این کارها کنید در درازمدت تأثیرش را بر روی مهارت‌ها و سطحِ دانشتان خواهید دید.

ذهنِ بازی داشته باشید. در مورد تکنولوژی‌ها، متعصب نباشید. هر موقع لازم شد از تکنولوژی‌های در دسترس برای حلِ مشکلات جاری‌تان استفاده کنید. به هیچ عنوان خودتان را درگیر بحث‌های بیهوده‌ای مثل مقایسۀ ویندوز و لینوکس، مقایسه زبان‌های برنامه‌نویسی و … نکنید. این بحث‌ها چیزی جز اتلافِ زمان و انرژی در پی ندارند.

هر مسئله‌ای راهکارِ مخصوصِ خود را دارد.

قهرمان‌بازی در نیاورید

در بسیاری از مواقع بهتر است به جای قهرمان‌بازی تسلیم شوید.

برای مثال، فکر می‌کنید تسکی را در ۲ ساعت انجام دهید؛ ولی بعد از گذشتِ ۴ ساعت هنوز یک چهارمش را حل نکرده‌اید. در این شرایط با خودتان می‌گویید «نمی‌توانم تسلیم شوم. تا الان ۴ ساعت وقت گذاشتم!». فازِ لج‌بازی‌تان گل می‌کند و مصمم می‌شوید مسئله را هر طوری هست حل کنید؛ حتی به قیمتِ اینکه کلِ زمان و برنامه‌ریزی خود را فدای آن کنید. اینجاست که وارد لاکِ تنهایی خود می‌شوید و کاری به دنیای پیرامون‌تان ندارید. شما هستید و مسئله‌ای که می‌خواهید یک نفس حلش کنید.

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

درخواست کمک کنید

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

در این مقاله سعی شد نگرش و مبانی فکری یک توسعه‌دهندۀ خوب مطرح شود. در قسمت‌هایی از کتابِ Code Simplicity استفاده شد که خواندن آن را به تمامِ توسعه‌دهنده‌ها پیشنهاد می‌کنیم. هنگام مطالعۀ این کتاب بارها برایتان پیش می‌آید که بگویید «چه جالب، اینو اشتباه انجام میدادم، اینو نمی‌دونستم.» با مطالعۀ این کتاب چیزی بسیار بیشتر از مواردی که در این مقاله بیان کردیم خواهید آموخت.

منبع

سید ایوب کوکبی

نویسنده و مترجم...

0 دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *