ویرگول
ورودثبت نام
علی کریمی
علی کریمیعلی هستم. توی توسعه محصول فعالیت میکنم.
علی کریمی
علی کریمی
خواندن ۱۳ دقیقه·۵ ماه پیش

۱۱. نقشه‌برداری Scopeها - کتاب Shape Up

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

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

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

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

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

همانطور که در فصل قبل دیدیم، برش‌های کاری، وظایف Front-end و Back-end را یکپارچه می‌کنند. این به ما اجازه می‌دهد تا یک برش از پروژه واقعی را به پایان برسانیم و قطعاً به مرحله بعدی برویم. این رویکرد بهتر از داشتن قطعات زیادی است که – به امید آنکه – قرار است تا پایان چرخه به هم متصل شوند.

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

نقشه Scope

یک نمای بالا از پروژه را تصور کنید. در ابتدا، فقط یک طرح کلی از کار شکل‌دهی که مقدم بر پروژه بوده، وجود دارد. هنوز هیچ وظیفه یا Scopeای وجود ندارد.

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

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

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

Scopeها بخش‌های معنادار مسئله را منعکس می‌کنند که می‌توانند مستقل و در مدت زمان کوتاهی – چند روز یا کمتر – تکمیل شوند. آنها از وظایف بزرگ‌ترند اما از کل پروژه بسیار کوچک‌ترند.

نقشه یک تصویر ذهنی است. در عمل، ما Scopeها را به عنوان لیست‌های To-do تعریف و پیگیری می‌کنیم. هر Scope متناظر با نام یک لیست است. سپس هر وظیفه مربوط به آن Scope در آن لیست قرار می‌گیرد.

زبان پروژه

Scopeها چیزی بیش از برش‌ها هستند. آنها به زبان پروژه در سطح کلان تبدیل می‌شوند. وقتی قابلیت "مشتریان در پروژه‌ها" را می‌ساختیم، تیم از زبان Scopeها به این صورت استفاده می‌کرد: "بعد از اینکه Bucket Access انجام شد، می‌توانیم Invite Clients را پیاده‌سازی کنیم. سپس وقتی افراد شرکت Visibility Toggle را فعال کنند، ما Update Recording Visibility را انجام خواهیم داد".

هنگامی که زمان گزارش وضعیت فرا می‌رسد، تیم از زبان Scopeها برای توضیح اینکه چه چیزی انجام شده و چه چیزی انجام نشده است، استفاده می‌کند. داشتن مکالمه در سطح بالا و اشاره به قطعات نرم‌افزاری تکمیل شده رضایت‌بخش‌تر است، به جای اینکه وارد جزئیات و پیچیدگی‌های کار شویم و اهداف و وضعیت وظایف ناتمام فردی را توجیه کنیم. (در فصل بعدی بیشتر در مورد نحوه گزارش‌دهی Scopeها با استفاده از Hill Chart خواهیم دید).

مطالعه موردی: پیش‌نویس پیام‌ها

یک طراح و یک برنامه‌نویس در حال ساخت قابلیتی برای ایجاد و ذخیره پیش‌نویس پیام‌ها در یک اپلیکیشن جدید بودند. پس از جلسه آغاز پروژه (kick-off)، آنها انبوهی از وظایف را شناسایی کردند که باید در مقطعی انجام می‌دادند.

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

آنها Scope جدید را "Start New" نامیدند، لیستی از To-doها برای آن ایجاد کردند و To-doها را به آن منتقل کردند. تنها یک وظیفه طراحی برای آنها باقی مانده بود تا این Scope را تکمیل شده تلقی کنند.

پس از اتمام آن وظیفه طراحی، Scope کامل شد.

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

با نگاهی به وظایف باقی‌مانده، آنها تصمیم گرفتند وظایف مربوط به یافتن پیش‌نویس‌ها را در Scope جدیدی به نام "Locate" و وظیفه حذف را در Scopeای به نام "Trash" قرار دهند. به نظر می‌رسید تمام کارهای باقی‌مانده مربوط به ذخیره و ویرایش پیش‌نویس بود، بنابراین آن را "Save/Edit" نامیدند.

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

طراح مقداری کار روی "Locate" را شروع کرد در حالی که برنامه‌نویس روی "Save/Edit" تمرکز کرد. همین که او عمیق‌تر وارد کار شد، متوجه شد که می‌تواند چند بخش را جدا کند تا پیشرفت قابل مشاهده‌تری ایجاد شود. در واقع سه Scope در آن وجود داشت.

او ابتدا کار مربوط به ارسال پیام پیش‌نویس را تفکیک کرد. او آن را "Send" نامید.

سرانجام، برخی از وظایف باقیمانده "Save/Edit" مربوط به ذخیره‌سازی اطلاعات بودند و یکی دیگر در واقع نامرتبط بود – این یک مورد خاص برای مدیریت پیش‌نویس‌ها هنگام پاسخ دادن به پیام دیگری بود. او این‌ها را به دو Scope جدید تقسیم کرد: "Store" و "Reply".

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

در همین حال، طراح روی "Locate" پیشرفت کرده بود. پس از کمی تنظیمات اولیه (wiring)، آنها توانستند آن را به عنوان انجام شده علامت بزنند. وظایف روی "Send" و "Store" نیز در حال انجام بودند.

پس از اینکه "Send" و "Store" به پایان رسیدند، تنها چند وظیفه برای "Trash" و "Reply" باقی ماند.

و سپس پروژه به اتمام رسید.

کشف Scopeها

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

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

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

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

چگونه بفهمیم Scopeها درست هستند

Scopeهای خوب ساخته شده، ساختار (آناتومی) پروژه را نشان می‌دهند. وقتی در بدن خود دردی احساس می‌کنید، لازم نیست سوال کنید که آیا در بازوهایتان است یا پاهایتان یا سرتان. شما بخش‌ها و نام‌های آنها را می‌دانید تا بتوانید توضیح دهید درد کجاست. به همین ترتیب، هر پروژه یک ساختار طبیعی دارد که از طراحی مورد نظر شما، سیستمی که در آن کار می‌کنید، و وابستگی‌های متقابل مشکلاتی که باید حل کنید، ناشی می‌شود.

سه نشانه نشان می‌دهد که Scopeها درست هستند:

• شما احساس می‌کنید که می‌توانید کل پروژه را ببینید و هیچ چیز مهمی که شما را نگران می‌کند در جزئیات پنهان نیست.

• مکالمات در مورد پروژه روان‌تر می‌شوند زیرا Scopeها زبان مناسبی را به شما می‌دهند.

• وقتی وظایف جدیدی پیش می‌آید، می‌دانید کجا باید آنها را قرار دهید. Scopeها مانند سطل‌هایی عمل می‌کنند که به راحتی می‌توانید وظایف جدید را به آنها اضافه کنید.

از سوی دیگر، این سه نشانه نشان می‌دهد که Scopeها باید بازطراحی شوند:

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

• نام Scope خاص پروژه نیست، مانند "front-end" یا "bugs". ما اینها را "کیسه‌های شلوغ" (grab bags) و "کشوی خرت و پرت" (junk drawers) می‌نامیم. این نشان می‌دهد که شما به اندازه کافی یکپارچه‌سازی نمی‌کنید، بنابراین هرگز نمی‌توانید یک Scope را مستقل از بقیه "تکمیل شده" علامت بزنید. برای مثال، در مورد باگ‌ها، بهتر است آنها را تحت یک Scope خاص دسته‌بندی کنید تا بتوانید بدانید که آیا، برای مثال، Scope "Send" تمام شده است یا اینکه باید قبل از فراموش کردن آن، چند باگ را برطرف کنید.

• Scope برای اتمام زودهنگام خیلی بزرگ است. اگر یک Scope بیش از حد بزرگ شود، با وظایف بسیار زیاد، مانند یک پروژه مستقل با تمام نقص‌های یک لیست To-do اصلی طولانی می‌شود. بهتر است آن را به بخش‌هایی تقسیم کنید که در زمان کمتری قابل حل هستند، تا پیروزی‌هایی در طول مسیر و مرزهایی بین مشکلاتی که باید حل شوند، وجود داشته باشد.

بیایید این فصل را با چند نکته برای مقابله با انواع مختلف وظایف و Scopeهایی که پیش خواهند آمد، به پایان برسانیم.

کیک‌های لایه‌ای (Layer cakes)

بیشتر پروژه‌های نرم‌افزاری به مقداری طراحی UI و یک لایه نازک کد در زیر آن نیاز دارند. به یک اپلیکیشن پایگاه داده فکر کنید که در آن تنها کاری که باید انجام دهید وارد کردن اطلاعات، ذخیره آن و نمایش مجدد آن است. کاری مانند این شبیه یک کیک لایه‌ای به نظر می‌رسد: می‌توانید کار را بر اساس مساحت سطح UI قضاوت کنید زیرا کار Back-end کم و به طور یکنواخت توزیع شده است. در این موارد، می‌توانید تمام وظایف طراحی و برنامه‌نویسی را با هم در یک Scope یکپارچه کنید. این یک پیش‌فرض خوب برای بیشتر اپلیکیشن‌های نوع "سیستم اطلاعاتی" است.

اما گاهی اوقات کار Back-end به طور قابل توجهی بیشتر از کار UI است و بالعکس. به عنوان مثال، یک قابلیت جدید که تنها به ارسال یک فرم نیاز دارد، ممکن است برای بازگرداندن پاسخ صحیح به منطق تجاری (business logic) بسیار پیچیده‌ای نیاز داشته باشد. این نوع کار مانند یک کوه یخ (iceberg) است.

برای کوه‌های یخ، می‌تواند کمک‌کننده باشد که UI را به عنوان یک Scope کاری جداگانه تفکیک کنید (با فرض اینکه UI به پیچیدگی Back-end وابسته نیست). اگر Back-end به اندازه کافی پیچیده باشد، می‌توانید آن را به دغدغه‌های جداگانه تقسیم کنید و سپس آنها را نیز به Scope تبدیل کنید. هدف در چنین مواردی این است که چیزهای مختلفی را تعریف کنید که بتوانید آنها را در مراحل مختلف به اتمام رسانده و یکپارچه کنید، به جای اینکه تا دقیقه نود با امید اینکه همه چیز به هم متصل شود، منتظر بمانید.

شما گاهی اوقات کوه‌های یخ وارونه را نیز مشاهده می‌کنید، جایی که حجم زیادی از پیچیدگی UI با پیچیدگی Back-end کمتری وجود دارد. به عنوان مثال، مدل داده برای یک تقویم پیچیده نیست، اما تعامل برای نمایش یک رویداد چند روزه و پیچاندن آن در سلول‌های Grid می‌تواند زمان زیادی و حل مسئله زیادی را ببرد.

هم برای کوه‌های یخ Back-end و هم Front-end، ما همیشه قبل از پذیرش آنها به عنوان یک واقعیت، آنها را زیر سوال می‌بریم. آیا این پیچیدگی واقعاً ضروری و غیرقابل تقلیل است؟ آیا به آن UI فانتزی نیاز داریم؟ آیا راه دیگری برای ساخت آن فرآیند Back-end وجود دارد تا وابستگی‌های متقابل کمتری با بقیه سیستم داشته باشد؟

چاوْدِر (Chowder)

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

مشخص کردن موارد "اگر وقت شد خوب است" با علامت ~

وظایف جدید دائماً با عمیق‌تر شدن شما در یک مسئله ظاهر می‌شوند. شما کدی را پیدا خواهید کرد که می‌توان آن را مرتب کرد، موارد خاص (edge cases) را برای رسیدگی، و بهبودهایی را در قابلیت‌های موجود. یک راه خوب برای مقابله با تمام این بهبودها این است که آنها را به عنوان وظایف در Scope ثبت کنید اما در ابتدای آنها یک علامت ~ قرار دهید. این به همه اعضای تیم اجازه می‌دهد تا به طور مداوم موارد ضروری (must-haves) را از موارد "اگر وقت شد خوب است" (nice-to-haves) جدا کنند.

در دنیایی بدون مهلت، می‌توانستیم همه چیز را برای همیشه بهبود بخشیم. اما در یک بازه زمانی محدود (fixed time box)، ما به یک شمشیر (machete) در دستمان نیاز داریم تا Scope که دائماً در حال رشد است را کاهش دهیم. علامت ~ در ابتدای یک مورد، یا حتی یک Scope کامل، بهترین ابزار ما برای این کار است. ما به این تکنیک وقتی در مورد کاهش Scope در فصل ۱۴، "تصمیم بگیرید چه زمانی متوقف شوید"، صحبت کنیم، باز خواهیم گشت.

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