فصل ۸ - پیش از پروژه
در همان سرآغاز یک پروژه، شما و تیمتان باید نیازمندیها را دریابید. صرفاً شنیدن اینکه چه کاری باید انجام دهید یا گوش سپردن به حرف کاربران کافی نیست: مبحث ۴۵، «گودال نیازمندیها» را بخوانید و بیاموزید که چطور از دامها و تلههای رایج دوری کنید.
خرد متعارف و مدیریت محدودیتها، موضوعات مبحث ۴۶، «حل معماهای ناممکن» هستند. چه در حال استخراج نیازمندیها باشید، چه تحلیل، کدنویسی یا تست، مشکلات دشواری سر بر خواهند آورد. در بیشتر مواقع، این مشکلات آنقدرها که در نگاه اول به نظر میرسند، سخت و پیچیده نیستند.
و زمانی که آن پروژه «ناممکن» پیش میآید، ما دوست داریم به سراغ سلاح مخفی خود برویم: مبحث ۴۷، «کار با یکدیگر». و منظور ما از «کار با یکدیگر» به اشتراک گذاشتن یک سند نیازمندیهای حجیم، پرتاب کردن ایمیلهایی با رونوشتهای (CC) فراوان به هم، یا تحمل جلسات بیپایان نیست. منظور ما حل مسائل در کنار هم و در حین کدنویسی است. ما به شما نشان خواهیم داد که به چه کسانی نیاز دارید و چگونه باید کار را شروع کنید.
با اینکه «بیانیه چابک» (Agile Manifesto) با عبارت «افراد و تعاملات، بالاتر از فرآیندها و ابزارها» آغاز میشود، تقریباً تمام پروژههای «چابک» با بحثی طعنهآمیز درباره اینکه از کدام فرآیند و کدام ابزارها استفاده کنند، شروع میشوند. اما مهم نیست آن روش چقدر خوب سنجیده شده باشد، و صرفنظر از اینکه شامل کدام «بهترین روشها» (Best Practices) باشد، هیچ متدی نمیتواند جایگزین تفکر شود. شما به هیچ فرآیند یا ابزار خاصی نیاز ندارید، آنچه واقعاً به آن نیاز دارید مبحث ۴۸، «جوهره چابکی» است.
با حلوفصل این مسائل حیاتی پیش از آنکه پروژه به جریان بیفتد، در موقعیت بهتری قرار خواهید گرفت تا از «فلج تحلیل» (Analysis Paralysis) اجتناب کنید و در عمل پروژه موفق خود را آغاز—و تکمیل—کنید.
مبحث ۴۵: گودال نیازمندیها
«کمال نه زمانی که چیزی برای افزودن نمانده، بلکه زمانی حاصل میشود که چیزی برای کم کردن نمانده باشد...»
— آنتوان دو سنت اگزوپری، زمین انسانها، ۱۹۳۹
بسیاری از کتابها و آموزشها به «جمعآوری نیازمندیها» (Requirements Gathering) به عنوان یکی از فازهای اولیه پروژه اشاره میکنند. کلمه «جمعآوری» ناخودآگاه تصویری از قبیلهای از تحلیلگران شاد را به ذهن میآورد که در حال جستوجوی تکههای خرد و دانش هستند که روی زمین ریخته شده، و در همین حین «سمفونی پاستورال» به آرامی در پسزمینه نواخته میشود. «جمعآوری» این حس را القا میکند که نیازمندیها از پیش آنجا وجود دارند—شما فقط باید پیدایشان کنید، در سبدتان بگذارید و شاد و خندان به راه خود ادامه دهید.
اما واقعیت به این شکل کار نمیکند. نیازمندیها به ندرت در سطح قرار دارند. معمولاً آنها در اعماق لایههایی از فرضیات، سوءبرداشتها و سیاستبازیها مدفون شدهاند. حتی بدتر از آن، اغلب اوقات آنها اصلاً وجود خارجی ندارند.
نکته ۷۵: هیچکس دقیقاً نمیداند چه میخواهد
افسانه نیازمندیها
در روزهای آغازین دنیای نرمافزار، رایانهها (از نظر هزینه مستهلکشده در ساعت) ارزشمندتر از آدمهایی بودند که با آنها کار میکردند. ما سعی میکردیم با درست انجام دادن کارها در همان بار اول، در پول صرفهجویی کنیم. بخشی از آن فرآیند، تلاش برای مشخص کردن دقیقِ کاری بود که قرار بود ماشین انجام دهد.
ما با گرفتن مشخصات (Specification) نیازمندیها شروع میکردیم، آن را به یک سند طراحی تبدیل میکردیم، سپس به فلوچارت و شبهکد (Pseudo code) و نهایتاً به کد تبدیل میشد. قبل از خوراندن آن به کامپیوتر، وقت زیادی را صرف «بررسی رومیزی» (Desk checking) و تست دستی آن میکردیم. این کار هزینه زیادی داشت. و این هزینه باعث میشد افراد فقط زمانی به سمت اتوماسیون بروند که دقیقاً میدانستند چه میخواهند.
چون ماشینهای اولیه نسبتاً محدود بودند، دامنه مشکلاتی که حل میکردند نیز محدود بود: واقعاً امکانپذیر بود که کل مسئله را پیش از شروع درک کرد.
اما آنجا دنیای واقعی نبود. دنیای واقعی درهمریخته، پر از تضاد و ناشناخته است. در این دنیا، مشخصات دقیق برای هر چیزی کمیاب است، اگر نگوییم غیرممکن. اینجاست که ما برنامهنویسان وارد میشویم. شغل ما این است که به مردم کمک کنیم بفهمند چه میخواهند. در واقع، این احتمالاً ارزشمندترین ویژگی ماست. و ارزش تکرار کردن را دارد:
نکته ۷۶: برنامهنویسان به افراد کمک میکنند تا بفهمند چه میخواهند
برنامهنویسی به مثابه رواندرمانی
بیایید کسانی را که از ما میخواهند نرمافزار بنویسیم، «مشتری» بنامیم. یک مشتری معمولی با یک «نیاز» نزد ما میآید. این نیاز ممکن است استراتژیک باشد، اما به همان اندازه محتمل است که یک مسئله تاکتیکی باشد: پاسخی به یک مشکل فعلی. نیاز ممکن است درخواست تغییر در سیستم موجود باشد یا درخواست چیزی کاملاً جدید. نیاز گاهی به زبان تجاری بیان میشود و گاهی به زبان فنی.
اشتباهی که توسعهدهندگان تازهکار اغلب مرتکب میشوند این است که این «بیانِ نیاز» را میگیرند و راهحلی برای آن پیادهسازی میکنند. طبق تجربه ما، این بیان اولیه نیاز، یک نیازمندی مطلق نیست. شاید مشتری متوجه نباشد، اما این در واقع دعوتی است برای کاوش و بررسی.
بیایید یک مثال ساده بزنیم. شما برای ناشری کار میکنید که کتابهای کاغذی و الکترونیکی میفروشد. یک نیازمندی جدید به شما داده میشود:
«ارسال پستی برای تمام سفارشهایی که ۵۰ دلار یا بیشتر هزینه دارند، باید رایگان باشد.»
یک لحظه صبر کنید و خودتان را در آن موقعیت تصور کنید. اولین چیزی که به ذهنتان میرسد چیست؟
احتمال خیلی زیاد سوالاتی دارید: آیا ۵۰ دلار شامل مالیات میشود؟ آیا شامل هزینه ارسال فعلی میشود؟ آیا ۵۰ دلار باید فقط برای کتابهای کاغذی باشد یا سفارش میتواند شامل کتاب الکترونیکی هم باشد؟ چه نوع ارسالی مد نظر است؟ پیشتاز؟ عادی؟ سفارشهای بینالمللی چطور؟ این سقف ۵۰ دلار در آینده چقدر تغییر خواهد کرد؟
این کاری است که ما انجام میدهیم. وقتی چیزی به نظر ساده میرسد، ما با گشتن به دنبال «حالتهای مرزی» (Edge cases) و پرسیدن درباره آنها، مردم را کلافه میکنیم.
احتمالاً مشتری به برخی از این موارد فکر کرده و فرض را بر این گذاشته که پیادهسازی طبیعتاً به همان شکل کار خواهد کرد. پرسیدن این سوالات فقط آن اطلاعات را بیرون میکشد. اما سایر سوالات احتمالاً چیزهایی هستند که مشتری قبلاً در نظر نگرفته است. اینجاست که اوضاع جالب میشود و جایی است که یک توسعهدهنده خوب یاد میگیرد دیپلماتیک باشد.
شما: ما درباره آن جمع ۵۰ دلار سوال داشتیم. آیا شامل هزینهای که معمولاً برای ارسال میگیریم هم میشود؟
مشتری: البته. این کل مبلغی است که آنها به ما میپردازند.
شما: این برای مشتریان ما ساده و قابل درک است؛ جذابیتش را میبینم. اما میتوانم ببینم که برخی مشتریانِ کمتر صادق سعی کنند سیستم را دور بزنند.
مشتری: چطور؟
شما: خب، فرض کنیم آنها یک کتاب ۲۵ دلاری میخرند و سپس ارسال یکروزه (Overnight) را انتخاب میکنند که گرانترین گزینه است. احتمالاً هزینه ارسال حدود ۳۰ دلار میشود و کل سفارش ۵۵ دلار. آنوقت ما ارسال را رایگان میکنیم و آنها عملاً برای یک کتاب ۲۵ دلاری، ارسال یکروزه رایگان میگیرند و فقط ۲۵ دلار میپردازند.
(در این نقطه توسعهدهنده باتجربه مکث میکند. حقایق را تحویل دهید و بگذارید مشتری تصمیم بگیرد.)
مشتری: اوخ (Ouch). قطعاً قصد من این نبود؛ ما روی آن سفارشها ضرر میکنیم. گزینهها چیست؟
و این سرآغاز یک اکتشاف است. نقش شما در اینجا تفسیر گفتههای مشتری و بازخورد دادن پیامدهای آن به آنهاست. این هم یک فرآیند فکری است و هم خلاقانه: شما فیالبداهه فکر میکنید و در راهحلی مشارکت میکنید که احتمالاً بهتر از راهحلی است که شما یا مشتری به تنهایی ارائه میدادید.
نیازمندیها یک فرآیند هستند
در مثال بالا، توسعهدهنده نیازمندیها را گرفت و یک پیامد (Consequence) را به مشتری بازخورد داد. این کار کاوش را آغاز کرد. در طول آن کاوش، همانطور که مشتری با راهحلهای مختلف بازی میکند، احتمالاً شما بازخوردهای بیشتری ارائه خواهید داد. این واقعیتِ تمامِ جمعآوریهای نیازمندی است:
نکته ۷۷: نیازمندیها در یک حلقه بازخورد آموخته میشوند
شغل شما این است که به مشتری کمک کنید پیامدهای نیازمندیهای بیانشدهشان را درک کنند. شما این کار را با تولید بازخورد و اجازه دادن به آنها برای استفاده از آن بازخورد جهت پالایش تفکرشان انجام میدهید.
در مثال قبلی، بیان بازخورد با کلمات آسان بود. گاهی اینطور نیست. و گاهی شما واقعاً دانش کافی از دامنه (Domain) مسئله ندارید تا آنقدر دقیق باشید. در این موارد، «برنامهنویسان عملگرا» (Pragmatic Programmers) به مکتبِ بازخوردِ «آیا منظورت این بود؟» تکیه میکنند. ما ماکآپها (Mockups) و پروتوتایپهایی میسازیم و اجازه میدهیم مشتری با آنها بازی کند. در حالت ایدهآل، چیزهایی که میسازیم آنقدر منعطف هستند که میتوانیم در حین بحث با مشتری آنها را تغییر دهیم و به جمله «این منظورم نبود» با پاسخ «پس بیشتر شبیه این؟» واکنش نشان دهیم.
گاهی این ماکآپها میتوانند در عرض یک ساعت یا بیشتر سرهمبندی شوند. آنها مشخصاً فقط کدهای هکی (Hack) هستند برای انتقال یک ایده. اما واقعیت این است که تمام کارهایی که ما انجام میدهیم در واقع نوعی ماکآپ است. حتی در پایان یک پروژه ما هنوز در حال تفسیرِ خواسته مشتری هستیم. در واقع، تا آن زمان احتمالاً مشتریان بیشتری داریم: افراد تضمین کیفیت (QA)، عملیات، بازاریابی و شاید حتی گروههای تست از مشتریان نهایی.
بنابراین برنامهنویس عملگرا به کل پروژه به چشم یک تمرین جمعآوری نیازمندیها نگاه میکند. به همین دلیل است که ما تکرارهای (Iterations) کوتاه را ترجیح میدهیم؛ تکرارهایی که با بازخورد مستقیم مشتری به پایان میرسند. این ما را در مسیر درست نگه میدارد و تضمین میکند که اگر در جهت اشتباه رفتیم، مقدار زمان از دست رفته به حداقل برسد.
در کفشهای مشتریتان راه بروید
یک تکنیک ساده برای نفوذ به ذهن مشتریانتان وجود دارد که به اندازه کافی استفاده نمیشود: مشتری شوید.
آیا سیستمی برای «هِلپ دِسک» (Help desk) مینویسید؟ چند روز را صرف نظارت بر تلفنها در کنار یک پشتیبان باتجربه کنید. آیا دارید یک سیستم کنترل موجودی دستی را اتوماتیک میکنید؟ یک هفته در انبار کار کنید.
علاوه بر اینکه بینشی درباره نحوه استفاده واقعی از سیستم به شما میدهد، تعجب خواهید کرد که درخواست «میتوانم یک هفته جای شما بنشینم در حالی که کارتان را انجام میدهید؟» چقدر به ایجاد اعتماد و پایهگذاری ارتباط با مشتریانتان کمک میکند. فقط یادتان باشد سر راهشان نباشید!
نکته ۷۸: با کاربر کار کنید تا مثل کاربر فکر کنید
جمعآوری بازخورد همچنین زمانی است برای شروع ایجاد رابطه با پایگاه مشتریانتان و یادگیری انتظارات و امیدهایشان برای سیستمی که میسازید. برای اطلاعات بیشتر، مبحث ۵۲، «کاربرانتان را خوشحال کنید» را ببینید.
نیازمندیها در برابر سیاستگذاری (Policy)
بیایید تصور کنیم در حال بحث درباره یک سیستم منابع انسانی (HR)، مشتری میگوید: «فقط سرپرستهای کارمند و دپارتمان پرسنلی میتوانند سوابق آن کارمند را مشاهده کنند.»
آیا این جمله واقعاً یک نیازمندی است؟ شاید امروز باشد، اما یک «سیاست تجاری» (Business Policy) را در یک جمله مطلق تعبیه کرده است. سیاست تجاری؟ نیازمندی؟ این تمایزی نسبتاً ظریف است، اما پیامدهای عمیقی برای توسعهدهندگان دارد. اگر نیازمندی به صورت «فقط سرپرستان و پرسنلی میتوانند سوابق کارمند را ببینند» بیان شود، توسعهدهنده ممکن است هر بار که اپلیکیشن به این داده دسترسی پیدا میکند، یک کد تست صریح بنویسد.
اما، اگر جمله این باشد که «فقط کاربران مجاز میتوانند به سوابق کارمند دسترسی داشته باشند»، توسعهدهنده احتمالاً نوعی سیستم کنترل دسترسی طراحی و پیادهسازی خواهد کرد. وقتی سیاست تغییر کند (که خواهد کرد)، فقط متادیتا (Metadata) برای آن سیستم نیاز به بهروزرسانی دارد. در واقع، جمعآوری نیازمندیها به این روش، طبیعتاً شما را به سمت سیستمی هدایت میکند که به خوبی برای پشتیبانی از متادیتا فاکتورگیری شده است. در اینجا یک قانون کلی وجود دارد:
سیاستگذاری، متادیتا است
نکته ۷۹: حالت کلی را پیادهسازی کنید، و اطلاعاتِ سیاستگذاری را صرفاً به عنوان مثالی از نوع چیزی که سیستم باید پشتیبانی کند در نظر بگیرید.
نیازمندیها در برابر واقعیت
در مقالهای در مجله Wired (ژانویه ۱۹۹۹)، تهیهکننده و موسیقیدان، برایان اینو (Brian Eno)، یک تکه تکنولوژی باورنکردنی را توصیف کرد: میزِ میکسِ نهایی. این دستگاه هر کاری را که میشد با صدا انجام داد، انجام میداد. و با این حال، به جای اینکه به موسیقیدانان اجازه دهد موسیقی بهتری بسازند یا ضبط را سریعتر یا ارزانتر انجام دهند، سد راه میشد؛ فرآیند خلاقیت را مختل میکرد.
برای فهمیدن دلیلش، باید به نحوه کار مهندسان ضبط نگاه کنید. آنها صداها را به صورت شهودی متعادل میکنند. در طول سالها، آنها یک حلقه بازخورد ذاتی بین گوشها و نوک انگشتانشان ایجاد میکنند—لغزاندن فیدرها، چرخاندن پیچها و غیره.
اما رابط کاربری میکسر جدید از آن تواناییها بهره نمیبرد. در عوض، کاربرانش را مجبور میکرد روی کیبورد تایپ کنند یا با ماوس کلیک کنند. عملکردهایی که ارائه میداد جامع بودند، اما به روشهای ناآشنا و عجیب بستهبندی شده بودند. عملکردهایی که مهندسان نیاز داشتند گاهی پشت نامهای مبهم پنهان شده بودند، یا با ترکیبات غیرشهودی از امکانات اولیه به دست میآمدند.
این مثال همچنین باور ما را نشان میدهد که ابزارهای موفق با دستهایی که از آنها استفاده میکنند منطبق میشوند. جمعآوری موفق نیازمندیها این را در نظر میگیرد. و به همین دلیل است که بازخورد اولیه، با پروتوتایپها یا «گلولههای رسام» (Tracer Bullets)، به مشتریانتان اجازه میدهد بگویند: «بله، کاری که میخواهم را انجام میدهد، اما نه آنطور که من میخواهم.»
مستندسازی نیازمندیها
ما معتقدیم که بهترین مستندات نیازمندیها، و شاید تنها مستندات نیازمندیها، کدِ در حال کار است. اما این بدان معنا نیست که میتوانید بدون مستند کردن درک خود از خواسته مشتری قسر در بروید. فقط به این معنی است که آن اسناد یک «خروجی تحویلدادنی» (Deliverable) نیستند: چیزی نیستند که به مشتری بدهید تا امضا و تایید کند. در عوض، آنها صرفاً نقاط نشانهگذاری (Mileposts) برای کمک به هدایت فرآیند پیادهسازی هستند.
اسناد نیازمندیها برای مشتریان نیستند
در گذشته، هم اندی و هم دیو در پروژههایی بودهاند که نیازمندیهای با جزئیات باورنکردنی تولید میکردند. این اسناد قطور، توضیحات اولیه دو دقیقهای مشتری را بسط میدادند و شاهکارهایی به ضخامت چند اینچ پر از نمودار و جدول تولید میکردند. چیزها تا حدی مشخص میشدند که تقریباً هیچ جایی برای ابهام در پیادهسازی باقی نمیماند. با ابزارهای به اندازه کافی قدرتمند، آن سند میتوانست در واقع همان برنامه نهایی باشد.
ایجاد این اسناد به دو دلیل اشتباه بود. اول، همانطور که بحث کردیم، مشتری واقعاً از قبل نمیداند چه میخواهد. بنابراین وقتی ما حرفهای آنها را میگیریم و به چیزی که تقریباً یک سند حقوقی است بسط میدهیم، داریم قلعهای فوقالعاده پیچیده روی ماسه روان میسازیم.
ممکن است بگویید «اما بعد ما سند را پیش مشتری میبریم و آنها امضایش میکنند. ما داریم بازخورد میگیریم.» و این ما را به مشکل دوم با این مشخصاتِ نیازمندی میرساند: مشتری هرگز آنها را نمیخواند.
مشتری از برنامهنویسان استفاده میکند چون، در حالی که مشتری با انگیزه حل یک مشکل سطح بالا و تا حدودی مبهم حرکت میکند، برنامهنویسان به تمام جزئیات و ظرایف علاقهمندند. سند نیازمندیها برای توسعهدهندگان نوشته شده و حاوی اطلاعات و ظرایفی است که گاهی برای مشتری غیرقابل درک و غالباً خستهکننده است. یک سند نیازمندی ۲۰۰ صفحهای ارائه دهید؛ مشتری احتمالاً آن را در دست سنگینوسبک میکند تا تصمیم بگیرد آیا وزنش برای مهم بودن کافی است یا نه، شاید یکی دو پاراگراف اول را بخواند (به همین دلیل است که دو پاراگراف اول همیشه «خلاصه مدیریتی» نامیده میشوند)، و ممکن است بقیه را ورق بزند، و گاهی وقتی نمودار تمیزی میبیند مکث کند.
این تحقیر مشتری نیست. اما دادن یک سند فنی بزرگ به آنها مثل این است که به یک توسعهدهنده معمولی نسخهای از ایلیاد به زبان یونانی هومری بدهید و از او بخواهید بازی ویدیوییاش را از روی آن کدنویسی کند.
اسناد نیازمندیها برای برنامهریزی هستند
بنابراین ما به سند نیازمندیهای یکپارچه و «آنقدر سنگین که یک گاو نر را از پا درآورد» اعتقادی نداریم. با این حال، میدانیم که نیازمندیها باید نوشته شوند، صرفاً به این دلیل که توسعهدهندگان تیم باید بدانند چه کاری انجام خواهند داد.
این به چه شکلی است؟ ما چیزی را ترجیح میدهیم که بتواند روی یک کارت نمایه (Index card) واقعی (یا مجازی) جا شود. این توضیحات کوتاه اغلب «داستانهای کاربر» (User Stories) نامیده میشوند. آنها توصیف میکنند که بخش کوچکی از برنامه از دیدگاه کاربرِ آن عملکرد، چه کاری باید انجام دهد. وقتی به این روش نوشته شوند، نیازمندیها میتوانند روی یک تخته قرار گیرند و جابهجا شوند تا وضعیت و اولویت را نشان دهند.
ممکن است فکر کنید یک کارت نمایه نمیتواند اطلاعات مورد نیاز برای پیادهسازی یک جزء از برنامه را در خود جای دهد. حق با شماست. و این بخشی از نکته ماجراست. با کوتاه نگه داشتن این بیانِ نیازمندیها، شما توسعهدهندگان را تشویق میکنید که سوالات شفافسازی بپرسند. شما فرآیند بازخورد بین مشتریان و کدنویسان را قبل و در حین ایجاد هر قطعه کد تقویت میکنید.
توصیف بیش از حد (Overspecification)
خطر بزرگ دیگر در تولید سند نیازمندی، بیش از حد دقیق بودن است. نیازمندیهای خوب، انتزاعی (Abstract) هستند. در جایی که پای نیازمندیها در میان است، سادهترین بیانی که به درستی نیاز تجاری را منعکس کند، بهترین است. این بدان معنا نیست که میتوانید مبهم باشید—باید «ثابتهای معنایی» (Semantic Invariants) زیربنایی را به عنوان نیازمندی ثبت کنید، و شیوههای کاری خاص یا فعلی را به عنوان «سیاستگذاری» مستند کنید.
نیازمندیها معماری نیستند. نیازمندیها طراحی نیستند، و رابط کاربری هم نیستند. نیازمندیها، نیاز هستند.
فقط یک قرص نعنای نازک دیگر...
بسیاری از شکستهای پروژه به گردن افزایش دامنه (Scope) انداخته میشوند—که به نامهای باد کردن ویژگیها (Feature bloat)، خزش ویژگیها یا خزش نیازمندیها (Requirements creep) نیز شناخته میشود. این جنبهای از سندرم قورباغه آبپز از مبحث ۴، «سوپ سنگ و قورباغههای آبپز» است.
چه کار میتوانیم بکنیم تا جلوی خزیدن نیازمندیها به سمت خودمان را بگیریم؟ پاسخ (دوباره) بازخورد است.
اگر با مشتری در تکرارها (Iterations) و با بازخورد مداوم کار میکنید، آنگاه مشتری تأثیرِ «فقط یک ویژگی دیگر» را دست اول تجربه خواهد کرد. آنها خواهند دید که یک کارت داستان دیگر روی تخته میرود، و مجبور خواهند شد برای باز کردن جا، کارت دیگری را برای انتقال به تکرار بعدی انتخاب کنند. بازخورد دوطرفه عمل میکند.
یک واژهنامه (Glossary) نگه دارید
به محض اینکه شروع به بحث درباره نیازمندیها میکنید، کاربران و کارشناسان دامنه از اصطلاحات خاصی استفاده خواهند کرد که معنی مشخصی برای آنها دارد. مثلاً ممکن است بین «مشتری» (Client) و «خریدار» (Customer) تمایز قائل شوند. در این صورت استفاده سرسری از هر کدام از این کلمات در سیستم نامناسب خواهد بود.
یک واژهنامه پروژه ایجاد و نگهداری کنید—یک مکان واحد که تمام اصطلاحات و واژگان خاص استفاده شده در پروژه را تعریف میکند. تمام شرکتکنندگان در پروژه، از کاربران نهایی تا کارکنان پشتیبانی، باید از واژهنامه استفاده کنند تا یکپارچگی تضمین شود. این یعنی واژهنامه باید به طور گسترده در دسترس باشد—استدلالی خوب برای مستندات آنلاین.
نکته ۸۰: از یک واژهنامه پروژه استفاده کنید
موفقیت در یک پروژه سخت است اگر کاربران و توسعهدهندگان یک چیز واحد را با نامهای مختلف صدا بزنند یا بدتر از آن، به چیزهای مختلف با یک نام واحد اشاره کنند.
تمرینها
تمرین ۳۳: کدامیک از موارد زیر احتمالاً نیازمندیهای واقعی هستند؟ آنهایی را که نیستند (در صورت امکان) بازنویسی کنید تا مفیدتر شوند.
۱. زمان پاسخگویی باید کمتر از ۵۰۰ میلیثانیه باشد.
۲. پنجرههای مودال (Modal) باید پسزمینه خاکستری داشته باشند.
۳. برنامه باید به صورت تعدادی فرآیند فرانتاند و یک سرور بکاند سازماندهی شود.
۴. اگر کاربر کاراکترهای غیرعددی در یک فیلد عددی وارد کرد، سیستم باید پسزمینه فیلد را چشمکزن کند و آنها را نپذیرد.
۵. کد و داده برای این اپلیکیشن نهفته (Embedded) باید در ۳۲ مگابایت جا شود.
چالشها
آیا میتوانید از نرمافزاری که مینویسید استفاده کنید؟ آیا ممکن است بدون اینکه قادر به استفاده از نرمافزار باشید، حس خوبی نسبت به نیازمندیها داشته باشید؟
یک مشکل غیرکامپیوتری را که هماکنون نیاز به حل آن دارید انتخاب کنید. نیازمندیهایی برای یک راهحل غیرکامپیوتری تولید کنید.
مبحث ۴۶: حل معماهای ناممکن
گوردیوس، پادشاه فریگیه، زمانی گرهی زد که هیچکس نمیتوانست بازش کند. گفته میشد هر کس معمای «گره گوردی» (Gordian Knot) را حل کند، فرمانروای تمام آسیا خواهد شد. تا اینکه اسکندر مقدونی از راه میرسد و با شمشیرش گره را تکهتکه میکند. فقط یک تفسیر کمی متفاوت از نیازمندیها، همین... و او در نهایت فرمانروای بخش بزرگی از آسیا شد.
هر از گاهی، خود را وسط پروژهای مییابید که در آن گیر افتادهاید و یک معمای واقعاً سخت پیش میآید: تکهای از مهندسی که اصلاً نمیتوانید از آن سر در بیاورید، یا شاید قطعه کدی که نوشتنش بسیار سختتر از آن چیزی شده که فکر میکردید. شاید غیرممکن به نظر برسد. اما آیا واقعاً همانقدر که به نظر میرسد سخت است؟
به معماهای دنیای واقعی فکر کنید—آن قطعات کوچک و بدقلقِ چوبی، فلزی یا پلاستیکی که معمولاً به عنوان کادوی کریسمس یا در حراجهای خانگی پیدا میشوند. تنها کاری که باید بکنید این است که حلقه را خارج کنید، یا قطعات T شکل را در جعبه جا دهید، یا هر چیز دیگر. پس شما حلقه را میکشید، یا سعی میکنید Tها را در جعبه بگذارید، و به سرعت درمییابید که راهحلهای بدیهی اصلاً کار نمیکنند. معما را نمیتوان از آن روش حل کرد.
اما با اینکه این موضوع بدیهی است، باز هم جلوی تلاش مکررِ آدمها برای انجام همان کار قبلی را نمیگیرد—با این فکر که حتماً راهی وجود دارد. البته که راهی (از آن طریق) وجود ندارد. راهحل در جای دیگری نهفته است.
راز حل معما، شناسایی محدودیتهای واقعی (و نه خیالی) و یافتن راهحل در درون آنهاست. برخی محدودیتها مطلق هستند؛ برخی دیگر صرفاً تصورات از پیش شکلگرفتهاند. محدودیتهای مطلق باید محترم شمرده شوند، هرچقدر هم که ناخوشایند یا احمقانه به نظر برسند. از طرف دیگر، همانطور که اسکندر ثابت کرد، برخی محدودیتهای ظاهری ممکن است اصلاً محدودیت واقعی نباشند. بسیاری از مشکلات نرمافزاری هم میتوانند به همین اندازه آبزیرکاه باشند.
درجات آزادی
عبارتِ رایج و دهنپرکنِ «تفکر خارج از جعبه» (Thinking outside the box) ما را تشویق میکند که محدودیتهایی را که ممکن است قابل اجرا نباشند تشخیص دهیم و آنها را نادیده بگیریم. اما این عبارت کاملاً دقیق نیست.
اگر «جعبه» همان مرزِ محدودیتها و شرایط باشد، پس ترفند اصلی پیدا کردن جعبه است؛ جعبهای که ممکن است بسیار بزرگتر از آن چیزی باشد که فکر میکنید. کلید حل معماها، هم شناختن محدودیتهای تحمیلشده بر شماست و هم شناختن درجات آزادی که در اختیار دارید، زیرا راهحل شما در همانها نهفته است. به همین دلیل است که برخی معماها تا این حد مؤثرند؛ چون شما راهحلهای بالقوه را خیلی زود رد میکنید.
برای مثال، آیا میتوانید تمام نقاط پازل زیر را تنها با سه خط صاف به هم وصل کنید و به نقطه شروع برگردید—بدون اینکه قلم خود را از روی کاغذ بردارید یا از روی خطوط خود دوباره عبور کنید؟ (اشاره به معمای ریاضی و بازیها [Hol92])
شما باید هرگونه تصورات از پیش شکلگرفته را به چالش بکشید و ارزیابی کنید که آیا آنها محدودیتهای واقعی و سفتوسخت هستند یا خیر. مسئله این نیست که داخل جعبه فکر میکنید یا خارج از آن. مسئله در پیدا کردن جعبه نهفته است—شناسایی محدودیتهای واقعی.
نکته ۸۱: خارج از جعبه فکر نکنید—جعبه را پیدا کنید
وقتی با مشکلی سرسخت و حلنشدنی روبرو میشوید، تمام مسیرهای ممکنی که پیش رو دارید را لیست کنید. هیچچیز را رد نکنید، مهم نیست چقدر غیرقابل استفاده یا احمقانه به نظر برسد. حالا لیست را مرور کنید و توضیح دهید چرا یک مسیر خاص نمیتواند طی شود. آیا مطمئن هستید؟ میتوانید ثابتش کنید؟
به «اسب تروا» فکر کنید—یک راهحل نوآورانه برای یک مشکل حلنشدنی. چطور نیروها را بدون دیده شدن وارد یک شهر دیوارکشی شده میکنید؟ میتوانید شرط ببندید که «از طریق دروازه جلویی» در ابتدا به عنوان خودکشی رد شده بود.
محدودیتهایتان را دستهبندی و اولویتبندی کنید. وقتی نجارها پروژهای را شروع میکنند، اول بلندترین قطعات را میبرند، سپس قطعات کوچکتر را از چوب باقیمانده درمیآورند. به همین شیوه، ما میخواهیم اول محدودکنندهترین محدودیتها را شناسایی کنیم و بقیه محدودیتها را درون آنها جای دهیم.
(راستی، راهحل معمای «چهار ستون» در انتهای کتاب آمده است.)
از سر راه خودتان کنار بروید!
گاهی اوقات خود را در حال کار روی مشکلی مییابید که بسیار سختتر از چیزی که باید باشد به نظر میرسد. شاید احساس میکنید در مسیر اشتباهی میروید—که حتماً راه آسانتری از این وجود دارد! شاید الان از برنامه زمانبندی عقب افتادهاید، یا حتی از اینکه سیستم اصلاً کار کند ناامید شدهاید، چون این مشکل خاص «غیرممکن» است.
این زمانی ایدهآل است برای اینکه مدتی کار دیگری انجام دهید. روی چیز متفاوتی کار کنید. بروید سگتان را بگردانید. بگذارید برای فردا (Sleep on it). مغز خودآگاه شما از مشکل آگاه است، اما مغز خودآگاه شما واقعاً کمی خنگ است (جسارت نباشد). پس وقت آن است که به مغز واقعیتان، آن شبکه عصبی تداعیگر شگفتانگیز که زیر خودآگاهی شما کمین کرده، کمی فضا بدهید. شگفتزده خواهید شد که چقدر پیش میآید وقتی عمداً حواس خودتان را پرت میکنید، پاسخ ناگهان به ذهنتان خطور میکند.
اگر این برایتان بیش از حد عرفانی به نظر میرسد، اینطور نیست. نشریه Psychology Today گزارش میدهد: [۷۲]
ساده بگوییم—افرادی که حواسشان پرت شده بود در یک وظیفه حل مسئله پیچیده، بهتر از افرادی عمل کردند که تلاش آگاهانه به خرج دادند.
اگر هنوز مایل نیستید مشکل را برای مدتی رها کنید، بهترین کارِ بعدی احتمالاً پیدا کردن کسی است که مسئله را برایش توضیح دهید. اغلب، حواسپرتیِ ناشی از صرفاً حرف زدن درباره آن، شما را به سمت روشنگری هدایت میکند. از آنها بخواهید سوالاتی از شما بپرسند، مثل:
- چرا داری این مشکل را حل میکنی؟
- فایده حل کردنش چیست؟
- آیا مشکلاتی که داری مربوط به حالتهای مرزی (Edge cases) است؟ میتوانی حذفشان کنی؟
- آیا مشکل سادهتر و مرتبطی هست که بتوانی آن را حل کنی؟
این مثال دیگری از تکنیک «اردک پلاستیکی» (Rubber Ducking) در عمل است.
بخت یارِ ذهن آماده است
نقل شده است که لویی پاستور گفته:
Dans les champs de l’observation le hasard ne favorise que les esprits préparés.
(در زمینه مشاهدات، بخت تنها یار ذهنهای آماده است.)
این در مورد حل مسئله نیز صدق میکند. برای اینکه آن لحظات «یافتم!» (Eureka!) را داشته باشید، مغز ناخودآگاه شما نیاز دارد مواد خام فراوانی داشته باشد؛ تجربیات قبلی که بتوانند در رسیدن به پاسخ کمک کنند.
یک راه عالی برای تغذیه مغزتان این است که حین انجام کار روزانه، به آن بازخورد بدهید که چه چیزی کار میکند و چه چیزی کار نمیکند. و ما روشی عالی برای انجام این کار با استفاده از «دفترچه یادداشت مهندسی» توصیف کردیم (مبحث ۲۲، دفترچههای یادداشت مهندسی).
و همیشه توصیهی روی جلد کتاب راهنمای مسافران کهکشان را به یاد داشته باشید: هول نکنید (DON’T PANIC).
بخشهای مرتبط شامل:
- مبحث ۵: نرمافزار به اندازه کافی خوب
- مبحث ۳۷: به مغز مارمولکی خود گوش دهید
- مبحث ۴۵: گودال نیازمندیها
(اندی یک کتاب کامل درباره این جور چیزها نوشته است: تفکر و یادگیری: ریفکتور کردن مغز خیس (Wetware) [Hun08].)
چالشها
- نگاهی دقیق به هر مشکل دشواری که امروز درگیرش هستید بیندازید. آیا میتوانید گره کور (گوردی) را ببرید؟ آیا مجبورید این کار را به این روش انجام دهید؟ آیا اصلاً مجبورید این کار را انجام دهید؟
- آیا وقتی قرارداد پروژه فعلیتان را امضا کردید، مجموعهای از محدودیتها به دستتان داده شد؟ آیا همه آنها هنوز قابلاعمال هستند و آیا تفسیر آنها هنوز معتبر است؟
مبحث ۴۷: کار با یکدیگر
«من هرگز انسانی را ندیدهام که بخواهد ۱۷۰۰۰ صفحه مستندات را بخواند، و اگر چنین کسی وجود داشت، او را میکشتم تا از خزانه ژنی (Gene Pool) خارجش کنم.»
— جوزف کاستلو، رئیس شرکت کادنس
این یکی از آن پروژههای «ناممکن» بود؛ از آن نوعی که دربارهاش میشنوید و همزمان هم هیجانانگیز به نظر میرسد و هم ترسناک. یک سیستم باستانی به پایان عمرش نزدیک میشد، سختافزارش داشت فیزیکاً از بین میرفت، و یک سیستم کاملاً جدید باید ساخته میشد که رفتارهای (اغلب غیرمستند) سیستم قبلی را دقیقاً تکرار کند. صدها میلیون دلار از پول دیگران قرار بود از طریق این سیستم جابهجا شود، و ضربالاجل از لحظه شروع تا استقرار، در حد چند ماه بود.
و این جایی است که اندی و دیو اولین بار همدیگر را ملاقات کردند. یک پروژه ناممکن با یک ددلاین مضحک.
تنها یک چیز وجود داشت که آن پروژه را به یک موفقیت پرسروصدا تبدیل کرد. متخصصی که سالها این سیستم را مدیریت کرده بود، درست آنجا در دفترش نشسته بود، دقیقاً روبهروی اتاق توسعه ما که به اندازه یک کمد جارو بود. او دائماً برای سوالات، شفافسازیها، تصمیمگیریها و دموها در دسترس بود.
ما در سراسر این کتاب توصیه میکنیم که با کاربران از نزدیک کار کنید؛ آنها بخشی از تیم شما هستند. در آن اولین پروژه مشترک، ما چیزی را تمرین کردیم که اکنون ممکن است «برنامهنویسی دونفره» (Pair programming) یا «برنامهنویسی گروهی» (Mob programming) نامیده شود: یک نفر کد را تایپ میکند در حالی که یک یا چند عضو دیگر تیم نظر میدهند، تامل میکنند و مشکلات را با هم حل میکنند.
این یک روش قدرتمند برای همکاری است که فراتر از جلسات بیپایان، یادداشتهای اداری و مستندات حقوقیِ حجیمی میرود که ارزششان به وزنشان است نه به کاربردشان. و این دقیقاً منظور ما از «کار کردن با» است: نه فقط سوال پرسیدن، بحث کردن و یادداشتبرداری؛ بلکه سوال پرسیدن و بحث کردن در حالی که واقعاً دارید کد میزنید.
قانون کانوی (Conway's Law)
در سال ۱۹۶۷، ملوین کانوی ایدهای را در مقاله چگونه کمیتهها اختراع میکنند؟ [Con68] معرفی کرد که بعدها به قانون کانوی معروف شد:
سازمانهایی که سیستمها را طراحی میکنند، ناچارند طرحهایی تولید کنند که کپیهایی از ساختارهای ارتباطی همان سازمانها هستند.
یعنی ساختارهای اجتماعی و مسیرهای ارتباطی تیم و سازمان، در اپلیکیشن، وبسایت یا محصولی که توسعه مییابد بازتاب خواهد داشت. مطالعات مختلفی حمایت قوی از این ایده نشان دادهاند. ما بارها به چشم خود شاهد این ماجرا بودهایم—برای مثال، در تیمهایی که هیچکس با دیگری حرف نمیزند، نتیجه سیستمهای «سیلویی» و «دودکشی» (Stove-pipe) است. یا تیمهایی که به دو دسته تقسیم شدهاند، منجر به جدایی کلاینت/سرور یا فرانتاند/بکاند میشوند.
مطالعات همچنین از اصل معکوس پشتیبانی میکنند: شما میتوانید عمداً تیم خود را طوری ساختار دهید که میخواهید کدتان آنشکلی باشد. برای مثال، نشان داده شده است که تیمهای توزیعشده جغرافیایی به سمت نرمافزارهای ماژولارتر و توزیعشدهتر گرایش دارند.
اما مهمتر از همه، تیمهای توسعهای که شامل کاربران هستند، نرمافزاری تولید میکنند که به وضوح منعکسکننده آن مشارکت است، و تیمهایی که به خود زحمت نمیدهند نیز، همین بیتوجهی را منعکس خواهند کرد.
برنامهنویسی دونفره (Pair Programming)
برنامهنویسی دونفره یکی از روشهای «برنامهنویسی مفرط» (XP) است که خارج از خود XP نیز محبوب شده است. در برنامهنویسی دونفره، یک توسعهدهنده با صفحه کلید کار میکند و دیگری نه. هر دو با هم روی مسئله کار میکنند و میتوانند در صورت نیاز وظیفه تایپ کردن را جابهجا کنند.
برنامهنویسی دونفره مزایای زیادی دارد. افراد مختلف پیشزمینهها و تجربیات متفاوتی دارند، تکنیکها و رویکردهای حل مسئله متفاوتی دارند، و سطوح متفاوتی از تمرکز و توجه را به هر مسئله خاص میآورند.
توسعهدهندهای که نقش تایپیست را دارد باید روی جزئیات سطح پایین سینتکس و سبک کدنویسی تمرکز کند، در حالی که توسعهدهنده دیگر آزاد است تا مسائل سطح بالاتر و دامنه (Scope) کلی را در نظر بگیرد. شاید این تمایز کوچکی به نظر برسد، اما به یاد داشته باشید که ما انسانها «پهنای باند مغزی» محدودی داریم. کلنجار رفتن با تایپ کلمات و نمادهای عجیبوغریبی که کامپایلر با اکراه میپذیرد، بخش قابل توجهی از توان پردازشی ما را میگیرد. داشتن مغز کاملِ یک توسعهدهنده دوم در حین کار، توان ذهنی بسیار بیشتری را به میدان میآورد.
فشارِ نظیر-به-نظیر (Peer-pressure) ذاتیِ حضور نفر دوم، به جلوگیری از لحظات ضعف و عادتهای بدِ نامگذاری متغیرها به اسم foo و امثال آن کمک میکند. وقتی کسی فعالانه در حال تماشاست، شما کمتر تمایل دارید میانبرهای بالقوه خجالتآور بزنید، که این هم منجر به نرمافزاری با کیفیت بالاتر میشود.
برنامهنویسی گروهی (Mob Programming)
و اگر دو سر بهتر از یک سر است، نظرتان درباره داشتن دوجین آدم متنوع که همه همزمان روی یک مشکل کار میکنند، با یک تایپیست چیست؟
برنامهنویسی موب (گروهی)، با وجود نامش، شامل مشعل و چنگک (اشاره به شورشهای خیابانی) نیست. این گسترشیافتهی برنامهنویسی دونفره است که شامل بیش از دو توسعهدهنده میشود. طرفداران این روش نتایج عالی را در استفاده از «موب» برای حل مشکلات سخت گزارش میدهند. موبها میتوانند به راحتی شامل افرادی شوند که معمولاً بخشی از تیم توسعه در نظر گرفته نمیشوند، از جمله کاربران، حامیان مالی پروژه و تسترها.
در واقع، در اولین پروژه «ناممکن» مشترک ما، صحنهای رایج بود که یکی از ما تایپ میکرد در حالی که دیگری با کارشناس کسبوکارمان بحث میکرد. این یک موب کوچک سه نفره بود. میتوانید به برنامهنویسی موب به عنوان همکاری تنگاتنگ همراه با کدنویسی زنده (Live coding) نگاه کنید.
من باید چه کار کنم؟
اگر در حال حاضر فقط به صورت انفرادی (Solo) برنامهنویسی میکنید، شاید بد نباشد برنامهنویسی دونفره را امتحان کنید. حداقل دو هفته، هر بار فقط چند ساعت به آن فرصت دهید، چون در ابتدا حس عجیبی خواهد داشت.
برای طوفان فکری ایدههای جدید یا تشخیص عیبهای پیچیده (Diagnose)، شاید بد نباشد یک جلسه برنامهنویسی موب را امتحان کنید.
اگر همین الان هم جفت (Pair) یا موب (Mob) کار میکنید، چه کسانی شامل میشوند؟ آیا فقط توسعهدهندگان هستند، یا به اعضای تیم گستردهتر خود هم اجازه مشارکت میدهید: کاربران، تسترها، اسپانسرها...؟
و مثل تمام همکاریها، باید جنبههای انسانی آن را هم مثل جنبههای فنی مدیریت کنید. در اینجا چند نکته برای شروع آورده شده است:
- کد را بسازید، نه نَفستان را (Ego). مسئله این نیست که چه کسی باهوشتر است؛ همه ما لحظات خوب و بد خود را داریم.
- کوچک شروع کنید. موب را فقط با ۴-۵ نفر، یا با چند جفت، در جلسات کوتاه شروع کنید.
- از کد انتقاد کنید، نه از شخص. «بیایید به این بلوک نگاه کنیم» خیلی بهتر از «تو اشتباه میکنی» به گوش میرسد.
- گوش دهید و سعی کنید دیدگاههای دیگران را درک کنید. متفاوت بودن به معنی اشتباه بودن نیست.
- بازنگریهای (Retrospectives) مکرر برگزار کنید تا سعی کنید برای دفعه بعد بهتر شوید.
کدنویسی در یک دفتر یا از راه دور، به تنهایی، دوتایی یا گروهی، همگی روشهای موثری برای کار با یکدیگر جهت حل مشکلات هستند. اگر شما و تیمتان تا به حال فقط به یک روش کار کردهاید، ممکن است بخواهید سبک متفاوتی را آزمایش کنید.
اما همینطوری با رویکردی سادهلوحانه وسط ماجرا نپرید: برای هر کدام از این سبکهای توسعه، قوانین، پیشنهادات و دستورالعملهایی وجود دارد. برای مثال، در برنامهنویسی موب شما تایپیست را هر ۵ تا ۱۰ دقیقه عوض میکنید. کمی مطالعه و تحقیق کنید، هم از کتابهای درسی و هم از گزارشهای تجربی، و حسی نسبت به مزایا و دامهایی که ممکن است با آنها روبرو شوید پیدا کنید. شاید بخواهید با کدنویسی یک تمرین ساده شروع کنید، نه اینکه مستقیم بپرید وسط سختترین کدِ محصولتان.
اما هر طور که پیش میروید، اجازه دهید یک نصیحت نهایی بکنیم:
نکته ۸۲: تنها به دلِ کد نروید (Don’t Go into the Code Alone)
مبحث ۴۸: جوهره چابکی
«تو مدام از آن کلمه استفاده میکنی؛ فکر نمیکنم معنیش آن چیزی باشد که تو فکر میکنی.»
— اینیگو مونتویا، عروس شاهزاده
نکته ۸۳: چابک (Agile) یک صفت است: نحوه انجام کاری است.
شما میتوانید یک توسعهدهنده چابک باشید. میتوانید در تیمی باشید که شیوههای چابک را اتخاذ میکند؛ تیمی که با چابکی به تغییرات و شکستها پاسخ میدهد. چابکی سبکِ شماست، نه خودِ شما.
چابک اسم نیست؛ چابک نحوه انجام کارهاست [۷۳]
در حالی که این را مینویسیم، تقریباً ۲۰ سال پس از ظهور «بیانیه توسعه نرمافزار چابک» (Manifesto for Agile Software Development)، ما توسعهدهندگان بسیار بسیار زیادی را میبینیم که با موفقیت ارزشهای آن را به کار میگیرند. ما تیمهای فوقالعاده زیادی را میبینیم که راههایی پیدا میکنند تا این ارزشها را بگیرند و از آنها برای هدایت کارهایی که انجام میدهند، و نحوه تغییر کارهایی که انجام میدهند، استفاده کنند.
اما روی دیگر چابکی را هم میبینیم. تیمها و شرکتهایی را میبینیم که مشتاق راهحلهای آماده هستند: «چابک-در-یک-جعبه» (Agile-in-a-Box). و مشاوران و شرکتهای بسیاری را میبینیم که با کمال میل آنچه را که آنها میخواهند، به آنها میفروشند. ما شرکتهایی را میبینیم که لایههای بیشتری از مدیریت، گزارشدهی رسمیتر، توسعهدهندگان تخصصیتر، و عناوین شغلی پرزرقوبرقتری را به کار میگیرند که معنای واقعیشان فقط «یک نفر با یک تختهشاسی و یک کرنومتر» است. [۷۴]
ما احساس میکنیم بسیاری از افراد معنای حقیقی چابکی را گم کردهاند، و دوست داریم ببینیم که folks (دوستان) به اصول اولیه بازگردند. ارزشهای بیانیه را به یاد بیاورید:
ما در حال کشف راههای بهتری برای توسعه نرمافزار هستیم، با انجام دادن آن و کمک به دیگران در انجام آن. از طریق این کار، ما به ارزشهای زیر رسیدهایم:
- افراد و تعاملات بالاتر از فرآیندها و ابزارها
- نرمافزار کارآمد بالاتر از مستندات جامع
- همکاری با مشتری بالاتر از مذاکره قرارداد
- پاسخگویی به تغییر بالاتر از پیروی از یک برنامه
یعنی، با اینکه در موارد سمت راست ارزش وجود دارد، ما برای موارد سمت چپ ارزش بیشتری قائلیم.
هر کسی که چیزی به شما میفروشد که اهمیت موارد سمت راست را نسبت به موارد سمت چپ افزایش میدهد، به وضوح برای چیزهایی که ما و سایر نویسندگان بیانیه ارزش قائل بودیم، ارزش قائل نیست. و هر کسی که به شما یک «راهحل-در-جعبه» میفروشد، بیانیه مقدماتی را نخوانده است. ارزشها با انگیزه و آگاهی از عملِ مداومِ کشفِ راههای بهتر برای تولید نرمافزار شکل گرفتهاند. این یک سند ثابت (Static) نیست. اینها پیشنهاداتی برای یک فرآیند زاینده (Generative) هستند.
هرگز نمیتواند یک «فرآیند چابک» وجود داشته باشد
در واقع، هر وقت کسی میگوید «این کار را بکن، و چابک خواهی شد»، آنها در اشتباهند. طبق تعریف.
چون چابکی، چه در دنیای فیزیکی و چه در توسعه نرمافزار، تماماً درباره پاسخ دادن به تغییر است، پاسخ دادن به ناشناختههایی که پس از شروع حرکت با آنها روبرو میشوید. یک غزالِ در حال دویدن، در یک خط مستقیم نمیرود. یک ژیمناست در حالی که به تغییرات محیطش و خطاهای جزئی در محل قرارگیری پاهایش واکنش نشان میدهد، صدها اصلاح در ثانیه انجام میدهد.
در مورد تیمها و توسعهدهندگان فردی هم همینطور است. هیچ برنامه واحدی وجود ندارد که بتوانید هنگام توسعه نرمافزار از آن پیروی کنید. سه مورد از چهار ارزش بیانیه، این را به شما میگویند. همه آنها درباره جمعآوری و پاسخ دادن به بازخورد هستند.
ارزشها به شما نمیگویند چه کاری انجام دهید. آنها به شما میگویند وقتی خودتان تصمیم میگیرید چه کاری انجام دهید، به دنبال چه چیزی باشید. این تصمیمات همیشه وابسته به زمینه (Contextual) هستند: به اینکه شما کی هستید، ماهیت تیمتان، اپلیکیشنتان، ابزارهایتان، شرکتتان، مشتریتان، دنیای بیرون؛ و تعداد فوقالعاده زیادی از عوامل بستگی دارد که برخی بزرگ و برخی جزئی هستند. هیچ برنامه ثابت و ایستایی نمیتواند از این عدم قطعیت جان سالم به در ببرد.
پس ما چه کار کنیم؟
هیچکس نمیتواند به شما بگوید چه کار کنید. اما ما فکر میکنیم میتوانیم چیزی درباره روحیهای که با آن کار را انجام میدهید به شما بگوییم. همه چیز به این خلاصه میشود که چگونه با عدم قطعیت برخورد میکنید. بیانیه پیشنهاد میکند که این کار را با جمعآوری و عمل کردن بر اساس بازخورد انجام دهید.
بنابراین، این دستورالعمل ما برای کار کردن به شیوه چابک است:
۱. دریابید کجا هستید.
۲. کوچکترین گام معنادار را به سمت جایی که میخواهید باشید بردارید.
۳. ارزیابی کنید که سر از کجا درآوردهاید، و هر چیزی را که خراب کردهاید درست کنید.
این مراحل را تکرار کنید تا کارتان تمام شود. و از آنها به صورت بازگشتی (Recursively)، در هر سطحی از هر کاری که میکنید استفاده کنید.
گاهی حتی تصمیماتی که به نظر بیاهمیتترین میرسند، وقتی بازخورد جمعآوری میکنید مهم میشوند.
«خب، الان کد من باید صاحب حساب (account owner) را بگیرد.
let user = accountOwner(accountID);
هوم... user اسم بیخودیه. میذارمش owner.
let owner = accountOwner(accountID);
اما حالا این یه کم تکراری به نظر میرسه. من واقعاً دارم اینجا سعی میکنم چی کار کنم؟ داستان (Story) میگه که من دارم برای این شخص یه ایمیل میفرستم، پس باید آدرس ایمیلشون رو پیدا کنم. شاید اصلاً به کلِ آبجکتِ صاحب حساب نیاز ندارم.
let email = emailOfAccountOwner(accountID);
با اعمال حلقه بازخورد در یک سطح واقعاً پایین (نامگذاری یک متغیر) ما در واقع طراحی کل سیستم را بهبود بخشیدهایم، و وابستگی (Coupling) بین این کد و کدی که با حسابها سروکار دارد را کاهش دادهایم.
حلقه بازخورد در بالاترین سطح پروژه نیز اعمال میشود. برخی از موفقترین کارهای ما زمانی اتفاق افتاد که کار روی نیازمندیهای مشتری را شروع کردیم، یک گام برداشتیم، و متوجه شدیم که کاری که قرار بود انجام دهیم اصلاً ضروری نبود، و بهترین راهحل حتی شامل نرمافزار هم نمیشد.
این حلقه خارج از محدوده یک پروژه واحد نیز اعمال میشود. تیمها باید آن را برای بازنگری فرآیند خود و میزان کارآمدی آن اعمال کنند. تیمی که به طور مداوم فرآیند خود را آزمایش نمیکند، یک تیم چابک نیست.
و این طراحی را هدایت میکند
در مبحث ۸، «جوهره طراحی خوب» ما ادعا کردیم که معیار طراحی این است که نتیجه آن طراحی چقدر برای تغییر دادن آسان است: یک طراحی خوب چیزی تولید میکند که تغییر دادنش آسانتر از یک طراحی بد است. و این بحث درباره چابکی توضیح میدهد که چرا قضیه از این قرار است.
شما تغییری ایجاد میکنید، و متوجه میشوید که دوستش ندارید. مرحله ۳ در لیست ما میگوید ما باید بتوانیم آنچه را که خراب کردهایم درست کنیم. برای اینکه حلقه بازخورد ما کارآمد باشد، این اصلاح باید تا حد امکان بدون دردسر باشد. اگر نباشد، وسوسه میشویم که بیخیالش شویم و آن را اصلاحنکرده رها کنیم. ما درباره این اثر در مبحث ۳، «آنتروپی نرمافزار» صحبت میکنیم.
برای اینکه این ماجرای چابکی کار کند، ما باید طراحی خوب را تمرین کنیم، زیرا طراحی خوب تغییر چیزها را آسان میکند. و اگر تغییر آسان باشد، میتوانیم در هر سطحی، بدون هیچ تردیدی خود را تطبیق دهیم.
این یعنی چابکی.
بخشهای مرتبط شامل:
- مبحث ۲۷: از چراغهای جلوی خود جلو نزنید
- مبحث ۴۰: ریفکتورینگ
- مبحث ۵۰: نارگیلها کار را راه نمیاندازند
چالشها
- حلقه بازخورد ساده فقط برای نرمافزار نیست. به تصمیمات دیگری که اخیراً گرفتهاید فکر کنید. آیا هیچکدام از آنها میتوانست با فکر کردن به اینکه «اگر اوضاع به سمتی که میرفتم پیش نرفت، چطور میتوانم آنها را خنثی (Undo) کنم» بهبود یابد؟
- آیا میتوانید راههایی پیدا کنید که کارهایتان را با جمعآوری و عمل کردن بر اساس بازخورد بهبود بخشید؟