حالت تاریک
پیش از پروژه
آیا تا به حال حس کردهاید پروژهتان حتی پیش از شروع محکوم به شکست است؟ گاهی شاید همینطور باشد — مگر اینکه ابتدا چند قاعده پایهای را مشخص کنید. در غیر این صورت، بهتر است پیشنهاد دهید همین حالا تعطیل شود و کمی پول حامی را ذخیره کنید.
در همان آغاز پروژه باید نیازمندیها را تعیین کنید. فقط گوش دادن به کاربران کافی نیست: در گودال نیازمندیها بیشتر بخوانید.
حل معماهای غیرممکن درباره حکمت رایج و مدیریت محدودیتهاست. چه در جمعآوری نیازمندیها، تحلیل، کدنویسی یا تست باشید، مسائل دشوار سر میزنند. بیشتر وقتها آنقدرها هم که در نگاه اول به نظر میرسند سخت نیستند.
وقتی فکر میکنید مسائل را حل کردهاید، شاید هنوز برای پریدن و شروع راحت نباشید. آیا این تنها بهتعویق انداختن است یا چیز دیگری؟ تا وقتی آماده نیستید درباره اینکه چه وقت عاقلانه است به آن صدای هشداردهنده درون سر گوش دهید، توصیه میدهد.
زود شروع کردن یک مشکل است، اما دیر شروع کردن شاید بدتر باشد. در تله مشخصات، مزایای مشخصسازی با مثال را بررسی میکنیم.
در پایان، در دایرهها و پیکانها به برخی مهلکههای فرایندها و متدولوژیهای رسمی توسعه میپردازیم. هرچقدر هم که خوب فکر شده باشد و هر «بهترین روش»ی را که شامل شود، هیچ روشی جایگزین فکر کردن نمیشود.
با حل این مسائل حیاتی پیش از آغاز پروژه، میتوانید در موقعیت بهتری برای اجتناب از «فلج تحلیلی» و آغاز واقعی پروژه موفق خود باشید.
۳۶ — گودال نیازمندیها
کمال حاصل نمیشود وقتی چیزی برای افزودن نماند، بلکه وقتی چیزی برای برداشتن نماند. . . — آنتوان دو سنت-اگزوپری، باد، شن و ستارهها، ۱۹۳۹
بسیاری از کتابها و آموزشها به جمعآوری نیازمندیها بهعنوان فاز اولیه پروژه اشاره میکنند. واژه «جمعآوری» انگار قبیلهای از تحلیلگران شاد را تداعی میکند که در حالی که سمفونی مرتبط در پسزمینه آرام پخش میشود، برای یافتن تکههای خرد حکمت که همهجا روی زمین پراکندهاند، میگردند. «جمعآوری» یعنی نیازمندیها از قبل آنجا هستند — فقط باید آنها را پیدا کنید، در سبد بگذارید و شاد راهتان را ادامه دهید.
اینطور کار نمیکند. نیازمندیها بهندرت روی سطحاند. معمولاً زیر لایههایی از فرضیات، برداشتهای غلط و سیاستها مدفوناند.
TIP 51
نیازمندی جمع نکنید — برایشان بکنید
کندن نیازمندیها
چطور در میان همه خاک اطراف، یک نیازمندی واقعی را تشخیص دهید؟ پاسخ هم ساده است هم پیچیده.
پاسخ ساده این است که نیازمندی بیانیهای از چیزی است که باید انجام شود. نیازمندیهای خوب ممکن است شامل موارد زیر باشند:
فقط گروهی مشخص از افراد میتوانند پرونده کارمند را ببینند.
دمای سر سیلندر نباید از مقدار بحرانی — که بسته به موتور متفاوت است — فراتر رود.
ویرایشگر کلمات کلیدی را برجسته میکند؛ انتخاب آنها بسته به نوع فایل در حال ویرایش است.
با این حال، بسیاری از نیازمندیها به این روشنی نیستند — و همین تحلیل نیازمندیها را پیچیده میکند.
اولین بیانیه در فهرست بالا شاید توسط کاربران اینطور گفته شده باشد: «فقط سرپرستان یک کارمند و بخش پرسنلی میتوانند پرونده آن کارمند را ببینند.» آیا این واقعاً یک نیازمندی است؟ شاید امروز بله، اما سیاست کسبوکار را در یک بیانیه مطلق جاسازی میکند. سیاستها مرتب عوض میشوند، پس احتمالاً نمیخواهیم آنها را سخت در نیازمندیها حک کنیم. توصیه ما این است که این سیاستها را جدا از نیازمندی مستند کنید و دو طرف را به هم لینک دهید. نیازمندی را بیانیه کلی بگذارید و اطلاعات سیاست را بهعنوان نمونهای از چیزی که در پیادهسازی باید پشتیبانی شود به توسعهدهندگان بدهید. در نهایت، سیاست ممکن است بهصورت متادیتا در برنامه درآید.
این تمایز نسبتاً ظریف است، اما برای توسعهدهندگان پیامدهای عمیقی دارد. اگر نیازمندی «فقط پرسنل میتوانند پرونده کارمند را ببینند» باشد، توسعهدهنده شاید هر بار که برنامه به این فایلها دسترسی پیدا میکند، یک تست صریح کد بزند. اما اگر بیانیه «فقط کاربران مجاز میتوانند به پرونده کارمند دسترسی داشته باشند» باشد، توسعهدهنده احتمالاً نوعی سیستم کنترل دسترسی طراحی و پیادهسازی میکند. وقتی سیاست عوض شود — و میشود — فقط متادیتای آن سیستم باید بهروز شود. در واقع، جمعآوری نیازمندیها به این روش طبیعتاً شما را به سیستمی با فاکتوربندی خوب برای پشتیبانی از متادیتا هدایت میکند.
تمایز میان نیازمندی، سیاست و پیادهسازی وقتی رابط کاربری مطرح میشود خیلی مبهم میشود. «سیستم باید اجازه انتخاب مدت وام را بدهد» بیانیه نیازمندی است. «به list box برای انتخاب مدت وام نیاز داریم» شاید باشد و شاید نباشد. اگر کاربران حتماً باید list box داشته باشند، آن وقت نیازمندی است. اگر در عوض درباره توانایی انتخاب صحبت میکنند و list box را فقط بهعنوان مثال میآورند، شاید نیازمندی نباشد. جعبه در صفحه ۲۰۵ پروژهای را بحث میکند که بهخاطر نادیده گرفتن نیازهای رابط کاربری کاربران بهشکل فاجعهبار خراب شد.
مهم است دلیل زیربنایی اینکه کاربران کاری را انجام میدهند کشف کنید، نه فقط روشی که الان انجام میدهند. در نهایت، توسعه شما باید مسئله کسبوکار آنها را حل کند، نه فقط نیازمندیهای بیانشده را برآورده کند. مستند کردن دلایل پشت نیازمندیها به تیم شما هنگام تصمیمهای روزانه پیادهسازی اطلاعات بینظیری میدهد.
یک تکنیک ساده برای ورود به نیازمندیهای کاربران هست که بهاندازه کافی استفاده نمیشود: خودتان کاربر شوید. برای میز راهنما سیستم مینویسید؟ چند روز با یک پشتیبان باتجربه تلفنها را پایش کنید. سیستم کنترل موجودی دستی را خودکار میکنید؟ یک هفته در انبار کار کنید.¹
یادداشت ۱: یک هفته زیاد به نظر میرسد؟ واقعاً نیست، بهویژه وقتی فرایندهایی را میبینید که مدیریت و کارگران در دنیاهای جدا زندگی میکنند. مدیریت یک تصویر از نحوه کار میدهد، اما وقتی پایین میروید، واقعیت بسیار متفاوتی میبینید — واقعیتی که زمان میبرد جذب شود.
علاوه بر بینشی درباره استفاده واقعی سیستم، از اینکه درخواست «میتوانم یک هفته بنشینم و کار شما را انجام دهم؟» چقدر اعتماد میسازد و پایه ارتباط با کاربران برقرار میکند شگفتزده میشوید. فقط یادتان باشد سر راهشان نایستید!
TIP 52
با یک کاربر کار کنید تا مثل کاربر فکر کنید
فرایند استخراج نیازمندیها هم زمان شروع ساختن رابط با پایگاه کاربران است — یادگیری انتظارات و امیدهایشان برای سیستمی که میسازید. برای بیشتر، انتظارات بزرگ، صفحه ۲۵۵ را ببینید.
مستندسازی نیازمندیها
پس با کاربران نشستهاید و نیازمندیهای واقعی را از آنها بیرون میکشید. چند سناریوی محتمل پیدا میکنید که توصیف میکند برنامه چه باید بکند. حرفهای که هستید، میخواهید آنها را بنویسید و سندی منتشر کنید که همه — توسعهدهندگان، کاربران نهایی و حامیان پروژه — مبنای بحثش باشد.
آن مخاطب خیلی گسترده است.
ایوار یاکوبسون [Jac94] مفهوم use case را برای ثبت نیازمندیها پیشنهاد داد. اجازه میدهند استفاده خاصی از سیستم را — نه بهصورت رابط کاربری، بلکه انتزاعیتر — توصیف کنید. متأسفانه کتاب یاکوبسون در جزئیات کمی مبهم بود، پس حالا نظرات زیادی درباره use case وجود دارد. رسمی است یا غیررسمی؟ نثر ساده یا سند ساختیافته (مثل فرم)؟ سطح جزئیات مناسب چیست (به یاد داشته باشید مخاطب گسترده است)؟
گاهی رابط، خود سیستم است
در مقالهای در مجله Wired (ژانویه ۱۹۹۹، صفحه ۱۷۶)، تهیهکننده و موسیقیدان برایان اینو تکنولوژی باورنکردنی را توصیف کرد — تابلوی میکس نهایی. هر کاری که روی صدا میشود انجام میدهد. با این حال، بهجای اینکه به موسیقیدانان موسیقی بهتر بسازند یا ضبط را سریعتر یا ارزانتر کنند، سر راه میایستد؛ فرایند خلاق را مختل میکند.
برای فهمیدن باید ببینید مهندسان ضبط چطور کار میکنند. صداها را شهودی متعادل میکنند. سالها حلقه بازخورد ذاتی بین گوش و انگشتانشان — لغزاندن faderها، چرخاندن knobها و مانند آن — شکل میگیرد. اما رابط میکسر جدید از این تواناییها بهره نمیگرفت. در عوض، کاربران را مجبور میکرد روی صفحهکلید تایپ کنند یا ماوس کلیک کنند. توابع جامع بودند، اما در بستهبندیهای ناآشنا و عجیب. توابعی که مهندسان میخواستند گاهی پشت نامهای مبهم پنهان بودند یا با ترکیبهای غیرشهودی امکانات پایه بهدست میآمدند.
آن محیط نیازمندی دارد که از مهارتهای موجود بهره ببرد. کپی کورکورانه آنچه هست پیشرفت را ممکن نمیکند، اما باید بتوانیم گذار به آینده را فراهم کنیم.
مثلاً مهندسان ضبط شاید با نوعی رابط لمسی — هنوز لمسی، هنوز مثل تابلوی میکس سنتی نصبشده — بهتر سرویس میشدند، اما نرمافزار میتوانست فراتر از knob و سوئیچ ثابت برود. فراهم کردن گذار راحت با استعارههای آشنا یکی از راههای کمک به پذیرش است.
این مثال هم باور ما را نشان میدهد که ابزارهای موفق به دستان استفادهکننده سازگار میشوند. در این مورد، ابزارهایی که برای دیگران میسازید باید سازگار باشند.
یک نگاه به use caseها، تأکید بر ماهیت هدفمحور آنهاست. آلیستair Cockburn مقالهای دارد که این رویکرد را توصیف میکند، و همچنین قالبهایی که میتوان (سخت یا نرم) نقطه شروع گرفت ([Coc97a]، آنلاین در [URL 46]). شکل ۷.۱ در صفحه بعد نمونه خلاصهشده قالب او را نشان میدهد و شکل ۷.۲ use case نمونه او را.
شکل ۷.۱. قالب use case کاکبرن
A. اطلاعات مشخصهای
– هدف در بافت
– دامنه
– سطح
– پیششرطها
– شرط پایان موفق
– شرط پایان ناموفق
– بازیگر اصلی
– محرک
B. سناریوی موفقیت اصلی
C. گسترشها
D. تغییرات
E. اطلاعات مرتبط
– اولویت
– هدف عملکرد
– فراوانی
– use case والد
– use caseهای فرعی
– کانال به بازیگر اصلی
– بازیگران ثانوی
– کانال به بازیگران ثانوی
F. زمانبندی
G. مسائل بازشکل ۷.۲. یک use case نمونه
USE CASE 5: BUY GOODS
A. اطلاعات مشخصهای
Goal in context: Buyer issues request directly to our company, expects
goods shipped and to be billed.
Scope: Company
Level: Summary
Preconditions: We know buyer, their address, etc.
Success end condition: Buyer has goods, we have money for the goods.
Failed end condition: We have not sent the goods, buyer has not sent
the money.
Primary actor: Buyer, any agent (or computer) acting for the customer
Trigger: Purchase request comes in.
B. MAIN SUCCESS SCENARIO
1. Buyer calls in with a purchase request.
2. Company captures buyer's name, address, requested goods, etc.
3. Company gives buyer information on goods, prices, delivery dates, etc.
4. Buyer signs for order.
5. Company creates order, ships order to buyer.
6. Company ships invoice to buyer.
7. Buyer pays invoice.
C. EXTENSIONS
3a. Company is out of one of the ordered items: Renegotiate order.
4a. Buyer pays directly with credit card: Take payment by credit card (use
case 44).
7a. Buyer returns goods: Handle returned goods (use case 105).
D. VARIATIONS
1. Buyer may use phone in, fax in, Web order form, electronic interchange.
7. Buyer may pay by cash, money order, check, or credit card.
E. RELATED INFORMATION
Priority: Top
Performance target: 5 minutes for order, 45 days until paid
Frequency: 200/day
Superordinate use case: Manage customer relationship (use case 2).
Subordinate use cases: Create order (15). Take payment by credit card
(44). Handle returned goods (105).
Channel to primary actor: May be phone, file, or interactive
Secondary actors: Credit card company, bank, shipping service
F. SCHEDULE
Due date: Release 1.0
G. OPEN ISSUES
What happens if we have part of the order?
What happens if credit card is stolen?با استفاده از قالب رسمی بهعنوان یادآور، مطمئن میشوید همه اطلاعات لازم در use case هست: ویژگیهای عملکردی، طرفهای دیگر درگیر، اولویت، فراوانی، و خطاها و استثناهای مختلف («نیازمندیهای غیرعملکردی»). این هم جای خوبی برای ثبت نظرات کاربر مثل «آه، مگر اینکه شرایط xxx پیش بیاید، آن وقت باید yyy کنیم» است. قالب هم دستور جلسه آماده برای ملاقات با کاربران است.
این نوع سازماندهی ساختار سلسلهمراتبی use caseها را پشتیبانی میکند — use caseهای جزئیتر داخل use caseهای سطح بالاتر تو در تو. مثلاً post debit و post credit هر دو post transaction را گسترش میدهند.
نمودارهای Use Case
جریان کار را میتوان با نمودار فعالیت UML ثبت کرد و نمودار کلاس سطح مفهومی گاهی برای مدلسازی کسبوکار مفید است. اما use caseهای واقعی توصیف متنی با سلسلهمراتب و پیوند متقابل هستند. use caseها میتوانند به use caseهای دیگر لینک داشته باشند و در یکدیگر تو در تو شوند.
برای ما باورنکردنی است که کسی جدی بخواهد اطلاعات به این تراکم را فقط با آدمکهای ساده مثل شکل ۷.۳ مستند کند. برده هیچ notationای نباشید؛ هر روشی که بهترین ارتباط نیازمندیها را با مخاطبتان برقرار میکند به کار ببرید.
شکل ۷.۳. use caseهای UML — آنقدر ساده که بچه هم میتواند!
برو
خانهبیشمشخصسازی
خطر بزرگ در تولید سند نیازمندیها، بیش از حد مشخص بودن است. اسناد نیازمندی خوب انتزاعی میمانند. درباره نیازمندیها، سادهترین بیانیهای که دقیقاً نیاز کسبوکار را منعکس کند بهترین است. این به معنای مبهم بودن نیست — باید ناوردهای معنایی زیربنایی را بهعنوان نیازمندی بگیرید و شیوه کار مشخص یا فعلی را بهعنوان سیاست مستند کنید.
نیازمندیها معماری نیستند. نیازمندیها طراحی نیستند و رابط کاربری هم نیستند. نیازمندیها نیاز هستند.
دیدن دورتر
مسئله سال ۲۰۰۰ اغلب به برنامهنویسان کوتاهبین که در روزهایی که mainframeها حافظهای کمتر از ریموت تلویزیون مدرن داشتند، چند بایت ذخیره میکردند، نسبت داده میشود.
اما کار برنامهنویسان نبود و واقعاً مسئله حافظه هم نبود. اگر چیزی، تقصیر تحلیلگران و طراحان سیستم بود. مشکل Y2K از دو علت اصلی آمد: ناتوانی در دیدن فراتر از شیوه فعلی کسبوکار، و نقض اصل DRY.
کسبوکارها سالها پیش از کامپیوترها از میانبر دو رقمی استفاده میکردند. عرف رایج بود. اولین برنامههای پردازش داده فقط فرایندهای موجود را خودکار کردند و همان اشتباه را تکرار کردند. حتی اگر معماری برای ورود، گزارش و ذخیره سال دو رقمی میخواست، باید انتزاعی از DATE وجود میداشت که «میدانست» دو رقم شکل مخفف تاریخ واقعی است.
TIP 53
انتزاعها از جزئیات بیشتر عمر میکنند
آیا «دیدن دورتر» یعنی آینده را پیشبینی کنید؟ نه. یعنی بیانیههایی مثل این تولید کنید:
سیستم از انتزاع DATE بهصورت فعال استفاده میکند. سیستم خدمات DATE — مانند قالببندی، ذخیره و عملیات ریاضی — را یکنواخت و سراسری پیادهسازی میکند.
نیازمندیها فقط میگویند تاریخ استفاده میشود. شاید اشاره کند روی تاریخها محاسبهای انجام میشود. شاید بگوید تاریخها روی انواع ذخیره ثانویه ذخیره میشوند. اینها نیازمندیهای واقعی برای ماژول یا کلاس DATE هستند.
فقط یک نعناع نازک دیگر. . .
بسیاری از شکستهای پروژه به افزایش دامنه — انباشت قابلیت، قابلیتافزایی creeping یا خزیدن نیازمندی — نسبت داده میشود. جنبهای از سندرم قورباغه جوشان در آش سنگ و قورباغههای جوشان، صفحه ۷. چطور از خزیدن نیازمندیها جلوگیری کنیم؟
در ادبیات، توصیف معیارهای زیادی — باگ گزارششده و رفعشده، چگالی نقص، cohesion، coupling، function point، خطوط کد و غیره — مییابید. این معیارها دستی یا با نرمافزار ردیابی میشوند.
متأسفانه پروژههای زیادی نیازمندیها را فعالانه ردیابی نمیکنند. یعنی راهی برای گزارش تغییر دامنه — چه کسی قابلیت خواست، چه کسی تأیید کرد، تعداد کل درخواستهای تأییدشده و غیره — ندارند.
کلید مدیریت رشد نیازمندیها این است که تأثیر هر قابلیت جدید روی زمانبندی را به حامیان پروژه نشان دهید. وقتی پروژه یک سال از تخمین اولیه عقب است و اتهامها پرواز میکند، داشتن تصویر دقیق و کامل از اینکه چگونه و چه وقت رشد نیازمندی رخ داده مفید است.
آسان است در گرداب «فقط یک قابلیت دیگر» گیر کنید، اما با ردیابی نیازمندیها تصویر روشنتری میگیرید که «فقط یک قابلیت دیگر» در واقع پانزدهمین قابلیت جدید این ماه است.
نگهداشتن واژهنامه
به محض شروع بحث نیازمندیها، کاربران و متخصصان حوزه از واژههایی با معنای خاص استفاده میکنند. مثلاً ممکن است بین «client» و «customer» تمایز بگذارند. آن وقت استفاده تصادفی از هر کلمه در سیستم نامناسب است.
واژهنامه پروژه بسازید و نگه دارید — یک جا که همه اصطلاحات و واژگان خاص پروژه تعریف میشوند. همه شرکتکنندگان — از کاربر نهایی تا پشتیبانی — باید از واژهنامه برای یکنواختی استفاده کنند. یعنی واژهنامه باید بهراحتی در دسترس باشد — استدلال خوبی برای مستندسازی وبمحور (بیشتر در لحظه).
TIP 54
از واژهنامه پروژه استفاده کنید
خیلی سخت است در پروژهای موفق شوید که کاربران و توسعهدهندگان به یک چیز با نامهای مختلف اشاره کنند — یا بدتر، به چیزهای مختلف با یک نام.
پخش خبر
در همهچیز نوشتن است، صفحه ۲۴۸، انتشار اسناد پروژه روی سایتهای داخلی برای دسترسی آسان همه شرکتکنندگان را بحث میکنیم. این روش توزیع بهویژه برای اسناد نیازمندی مفید است.
با ارائه نیازمندیها بهصورت سند ابرمتن، بهتر به نیاز مخاطبان متنوع پاسخ میدهید — به هر خواننده آنچه میخواهد. حامیان پروژه در سطح انتزاع بالا حرکت میکنند تا اهداف کسبوکار برآورده شود. برنامهنویسان با پیوند ابرمتن میتوانند به سطوح جزئیتر «حفر کنند» (حتی به تعاریف یا مشخصات مهندسی مناسب ارجاع دهند).
توزیع وبمحور از جلد دو اینچی معمول با عنوان «تحلیل نیازمندی» که کسی نمیخواند و لحظهای که جوهر روی کاغذ مینشیند منسوخ میشود هم جلوگیری میکند.
اگر روی وب باشد، شاید برنامهنویسان واقعاً بخوانندش.
بخشهای مرتبط:
- آش سنگ و قورباغههای جوشان، صفحه ۷
- نرمافزار بهاندازه کافی خوب، صفحه ۹
- دایرهها و پیکانها، صفحه ۲۲۰
- همهچیز نوشتن است، صفحه ۲۴۸
- انتظارات بزرگ، صفحه ۲۵۵
Challenges
آیا میتوانید از نرمافزاری که مینویسید استفاده کنید؟ آیا بدون استفاده واقعی از نرمافزار میتوان حس خوبی از نیازمندیها داشت؟
مسئله غیرمرتبط با کامپیوتری که الان باید حل کنید انتخاب کنید. برای راهحل غیرکامپیوتری نیازمندی تولید کنید.
Exercises
پاسخ در صفحه ۳۰۷
۴۲. کدامهای زیر احتمالاً نیازمندی واقعی هستند؟ آنهایی که نیستند را — اگر ممکن است — طوری بازنویسی کنید که مفیدتر شوند.
زمان پاسخ باید کمتر از ۵۰۰ ms باشد.
جعبههای گفتگو پسزمینه خاکستری دارند.
برنامه بهصورت چند فرایند front-end و یک سرور back-end سازماندهی میشود.
اگر کاربر در فیلد عددی کاراکتر غیرعددی وارد کند، سیستم بوق میزند و قبول نمیکند.
کد و داده برنامه باید در ۲۵۶kB جا بگیرند.
۳۷ — حل معماهای غیرممکن
گوردیوس، پادشاه فریgia، گرهی بست که کسی نمیتوانست باز کند. گفته میشد کسی که معمای گره گوردی را حل کند بر بیشتر آسیا حکومت میکند. الکساندر بزرگ میآید و گره را با شمشیر تکهتکه میکند. فقط تفسیر کمی متفاوت از نیازمندیها — و در نهایت بیشتر آسیا را فتح کرد.
گاهی در میانه پروژه با معمای واقعاً سخت روبهرو میشوید: تکهای مهندسی که دستتان نمیآید، یا بخشی از کد که نوشتنش از آنچه فکر میکردید سختتر است. شاید غیرممکن به نظر برسد. اما واقعاً به این سختی است؟
معماهای دنیای واقعی را در نظر بگیرید — آن تکههای چوب، آهن یا پلاستیک که هدیه کریسمس یا حراجی میآیند. فقط باید حلقه را بردارید، یا قطعات T شکل را در جعبه جا دهید، یا هر چیز دیگر.
پس حلقه را میکشید یا Tها را در جعبه میگذارید و زود میفهمید راهحلهای آشکار کار نمیکنند. معما آنطور حل نمیشود. اما با وجود آشکار بودن، مردم همان کار را — بارها — تکرار میکنند، فکر میکنند حتماً راهی هست.
البته نیست. راهحل جای دیگری است. راز حل معما شناسایی محدودیتهای واقعی (نه خیالی) و یافتن راهحل در آنهاست. بعضی محدودیتها مطلقاند؛ بعضی فقط تصورات از پیش ساختهاند. محدودیتهای مطلق باید رعایت شوند، هرچقدر هم ناخوشایند یا احمقانه به نظر برسند. از سوی دیگر، بعضی محدودیتهای ظاهری اصلاً واقعی نیستند. مثلاً آن ترفند بار قدیمی: شرط میبندید که از بطری شامپاین نو و بسته میتوانید آبجو بنوشید. راز این است که بطری را وارونه کنید و مقدار کمی آبجو در فرورفتگی ته بطری بریزید. بسیاری از مسائل نرمافزاری هم به همین زیرکیاند.
درجههای آزادی
عبارت رایج «think outside the box» ما را تشویق میکند محدودیتهایی که شاید اعمال نشوند را بشناسیم و نادیده بگیریم.
اما این عبارت کاملاً دقیق نیست. اگر «جعبه» مرز محدودیتها و شرایط است، ترفند یافتن جعبه است — که ممکن است خیلی بزرگتر از آنچه فکر میکنید باشد.
کلید حل معماها هم شناخت محدودیتهایی است که روی شما گذاشته شده و هم درجههای آزادی که دارید — در آنها راهحل را مییابید. به همین دلیل بعضی معماها مؤثرند؛ شاید راهحلهای بالقوه را زود رد کنید.
مثلاً آیا میتوانید همه نقطههای معمای زیر را با فقط سه خط راست وصل کنید و به نقطه شروع برگردید — بدون برداشتن قلم از کاغذ یا تکرار مسیر [Hol78]?
• • •
• • •
• • •باید هر تصور از پیش ساختهای را به چالش بکشید و بسنجید واقعاً محدودیت سخت و سریع است یا نه.
مسئله «داخل جعبه فکر کنید یا بیرون» نیست. مسئله یافتن جعبه — شناسایی محدودیتهای واقعی — است.
TIP 55
خارج از جعبه فکر نکنید — جعبه را پیدا کنید
وقتی با مسئله بنبست روبهرو شدید، همه راههای ممکن را فهرست کنید. چیزی را رد نکنید، هرچقدر هم غیرقابل استفاده یا احمقانه به نظر برسد. حالا فهرست را بروید و توضیح دهید چرا مسیر خاصی قابل رفتن نیست. مطمئنید؟ میتوانید ثابت کنید؟
اسب تروا را در نظر بگیرید — راهحل نوآورانه برای مسئله بنبست. چطور سربازان را به شهر محصور ببرید بدون اینکه کشف شوند؟ مطمئناً «از در جلو» در ابتدا بهعنوان خودکشی رد شد.
محدودیتها را دستهبندی و اولویتبندی کنید. وقتی نجار پروژهای را شروع میکند، اول قطعات بلندتر را میبرد، بعد قطعات کوچکتر را از چوب باقیمانده. به همین ترتیب، محدودیتترین محدودیتها را اول شناسایی کنید و بقیه را در آنها جا دهید.
راهحل معمای Four Posts در صفحه ۳۰۷ نشان داده شده.
حتماً راه سادهتری هست!
گاهی روی مسئلهای کار میکنید که خیلی سختتر از آنچه باید باشد به نظر میرسد. شاید حس کنید مسیر اشتباهی میروید — حتماً راه سادهتری هست! شاید از زمانبندی عقب افتادهاید، یا حتی از کار کردن سیستم ناامید شدهاید چون این مسئله «غیرممکن» است.
آن وقت یک قدم عقب میروید و از خودتان میپرسید:
آیا راه سادهتری هست؟
آیا مسئله درست را حل میکنید، یا حواستان با جزئیات فنی حاشیهای پرت شده؟
چرا این چیز مسئله است؟
چه چیزی حل آن را اینقدر سخت میکند؟
آیا باید اینطور انجام شود؟
آیا باید اصلاً انجام شود؟
بارها با پاسخ به یکی از این سؤالها بینش شگفتانگیزی به سراغتان میآید. بارها بازتفسیر نیازمندیها کل مجموعه مسائل را از بین میبرد — مثل گره گوردی.
فقط به محدودیتهای واقعی، محدودیتهای گمراهکننده و حکمت تمایز بین آنها نیاز دارید.
Challenges
به مسئله سخت امروزتان سخت نگاه کنید. آیا میتوانید گره گوردی را ببرید؟ سؤالات کلیدی بالا — بهویژه «آیا باید اینطور انجام شود؟» — را از خود بپرسید.
وقتی به پروژه فعلی پیوستید، مجموعهای از محدودیتها به شما داده شد؟ آیا همه هنوز اعمالاند و تفسیرشان هنوز معتبر است؟
۳۸ — تا وقتی آماده نیستید
کسی که مردد میماند گاهی نجات مییابد. — جیمز Thurber، The Glass in the Field
اجراکنندگان بزرگ صفت مشترک دارند: میدانند کی شروع کنند و کی صبر کنند. غواص روی تخته بلند میایستد و لحظه مناسب برای پریدن را منتظر میماند. رهبر ارکست جلوی ارکستر میایستد، دستها بالا، تا حس کند لحظه درست برای شروع قطعه است.
شما هم اجراکننده بزرگی هستید. شما هم باید به صدایی که «صبر» میگوید گوش دهید. اگر برای شروع تایپ مینشینید و شکی مزاحم در ذهنتان هست، به آن توجه کنید.
TIP 56
به شکهای مزاحم گوش دهید — وقتی آمادهاید شروع کنید
روزی سبک مربیگری تنیس به نام «inner tennis» بود. ساعتها توپ را از روی تور میزدید، نه لزوماً برای دقت، بلکه با گفتن اینکه توپ نسبت به هدف (اغلب صندلی) کجا خورد. ایده این بود که بازخورد زیرآگاه و رفلکسها را تربیت کند تا بدون دانستن آگاهانه چگونه یا چرا بهتر شوید.
بهعنوان توسعهدهنده، همین کار را در کل مسیر حرفهتان کردهاید. چیزها را امتحان کردهاید و دیدهاید کدام کار کرد و کدام نه. تجربه و خرد جمع کردهاید. وقتی شک مزاحم حس میکنید، یا هنگام مواجهه با کاری مردد میشوید، به آن توجه کنید. شاید نتوانید دقیقاً بگویید چه چیز اشتباه است، اما وقت بدهید و شکهایتان احتمالاً به چیز محکمتری تبدیل میشوند که بتوانید به آن بپردازید. توسعه نرمافزار هنوز علم نیست. بگذارید غریزهها به عملکردتان کمک کنند.
قضاوت خوب یا بهتعویق انداختن؟
همه از برگه خالی میترسند. شروع پروژه جدید (یا حتی ماژول جدید در پروژه موجود) میتواند آزاردهنده باشد. بسیاری از ما ترجیح میدهیم تعهد اولیه شروع را به تأخیر بیندازیم. پس چطور بفهمید فقط بهتعویق میاندازید، نه اینکه مسئولانه منتظر میمانید تا همه قطعات سر جایشان بیفتند؟
تکنیکی که برای ما کار کرده، شروع نمونهسازی اولیه است. ناحیهای که سخت به نظر میرسد انتخاب کنید و نوعی اثبات مفهوم تولید کنید. معمولاً یکی از دو اتفاق میافتد. کمی بعد از شروع، شاید حس کنید وقتتان را تلف میکنید. این ملال احتمالاً نشانه خوبی است که مردد بودن اولیه فقط تمایل به بهتعویق انداختن تعهد شروع بود. نمونه اولیه را رها کنید و وارد توسعه واقعی شوید.
از سوی دیگر، با پیشرفت نمونه اولیه ممکن است لحظه بینش داشته باشید که ناگهان بفهمید فرض پایهای اشتباه بود — نه فقط آن، بلکه واضح میبینید چطور درستش کنید. راحت نمونه اولیه را رها میکنید و وارد خود پروژه میشوید. غریزهتان درست بود و مقدار زیادی تلاش هدر رفته از خود و تیم نجات دادید.
وقتی برای بررسی ناراحتیتان نمونه اولیه میسازید، یادتان باشد چرا این کار را میکنید. آخرین چیزی که میخواهید چند هفته در توسعه جدی باشید و بعد یادتان بیاید با نوشتن نمونه اولیه شروع کرده بودید.
کمی بدبینانه، شروع کار روی نمونه اولیه از نظر سیاسی هم ممکن است قابل قبولتر از اعلام «حس خوبی برای شروع ندارم» و باز کردن solitaire باشد.
Challenges
- سندرم ترس از شروع را با همکاران بحث کنید. دیگران هم همین را تجربه میکنند؟ به آن توجه میکنند؟ چه ترفندهایی برای غلبه دارند؟ آیا گروه میتواند مردد بودن فرد را جبران کند، یا فقط فشار همسالان است؟
۳۹ — تله مشخصات
خلبان فرود، تا فراخوان «ارتفاع تصمیم»، خلبان غیرفروددهنده است؛ آن وقت خلبان غیرفروددهنده کنترل را به خلبان فروددهنده غیرکنترلکننده میدهد، مگر اینکه دومی «go-around» بزند، که در آن صورت خلبان غیرفروددهنده کنترل را ادامه میدهد و خلبان فروددهنده غیرکنترلکننده غیرکنترل را ادامه میدهد تا فراخوان بعدی «land» یا «go-around»، بسته به مورد. با توجه به سردرگمیهای اخیر درباره این قواعد، لازم دیدیم آنها را روشن بازگو کنیم.
— یادداشت British Airways، نقلشده در Pilot Magazine، دسامبر ۱۹۹۶
مشخصسازی برنامه فرایند گرفتن یک نیازمندی و کاهش آن تا جایی است که مهارت برنامهنویس بتواند ادامه دهد. عمل ارتباط است — توضیح و روشنسازی جهان بهگونهای که ابهامات بزرگ برداشته شوند. علاوه بر صحبت با توسعهدهندهای که پیادهسازی اولیه را انجام میدهد، مشخصات سابقهای برای نسلهای بعدی برنامهنویسانی است که کد را نگه میدارند و گسترش میدهند. مشخصات هم توافق با کاربر است — ثبت نیازهایشان و قرارداد ضمنی که سیستم نهایی با آن نیازمندی همراستا باشد.
نوشتن مشخصات مسئولیت بزرگی است.
مشکل این است که بسیاری از طراحان سخت میتوانند متوقف شوند. حس میکنند مگر هر جزئی کوچک با جزئیات دردناک ثبت نشود، دلار روزانهاشان را نکشیدهاند.
این برای چند دلیل اشتباه است. اول، سادهلوحانه است فرض کنیم مشخصات هرگز هر جزئی و ظرافت سیستم یا نیازمندیاش را میگیرد. در حوزههای محدود مسئله، روشهای رسمی هست که سیستم را توصیف میکنند، اما هنوز طراح باید معنای notation را به کاربران نهایی توضیح دهد — هنوز تفسیر انسانی هست که اوضاع را خراب میکند. حتی بدون مشکلات ذاتی این تفسیر، خیلی بعید است کاربر متوسط دقیقاً بداند چه میخواهد. شاید بگوید نیازمندی را میفهمند و سند ۲۰۰ صفحهای شما را امضا کنند، اما تضمین میکنید وقتی سیستم در حال اجرا را ببینند، موج درخواست تغییر میگیرید.
دوم، مشکل قدرت بیان زبان خودش است. همه تکنیکهای نموداری و روشهای رسمی هنوز به بیان زبان طبیعی عملیات وابستهاند.² و زبان طبیعی واقعاً برای این کار ساخته نشده. wording هر قراردادی را ببینید: برای دقیق بودن، وکلا مجبورند زبان را به غیرطبیعیترین شکلها خم کنند.
یک چالش برای شما: توضیح کوتاهی بنویسید که به کسی یاد دهد چطور روی بند کفش پاپیون بزند. بروید، امتحان کنید!
اگر مثل ما باشید، احتمالاً جایی حوالی «حالا انگشت شست و اشاره را بچرخانید تا انتهای آزاد زیر و داخل بند چپ رد شود. . .» تسلیم شدید. کار فوقالعاده سختی است. با این حال بیشتر ما بدون فکر آگاهی کفش میبندیم.
TIP 57
بعضی چیزها بهتر است انجام شوند تا توصیف
در نهایت، اثر قفس است. طراحی که به کدنویس هیچ فضایی برای تفسیر نمیدهد، تلاش برنامهنویسی را از هر مهارت و هنری محروم میکند. بعضی میگویند این بهتر است، اما اشتباه میکنند. اغلب فقط حین کدنویسی گزینههای خاصی آشکار میشوند. حین کدنویسی شاید فکر کنید «ببین، بهخاطر روشی که این روتین را کد زدم، میتوانم این قابلیت اضافه را با تقریباً بدون تلاش اضافه کنم» یا «مشخصات میگوید این کار را بکن، اما میتوانم تقریباً همان نتیجه را راه دیگر بگیرم و در نصف زمان.» واضح است که نباید فقط دستکاری کنید و تغییر بدهید، اما اگر طراحی بیش از حد دستوری بود، اصلاً فرصت را نمیدیدید.
بهعنوان برنامهنویس عملگرا، جمعآوری نیازمندی، طراحی و پیادهسازی را جنبههای مختلف یک فرایند — تحویل سیستم باکیفیت — ببینید. به محیطهایی که نیازمندی جمع میشود، مشخصات نوشته میشود و بعد کدنویسی شروع میشود، همه در انزوا، بدبین باشید. در عوض، رویکرد یکپارچه بگیرید: مشخصسازی و پیادهسازی فقط جنبههای مختلف یک فرایند — تلاش برای ثبت و رمزگذاری نیازمندی — هستند. هر کدام باید مستقیم به بعدی جریان یابد، بدون مرز مصنوعی. خواهید دید فرایند توسعه سالم بازخورد از پیادهسازی و تست به فرایند مشخصسازی را تشویق میکند.
برای روشن بودن: ما علیه تولید مشخصات نیستیم. بله، مواقعی هست که مشخصات با جزئیات باورنکردنی لازم است — بهدلایل قراردادی، محیط کاری، یا ماهیت محصول.³ فقط آگاه باشید با جزئیات بیشتر و بیشتر مشخصات به نقطه بازده نزولی — یا حتی منفی — میرسید. همچنین مراقب باشید مشخصات روی مشخصات بسازید بدون پیادهسازی یا prototyping پشتیبان؛ خیلی آسان است چیزی مشخص کنید که قابل ساخت نیست.
هرچه بیشتر بگذارید مشخصات پتو امن باشد که توسعهدهندگان را از دنیای ترسناک نوشتن کد محافظت کند، سختتر به کدنویسی میروید. در این مارپیچ مشخصسازی نیفتید: جایی باید کدنویسی را شروع کنید! اگر تیم همه در مشخصات گرم و راحت پیچیدهاند، آنها را بیرون بکشید. نمونهسازی اولیه را ببینید، یا توسعه با گلوله ردیاب را در نظر بگیرید.
یادداشت ۲: تکنیکهای رسمی هست که سعی میکنند عملیات را جبری بیان کنند، اما در عمل بهندرت استفاده میشوند. هنوز لازم است تحلیلگران معنا را به کاربران نهایی توضیح دهند.
یادداشت ۳: مشخصات جزئی برای سیستمهای حیاتی مناسب است. احساس میکنیم برای رابطها و کتابخانههایی که دیگران استفاده میکنند هم باید تولید شوند. وقتی کل خروجی شما مجموعهای از فراخوانیهای روتین دیده میشود، بهتر است آن فراخوانیها خوب مشخص شده باشند.
بخشهای مرتبط:
- گلولههای ردیاب، صفحه ۴۸
Challenges
مثال بند کفش در متن نشان جالبی از مشکلات توصیف نوشتاری است. آیا توصیف فرایند با نمودار بهجای کلمات را در نظر گرفتید؟ عکس؟ notation رسمی توپولوژی؟ مدل با بند سیمی؟ چطور به کودک نوپا یاد میدهید؟
گاهی یک تصویر از هر تعداد کلمه ارزشمندتر است. گاهی بیارزش است. اگر بیش از حد مشخص میکنید، آیا تصویر یا notation خاص کمک میکند؟ چقدر جزئی باید باشند؟ کی ابزار رسم از تخته سفید بهتر است؟
۴۰ — دایرهها و پیکانها
[عکسها] با دایرهها و پیکانها و پاراگرافی پشت هر کدام که توضیح میدهد هر کدام چه بود، برای استفاده بهعنوان مدرک علیه ما. . . — Arlo Guthrie، «Alice's Restaurant»
از برنامهنویسی ساختیافته، تیمهای chief programmer، ابزار CASE، توسعه waterfall، مدل مارپیچی، Jackson، نمودار ER، ابر Booch، OMT، Objectory و Coad/Yourdon تا UML امروز، محاسبات هرگز از روشهایی که برنامهنویسی را شبیه مهندسی کند کوتاه نبوده. هر روش پیروان جمع میکند و دورهای محبوبیت مییابد. بعد با بعدی جایگزین میشود. از همه، شاید فقط اولین — برنامهنویسی ساختیافته — عمر طولانی داشته باشد.
با این حال بعضی توسعهدهندگان، در دریای پروژههای غرقشونده، مثل قربانیان کشتیغوطه به آخرین مد چنگ میزنند. هر تکه چوب شناور که میگذرد با درد به سمتش شنا میکنند، امیدوار بهتر باشد. در پایان روز، مهم نیست آن چوب شناور چقدر خوب باشد — توسعهدهندگان هنوز بیهدف سرگرداناند.
منظورمان این نیست که از تکنیکها و روشهای رسمی بدمان میآید. بعضی را دوست داریم. اما باور داریم پذیرش کورکورانه هر تکنیک بدون گذاشتنش در بافت شیوهها و تواناییهای توسعهتان، دستور شکست است.
TIP 58
برده روشهای رسمی نباشید
روشهای رسمی کاستیهای جدی دارند.
بیشتر روشهای رسمی نیازمندیها را با ترکیب نمودار و کلمات پشتیبان میگیرند. این تصاویر درک طراحان از نیازمندیها را نشان میدهند. اما در بسیاری موارد این نمودارها برای کاربران نهایی بیمعناست، پس طراحان باید تفسیر کنند. پس بررسی واقعی رسمی نیازمندیها توسط کاربر واقعی سیستم نیست — همه بر توضیحات طراحان استوار است، مثل نیازمندیهای نوشتاری قدیمی. سودی در ثبت نیازمندیها اینطور میبینیم، اما ترجیح میدهیم در صورت امکان نمونه اولیه نشان دهیم و بگذاریم با آن بازی کنند.
روشهای رسمی به تخصصگرایی تشویق میکنند. یک گروه روی مدل داده کار میکند، دیگری معماری را میبیند، جمعکنندگان نیازمندی use case (یا معادل) جمع میکنند. دیدهایم این به ارتباط ضعیف و تلاش هدر رفته منجر شود. همچنین گرایش به بازگشت به ذهنیت ما در برابر آنها — طراحان در برابر کدنویسان. ترجیح میدهیم کل سیستمی که روی آن کار میکنیم را بفهمیم. شاید درک عمیق هر جنبه ممکن نباشد، اما باید بدانید اجزا چطور تعامل دارند، داده کجا زندگی میکند و نیازمندیها چیست.
سیستمهای سازگار و پویا مینویسیم، با متادیتا تا بتوانیم ماهیت برنامهها را در زمان اجرا عوض کنیم. بیشتر روشهای رسمی فعلی مدل شیء یا داده ایستا را با مکانیزم نمودار رویداد یا فعالیت ترکیب میکنند. هنوز به روشی برنخوردهایم که پویاییای را که احساس میکنیم سیستمها باید نشان دهند، نشان دهد. در واقع، بیشتر روشهای رسمی شما را گمراه میکنند و به روابط ایستا بین اشیاء تشویق میکنند که واقعاً باید پویا به هم بافته شوند.
آیا روشها سود دارند؟
در مقاله ۱۹۹۹ CACM [Gla99b]، Robert Glass تحقیق درباره بهبود بهرهوری و کیفیت با هفت فناوری توسعه نرمافزار (4GL، تکنیکهای ساختیافته، ابزار CASE، روشهای رسمی، clean room، مدل فرایند و شیءگرایی) را مرور میکند. گزارش میدهد hype اولیه اطراف همه این روشها بیش از حد بود. اگرچه نشانهای هست بعضی سود دارند، این سودها فقط بعد از افت محسوس بهرهوری و کیفیت حین پذیرش تکنیک و آموزش کاربران ظاهر میشوند. هزینه پذیرش ابزار و روش جدید را هرگز دستکم نگیرید. آماده باشید پروژههای اول با این تکنیکها را تجربه یادگیری بدانید.
آیا باید از روشهای رسمی استفاده کنیم؟
قطعاً. اما همیشه به یاد داشته باشید روشهای توسعه رسمی فقط یک ابزار دیگر در جعبهابزارند. اگر بعد از تحلیل دقیق احساس کردید روش رسمی لازم است، آن را بپذیرید — اما به یاد داشته باشید چه کسی فرمانده است. هرگز برده متدولوژی نشوید: دایرهها و پیکانها ارباب ضعیفیاند. برنامهنویسان عملگرا متدولوژیها را انتقادی میبینند، بهترین هر کدام را استخراج میکنند و در مجموعه شیوههای کاری که هر ماه بهتر میشود میآمیزند. این حیاتی است. باید مرتب فرایندها را پالایش و بهبود دهید. هرگز محدودیتهای سخت متدولوژی را بهعنوان مرز جهان خود نپذیرید.
به اقتدار کاذب روش تسلیم نشوید. ممکن است کسی با انبوهی نمودار کلاس و ۱۵۰ use case به جلسه بیاید، اما همه آن کاغذ هنوز فقط تفسیر خطاپذیر آنها از نیازمندیها و طراحی است. سعی کنید هنگام نگاه به خروجی ابزار، به هزینه ابزار فکر نکنید.
TIP 59
ابزار گران طراحی بهتر تولید نمیکند
روشهای رسمی جایگاهشان را در توسعه دارند. اما اگر پروژهای دیدید که فلسفهاش «نمودار کلاس خود برنامه است، بقیه کدنویسی مکانیکی است»، میدانید تیم غرقشده و سفر طولانی به خانه در پیش دارید.
بخشهای مرتبط:
- گودال نیازمندیها، صفحه ۲۰۲
Challenges
نمودار use case بخشی از فرایند UML برای جمعآوری نیازمندیهاست (گودال نیازمندیها، صفحه ۲۰۲). آیا راه مؤثری برای ارتباط با کاربران شماست؟ اگر نه، چرا استفاده میکنید؟
چطور بفهمید روش رسمی به تیم سود میدهد؟ چه چیزی را میتوانید اندازه بگیرید؟ بهبود یعنی چه؟ آیا میتوانید بین سود ابزار و تجربه بیشتر اعضای تیم تمایز بگذارید؟
نقطه سر به سر برای معرفی روش جدید به تیم کجاست؟ چطور مزیت و هزینه بین سود آینده و افت بهرهوری فعلی حین معرفی ابزار را ارزیابی میکنید؟
آیا ابزارهایی که برای پروژههای بزرگ کار میکنند برای کوچک هم خوبند؟ برعکس چطور؟