پاییز 1396: دوره متدهای چابک
برگردیم به طراحی!
پیشگفتار:
مانند هر انسان دیگری، از دیرباز یک سری پرسش در ذهنام نقش بسته است، و از آنجا که پاسخهای یافتهشده قانعام نکرده، هر از گاهی دوباره فرصتی پیدا میکنند و خودشان به سر صف میرسانند و فرصتی پیدا میکنند تا بخشی از ظرفیت مغزم را به خود اختصاص دهند. من هم به مانند بسیاری از انسانها هم از سر علاقه و هم از سر ناچاری برای رضایت آنها، کمی دنبال منابع جدید میگردم و آنها را مطالعه میکنم و هم از دوستان باتجربهام کمک میگیرم شاید به نقطهی قابل قبولی برسم.
پرسشها:
دیروز از چند تن از دوستانم که در جمعی حاضر بودند خواهش کردم که به سه پرسش زیر فکر کنند و به آن پاسخ بدهند.
پرسش اول: اگر پیادهسازی یک ویژگی جدیدِ سیستم به شما سپرده شود، چگونه و طی چه گامهایی آن را به کد تبدیل میکنید؟ (تاکید روی بخش طراحی است)
پرسش دوم: اگر قرار باشد راهنمای یک برنامهنویس باشید تا ویژگی جدید را پیادهسازی کند، مراحل انجام این کار را در قالب چه گامهایی به او خواهید آموخت؟ (تاکید روی آموزش طراحی حین کار است)
پرسش دوم: اگر قرار باشد پیادهسازی یک ویژگی جدید را در یک کلاس آموزشی به شاگردان آموزش دهید، آموزش شما شامل چه بخشهایی خواهد بود؟ (تاکید روی آموزش عمومی طراحی است)
گزیده:
اعمال یک تغییر در کد ممکن است منجر به ایجاد زنجیرهای از تغییرات در نرمافزار شود که دلیل آن، وجود وابستگی (coupling) بین اجزای نرمافزاری است. در نتیجه هزینهی این تغییر برابر است با جمع هزینهی کل این تغییرات. از سوی دیگر، کاهش یا حذف وابستگی بین این اجزای وابسته (decoupling) نیز نیازمند صرف هزینه است.
از این رو به عنوان برنامهنویس همواره ناچارید بین هزینهی تجمیعی زنجیرهی تغییرات ناشی از وابستگی (coupling) و هزینهی لازم برای جداسازی آنها (decoupling)، یکی را انتخاب کنید (trade-off).
کنت بک
مهندسِ فیلسوف!
پیشگفتار:
[…] یکی از دوستان محبوب من است که سالهاست او را ندیدهام و چند سالی است که در کشور دیگری زندگی میکند. او بیشتر از آن که مهندس باشد، فیلسوف است. نگاهی متفاوت به دنیا دارد. این تفاوت نگاه در کنار دوستی خالصانه و گفتار بیرنگ و لعابش باعث شده تا گفتگو با او همواره برای من آموزنده همراه با حس خوب باشد.
او یکی از خوانندگان قدیمی وبلاگ است. پس از انتشار مطالب اخیر وبلاگ، این پیامها را از او دریافت کردم. آن قدر دلنشین بود که با کسب اجازه از او و با کمی تغییرات، آن را در اینجا آوردهام.
در این پیام، او به یک کار مشترک، یک دوست مشترک و یک خودروی پراید اشاره میکند. ما با هم چند کار مشترک انجام دادیم. برای انجام یکی از این کارها، دوست دیگرمان که خودروی پراید داشت، مانند سرویس مدرسه، یکی یکی ما را از درب منزل سوار ماشین میکرد تا به محل انجام کارمان برسیم. تفاوت این سرویس با سرویس مدرسه در این بود که سرویس مدرسهی ما صبح روزهای تعطیل کار میکرد. یادش به خیر!
متن پیام:
مهندس مهرداد گل سلام..
کمی قبل داشتم نوشته هاتون رو میخوندم.. از گرمای هوا و به افتخار هانیه.
روز قبل وارد ۳۸ سالگیم شدم. هر از چند گاهی فکر میکنم به این راهی که توی این سالها رفتم و سفر زندگی خودم و برخی دوستانم رو مرور میکنم.
اگه میتونستم برگردم عقب و به […] ۲۵ ساله یه پیغام بدم اون این بود که “کلا مهم نیست. زیاد زندگی رو، دلخوریها رو، شکستها و موفقیتها رو جدی نگیر“.
اگه بر میگشتم عقب، به جای اینکه به این فکر کنم که کی کار […] تموم میشه، بیشتر سعی میکردم از دورهمیهامون توی پراید […] لذت ببرم. به جای اینکه به موفقیت محض و کار کردن توی بهترین شرکتها تمرکز کنم، بیشتر سعی میکردم از تکتک لحظههای با هم بودنمون لذت ببرم.
بیشتر سعی میکردم از حال و هوای صبحونهای مادرم و نونی که پدرم میخرید لذت ببرم.
تخته وایت برد هانیه رو دیدم و یادم افتاد اون وقتها چند تا از این نمودارهای بازدهی کشیده بودم. اگه عقب بر میگشتم سعی میکردم بیشتر لحظات سادهتر رو زندگی کنم.
مهندس جان دارم شهرم رو عوض کنم و جا به جا میشم.
میرم به یه شهر دیگه.. یه شهر آرومتر هست. اینجا […] مثل نیویورک میمونه. قلب قاره […]. همه در حال رقابت و در حال رسیدن به هدفها. یه شهر ایدهآل برای آدمی مثل من.
چند ماه قبل فرصتی پیش اومد که برم به یه شهر شمالی. جایی که از این رقابتها خبری نیست. دیدم ای بابا، زندگی جریان داره بدون رقابت، بدون هوش مصنوعی، بدون دویدن دنبال هدفهای بزرگ، بدون کار کردن توی بزرگترین شرکتهای دنیا. هیچ کم و کسری هم نیست. مردم […] خواب ندارن. در واقع مشکل خواب دارن. استرس دارن. فقط و فقط واسه اینکه شب میخوابن با هدف اینکه فردا برن و یه هدف دیگر رو هم بزنن.
به سماموس فکر کن. مردم زندگی میکنن، هیچ کم و کسری هم ندارن بدون هوش مصنوعی و داشتن ۱۰۰ هدف. واسه همین تصمیم گرفتم برم به یه شهر آرامتر.
گزیده:
هرچه از عمرتان بیشتر میگذرد، کمتر تلاش میکنید تا ثابت کنید فرد خوبی هستید. والا افشار
نمونه آموزندهای از بازسازی کد
مقدمه: بازسازی کد
بازسازی کد یا refactoring، یک واژهی تخصصی است که معنی آن، بهبود کیفیت کد یک سیستم است بدون آن که تغییری در رفتار خارجی آن ایجاد شود. مشابه غیرافزاری بازسازی کد، بازسازی داخلی یک خانه است که بدون آن نمای خارجی خانه دچار تغییر شود، اجزای داخلی آن مانند تاسیسات و چیدمان وسایل تغییر میکنند.
حالا اگر بهبود کیفیت کد منجر به خطاهای جدید یا تغییرات در رفتار سیستم گردد، آیا چنین کاری، بهبود یا بازسازی کد است؟ مسلما خیر! پاسخ این پرسش از این بابت اهمیت دارد که هر تغییری در کد، بازسازی محسوب نمیشود ولی بازسازی حتما با تغییر کد همراه است: هر گردی گردو نیست!
در بازسازی کد، بهترین رویکرد، اعمال تغییرات هدفمند و کوچک است. برعکس رویکرد ایجاد تغییرات بزرگ و گسترده، بازسازی کد اقدامی درازمدت و پیوسته است (آهسته و پیوسته). دلیل چنین رویکردی این است که اعمال یکبارهی تغییرات بزرگ و گسترده، موجب ریسک بیشتر و نیازمند زمان طولانیتری است.
رهرو آن نیست
که گه تند و گهی خسته رود
رهرو آن اسـت که آهستـــــه و پیـــوسته رود
بدیهی است که یکی از مزایای بازسازی کد این است که وقت گذاشتن پیشاپیش و تدریجی برای افزایش کیفیت کد باعث افزایش سرعت تیم در آینده میشود.
پرسش:
به تازگی، نمونهی آموزنده و جالبی از بازسازی کد خواندم که در اینجا با شما در میان میگذارم. ابتدا صورت پرسش را مطرح میکنم تا آن را بررسی نمایید.
آیا پیشنهادی برای بازسازی کد زیر دارید؟ قبل از ارائه پیشنهاد، چه پرسشهایی برای شما مطرح است؟ لطفا با پاسخهای پیشفرض خود، کد زیر را بازنویسی نمایید و اگر دوست داشتید آن را اینجا به اشتراک بگذارید.
if(user.role === "admin" && user.isActive && user.permissions.some(p => p === "edit")) {
// Do stuff
}حرف زدن که هزینه نداره، کدت رو نشون بده! 🙂
برایان کرنیگان
پ.ن.
شاید ترجمه بهتر این باشد: حرف زدن که مالیات نداره، کدت رو نشون بده!
شهرت برایان کرنیگان در کنار دنیس ریچی به دلیل کتاب معروف برنامهنویسی C است.
منبع کد: کتاب Refactoring TypeScript نوشتهی James Hickey
الگوی ایجاد نرمافزار: تجزیه – ترکیب!
پیشگفتار:
مدتی است که با خود میاندیشم تجربیاتم را در حوزهی نرمافزار در اینجا بنویسم، هم ماندگار خواهد شد و هم شاید به دوستی کمک کند. نمیدانم “الگوی ایجاد نرمافزار” عبارت مناسبی هست یا نه، ولی تا یافتن عبارت مناسبتر از آن استفاده خواهم کرد.
داستانی از عبید زاکانی:
گویند؛
روزی “مطربی” نزد “مرحوم کرباسی” که از علمای “عهد فتحعلی شاه” بود آمد و حکم شرع را در مورد “رقصیدن” پرسید.
کرباسی با عصبانیت جواب داد:
“عملی است مذموم و فعلی است حرام.”
مطرب پرسید: “حضرت آقا، اگر من دست راستم را بجنبانم حرام است؟”
مرحوم کرباسی گفت: “خیر!”
مطرب پرسید: “اگر دست چپم را بجنبانم؟!”
مرحوم کرباسی گفت: “خیر!”
سپس مطرب از “حکم شرعی” در مورد تکان دادن پای راست و چپ پرسید و هر بار مرحوم کرباسی گفتند: “خیر” ایرادی ندارد. اصولا دست و پا برای “جنبانده شدن” خلق گشته اند.
مطرب که منتظر این فرصت بود از جای خود بلند شد و در مقابل دیدگان بهت زده مرحوم کرباسی و حاضران مجلس “شروع به رقصیدن کرد” و گفت: “حضرت آقا، رقص همان تکان دادن دست ها و پاهاست که فرمودید حرام نیست.
مرحوم کرباسی در جواب گفت: “مفرداتش” خوب است…
ولی “مرده شوی ترکیبش را ببرد”
به این معنی که تک تک امور به تنهایی خوب هستند اما مجموعشان فعل حرام است و به درد نمی خورد.
منبع: اینجا
مفردات نرمافزاری:
یکی از روشهای حل مساله این است که مساله را به قسمتهای کوچکتری تقسیم کنید و بعد از حل هر قسمت که انتظار میرود پیچیدگی کمتری داشته باشد، از ترکیب راهکارها به پاسخ اصلی برسید. برای نمونه در طراحی الگوریتم، الگوریتم را به چند گام تقسیم میکنیم و هر یک از گامها را به تعدادی زیرگام. بعد از آن که جزییات هر زیرگام نهایی شد، آنها را با یک فرایند معکوس، سر هم میکنیم تا به الگوریتم نهایی دست پیدا کنیم. مثلا برای تولید و چاپ اعداد اول (به گونهای که چاپ آنها نیز بر مبنای یک الگوی خاص باشد)، مساله را به دو گام تولید اعداد اول و چاپ اعداد تولیدشده تقسیم میکنیم. بعد از حل هر دو گام، از سر هم شدن آنها، کل مساله حل میشود. در این شرایط هر بخش پاسخ ما به تنهایی فوقالعاده است و به خوبی کار میکند.
بعضی اوقات نیز به ناچار هر گام از مساله با یک تکنولوژی خاص انجام میشود. مثلا شما برای ایجاد اعداد اول تصمیم میگیرید که از یک کتابخانه موجود استفاده کنید. همچنین فرض کنید که برای چاپ اعداد هم از کتابخانهی دیگری استفاده مینمایید. دو گام/بخش راهکار شما به صورت جداگانه به خوبی کار میکنند.
ترکیبهای نرمافزاری:
نکته اینجاست که وقتی پاسخ تکتک اجزا (گامهای الگوریتم یا زیربخشها) را پیدا میکنید، هنگام سرهمبندی این اجزا با این واقعیت مواجه میشوید که این راهکارها قابل تجمیع در یک راهکار جامع و اصلی نیستند. به عبارت دیگر فرایند تجمیع که فرایندِ عکس فرایند تجزیه است، وقتی روی زیرراهکارها پیاده میشود، یا انجامپذیر نیست و یا در صورت انجامپذیری، موجود تجمیعشده پاسخ مسالهی اصلی نیست. این اتفاق به ویژه وقتی گامها/اجزا با تکنولوژیهای متفاوت و به صورت جداگانه پیش برده میشوند، بسیار بیشتر به چشم میخورد.
اینجاست که عبید زاکانی جلوی شما ظاهر میشود و با صدای بلند برایتان میخواند: تجزیهاش خوب بود، ولی مردهشور ترکیبش را ببرد!
برای این که ذهنمان به هم نزدیک شود اجازه بدهید مثالی بیان کنم. نمیدانم تا حالا رادیو یا ضبط یا کامپیوترهای قدیمی را باز کردهاید یا خیر. یکی از بستگان جوان ما عادت داشت که وقتی رادیوی خانهشان خراب میشد، آن را با آچار و پیچگوشتی باز میکرد و بعد از ساعتها کار مهندسی فشرده و طاقتفرسا 🙂 ، وقتی میخواست رادیو را دوباره سرهم کند یک سری قطعه و یک عالمه پیچ اضافه میآورد. به عبارت ساده فرایند سرهمبندی مطابق با فرایند جداسازی پیش نمیرفت. البته این فامیل ما همیشه میگفت که کارخانهی سازندهی رادیو این تجهیزات را به عنوان قطعات یدکی و اضافی در رادیو قرار داده است. 🙂
امیدوارم تجزیه و ترکیبهایتان فوقالعاده باشد.
گزیده:
یک برنامهنویس بد به راحتی میتواند دو شغل جدید در هر سال ایجاد کند. 🙂
دیوید پرناس
منبع عکس: گنجور





