چابک‌کار

وبلاگ محمدحسین احمدی دربارهٔ فرایند توسعهٔ نرم‌افزار (و موضوعات دیگر)

چابک‌کار

وبلاگ محمدحسین احمدی دربارهٔ فرایند توسعهٔ نرم‌افزار (و موضوعات دیگر)

  • ۰
  • ۰

روش رایج در همهٔ رشته‌های مهندسی این است که ابتدا محصول نهایی را «طراحی» می‌کنند و بعد از اینکه از صحت طراحی مطمئن شدند، پیاده‌سازی را انجام می‌دهند. به این روش Big Design Up Front (طراحی بزرگ در ابتدا) یا BDUF نیز می‌گویند. اگر غیر از این انجام شود، همگان - از مهندسان برق و عمران گرفته تا مهندسان نفت و پتروشیمی - توافق دارند که کار غیرحرفه‌ای و کم‌کیفیت انجام شده است. به همین دلیل در مهندسی نرم‌افزار سنتی هم فرض بر همین بوده: فقط وقتی کُدنویسی را باید شروع کرد که طراحی کاملاً انجام شده باشد.

اما تجربهٔ واقعی مهندسان نرم‌افزار چه بوده؟ آن‌ها مشاهده کرده‌اند که:

  • نهایی کردن طراحی بسیار سخت است: چون نیازهای مشتری - همان‌طور که در مطلب قبلی گفتیم - در طول توسعه و نگهداری محصول مرتب عوض می‌شوند و گسترش می‌یابند، باید طراحی نیز مرتباً تغییر کند.
  • محدودیت‌های جدیدی - که در زمان طراحی مشخص و واضح نبوده‌اند - در هنگام پیاده‌سازی یا نگهداری کشف می‌شوند که به خاطر آن‌ها طراحی باید تغییر کند، یا اینکه قابلیت‌های جدیدی در تکنولوژی پیاده‌سازی پیدا می‌شود که قبلاً طراحان از آن اطلاعی نداشته‌اند و در نتیجه طراحی‌شان بهینه نیست. مثلاً مشخص می‌شود که یک مؤلفهٔ آمادهٔ مورد استفاده، تحت بار زیاد دچار مشکلاتی در کارایی و پایداری می‌شود. یا اینکه یک کتابخانهٔ متن‌باز پیدا می‌شود که نیاز به توسعهٔ بخشی از سیستم را مرتفع می‌کند.
  • و مهم‌تر از همه، در اکثر پروژه‌ها بعداً کشف می‌شود که طراحی، علی‌رغم وقت و انرژی زیادی که صرف آن شده بوده است، آنقدرها هم مناسب و بی‌نقص نبوده است: خیلی از نیازهای مشتری را نمی‌تواند پشتیبانی کند و در برخی قسمت‌ها هم بیش از حد پیچیده - و پرهزینه در پیاده‌سازی - شده است. مثلاً نیاز جدیدی پیش می‌آید که نیاز به تغییرات بزرگ در طراحی دارد. یا بالعکس، برخی از نیازها که در طراحی دیده شده بود، هیچ وقت پیش نمی‌آیند و فقط پیچیدگی طراحی برای ما می‌ماند!

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

طراحی تدریجی

بنابراین رویکرد نوین نسبت به طراحی نرم‌افزار این است که طراحی را کم‌کم انجام دهیم و هر بار با پیاده‌سازی و آزمون و ترجیحاً تحویل به مشتری و رفتن نرم‌افزار زیر بار، از خوب بودنش مطمئن شویم. منظور از «کم‌کم» این است که هر بار، طراحی را با توجه به بخش کوچکی از نیازمندی‌های مشتری تغییر دهیم طوری که این نیازمندی‌ها + نیازمندی‌های قبلاً محقق شده، برآورده شوند.

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

  • محمدحسین احمدی
  • ۰
  • ۰

همان‌طور که قبلاً نوشته بودم، یکی از باورهای رایج در توسعهٔ نرم‌افزار این است که باید ابتدا «مسئله» را خوب شناخت و بعد آن را حل کرد، یعنی اول باید نیازمندی‌های مشتری را کامل استخراج، تحلیل و درک کنیم تا بعدش بتوانیم وارد طراحی و پیاده‌سازی راه‌حل شویم.

ظاهر این باور خیلی منطقی است؛ شاید بپرسید: «مگه کار دیگه‌ای هم می‌شه کرد؟» یا «نکنه منظورتون اینه که قبل از شناخت مسئله به دنبال راه‌حل بریم؟ این که خیلی بده!»

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

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

اینطوری حتی کارتان سریع‌تر هم پیش می‌رود، چون راه‌حل اشتباهی تولید نمی‌کنید یا اگر تولید کنید، زودتر معلوم می‌شود. به مرور راه‌حل شما کامل‌تر و بیشتر مطابق نیازهای مشتری‌تان خواهد شد. حتی اسکات امبلر - یکی از پیشگامان حوزهٔ مهندسی نرم‌افزار شیءگرا - استدلال می‌کند که وقتی ابتدا و قبل از توسعهٔ نرم‌افزار، سعی می‌کنیم کل نیازمندی‌ها را تشریح کنیم، نزدیک دوسوم سرمایه‌گذاری ما در تولید آن نرم‌افزار به هدر می‌رود.


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

  • محمدحسین احمدی
  • ۰
  • ۰

معجزهٔ iteration

فرد بروکس (Fred Brooks) که یکی از پیشگامان حوزهٔ مهندسی نرم‌افزار است، یک مقالهٔ معروف دارد به نام No Silver Bullet که در آن می‌گوید هیچ راهکار معجزه‌آسایی برای موفقیت پروژه‌های نرم‌افزاری وجود ندارد. هرچند گذشت سی سال از انتشار این مقاله صحت این ادعا را در عمل نشان داده، ولی برخی نوآوری‌ها در توسعهٔ نرم‌افزار وجود دارند که دست‌کمی از معجزه ندارند. یکی از آن‌ها توسعهٔ تکراری-نموی یا همان iterative-incremental است.

این یعنی این که به جای اینکه پروژه را «بزرگ» انجام دهیم، یعنی مثلاً:

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

پروژه را به قطعات کوچکی به نام iteration (حداکثر دو ماهه، ترجیحاً کمتر) تقسیم کنیم و هر قطعه را جداگانه توسعه داده و تحویل دهیم، یعنی:

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

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


آیا عجیب نیست که هنوز خیلی از پروژه‌ها به این روش انجام نمی‌شوند؟ شاید به این خاطر است که مدیران و مجریان این پروژه‌ها فکر می‌کنند «کار اصولی و مهندسی» این است که کار به روش «بزرگ» انجام شود چون به قول آن‌ها پروژه صفات دهن‌پرکنی مثل «بزرگ» یا Enterprise دارد! این مدیران و مجریان نه تنها نیاز دارند که روش فکر خود را عوض کنند، بلکه به نفعشان است که دانسته‌هایشان را هم دربارهٔ مدیریت پروژه‌های نرم‌افزاری به‌روز کنند. در این باره در آینده بیشتر خواهیم نوشت.

  • محمدحسین احمدی
  • ۰
  • ۰
روش‌های چابک توسعهٔ نرم‌افزار چند سال است که باب شده‌اند و به نوعی «مد روز» محسوب می‌شوند. اما توسعهٔ چابک نرم‌افزار دقیقاً یعنی چه؟ اگر در این باره در وب فارسی بگردید، تک و توک مطالب خوبی پیدا می‌کنید، مثل این یا این. اما در اینجا می‌خواهم چابکی در توسعهٔ نرم‌افزار را به روش خودم تعریف کنم:
روش‌های چابک تعدادی از فرضیات اساسی و رایج در توسعهٔ نرم‌افزار را زیر سؤال می‌برند.
این فرضیات چه هستند؟ برخی از مهم‌ترین آن‌ها را در ادامه آورده‌ام:
  1. اگر بخواهیم اصولی نرم‌افزار تولید کنیم، باید فعالیت‌هایی مثل تحلیل نیازمندی‌ها، معماری و طراحی، پیاده‌سازی و آزمون را به ترتیب انجام دهیم. چند باور رایج زیر هم حالت‌های خاصی از همین فرض هستند:
    1. باید همه یا عمدهٔ نیازهای مشتری در ابتدا معلوم شوند وگرنه نمی‌توان طراحی و پیاده‌سازی را شروع کرد.
    2. باید اول طراحی را نهایی کنیم و بعد پیاده‌سازی را انجام دهیم. تغییر زیاد در طراحی در حین پیاده‌سازی خوب نیست و نوعی دوباره‌کاری است که باعث اتلاف وقت می‌شود.
    3. تغییر زیاد در نیازمندی‌ها در حین طراحی و پیاده‌سازی خوب نیست و نشانهٔ این است که نیازمندی‌ها به درستی در ابتدا جمع‌آوری و تحلیل نشده‌اند.
    4. باید مؤلفه‌های مختلف نرم‌افزار، اول تولید شوند و بعداً یکپارچه‌سازی شوند.
    5. باید صبر کنیم تا پیاده‌سازی نرم‌افزار تمام شود تا بعدش آن را آزمون کنیم، وگرنه مجبور هستیم بعد از هر تغییر مرتباً همان آزمون‌های قبلی را دوباره انجام دهیم که دوباره‌کاری است و خوب نیست.
  2. اگر بخواهیم اصولی نرم‌افزار تولید کنیم، باید فعالیت‌های مختلف توسعهٔ نرم‌افزار توسط متخصص آن فعالیت‌ها انجام شوند، یعنی مثلاً کار تحلیل را تحلیلگر انجام دهد و کار طراحی را طراح. وقتی کار بزرگ می‌شود، هر کدام از این فعالیت‌ها را باید به یک تیم تخصصی جداگانه داد.
  3. نباید اجازه داد برنامه‌نویسان مستقیماً با مشتری/کاربر در تماس باشند، بلکه همهٔ روابط با مشتری/کاربر باید از طریق مدیر باشد.
  4. هر تیمی نیاز به یک مدیر دارد تا وظایف اعضا را به آن‌ها تخصیص داده و پیگیری کند تا انجام شوند.
  5. اگر بخواهیم اصولی نرم‌افزار تولید کنیم، باید توسعهٔ نرم‌افزار را مثل یک فرایند تولید صنعتی ببینیم و با فرایندهای تعریف شده و مشخص آن را انجام دهیم. برای مدیریت پروژه‌های نرم‌افزاری باید از تجربیات سایر صنایع در تولید انبوه و مدیریت پروژه‌های صنعتی الهام بگیریم.
  6. هر چه تیم توسعهٔ نرم‌افزار بزرگ‌تر باشد، خروجی کار از نظر ویژگی‌ها، زمان، هزینه و کیفیت بهتر خواهد بود.
  7. اگر مستنداتی مفصل از مدل‌های گرافیکی (مثلاً نمودارهای مختلف UML) برای تحلیل و طراحی تولید نکنیم، کار مهندسی نرم‌افزار را به درستی انجام نداده‌ایم. ایجاد این مدل‌ها یکی از مهم‌ترین فعالیت‌های توسعهٔ نرم‌افزار است.
فرضیات فوق در نگاه اول خیلی منطقی و اصولی به نظر می‌رسند، اما روش‌های چابک نشان می‌دهند که این فرضیات لزوماً همیشه درست نیستند. اما در ضمن یک نکتهٔ مهم دیگر هم وجود دارد:
فرضیات فوق بی‌ارزش نیستند و شمّه‌ای از حقیقت در همهٔ آن‌ها وجود دارد.
این نکته خیلی مهم است چون باعث می‌شود از آن طرف پشت بام نیفتیم: چابکی به معنای نفی انضباط و قاعده‌مندی، نفی دستاوردهای مهندسی نرم‌افزار، نفی تحلیل و طراحی و مدل‌سازی، نفی نیاز به مدیریت پروژه، نفی نیاز به متخصص و نفی نیاز به مستندسازی نیست!

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

قصد دارم در اینجا دربارهٔ بعضی از چیزهایی که در زمینهٔ توسعهٔ چابک نرم‌افزار، چابک‌سازی گروه‌های توسعهٔ محصول و در حالت عام‌تر تغییر سازمان‌ها یا نمی‌دانم یا فکر می‌کنم می‌دانم صحبت کنم و از خوانندگان وبلاگم چیز یاد بگیرم.

همه چیز از روزی شروع شد که یکی از دوستانم را پس از مدت‌ها تصادفاً دیدم، و به من پیشنهاد کاری در زمینهٔ کمک به تیم‌های نرم‌افزاری برای بهبود تولید نرم‌افزارشان را داد. نتوانستم در مقابل وسوسهٔ جذابیت چنین کاری مقاومت کنم، و اینطوری شد که در نهایت سر از وادی Agile و Scrum و XP و TDD در آوردم و برایم تبدیل به یک مشغلهٔ کاری و ذهنی چندساله شد.

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

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