برخی از شما میدانید که من در صنعت پیمانکاری کار میکنم — که این موضوع به معنای آن است که تجربه فنی من حاصل کار روی پروژههای بسیار متنوع طی سالهاست — برخلاف شرکتهای محصولمحور که معمولاً تمام دوران حرفهای خود را روی یک محصول واحد کار میکنید. یکی از دوستانم که صاحب آژانس است، گفته: «یک سال در پیمانکاری برابر با سه سال در شرکت محصولمحور است.» میتوانید با این حرف موافق باشید یا مخالف، اما زندگی من پر از پروژههای متنوع روزانه از حوزههای مختلف با فروشندگان و مشتریان گوناگون است.
همانطور که احتمالاً حدس میزنید، این تجربه در طول زمان به دیدگاهی منحصربهفرد درباره دلایل شکست پروژهها تبدیل میشود — صرفنظر از صنعتی که پروژه در آن انجام میشود، چه کسی آن را رهبری میکند و ذینفعان چه کسانی هستند. گاهی اوقات، پروژهها شکست میخورند و نمیتوانید دقیقاً مشخص کنید چه چیزی اشتباه پیش رفته است.
تجربه من، هرچند کاملاً شخصی است، نشان میدهد حتی پروژههایی که بهخوبی برنامهریزی و تأمین مالی شدهاند نیز تمایل به شکست دارند. من در پروژههایی بودهام، حتی آنهایی که به نظر میرسد همه چیز به نفعشان است، اما همیشه احتمال برخورد با «کوه یخ» وجود دارد. مهلتهای زمانی، محدودیتهای بودجه، اختلاف بین افراد، ورود ذینفعان جدید و تمام این ماجراها از جمله دلایل آشکاری هستند که پروژه ممکن است از مسیر خود خارج شود؛ دلایلی که روی سطح قرار دارند و بهراحتی قابل مشاهدهاند.
اما قاتلان خاموش؟ اینها همان مشکلات ظریفی هستند که بهتدریج پدیدار میشوند — مسائلی که در نگاه اول چندان آشکار نیستند، اما اگر مراقب نباشید، میتوانند بهشدت زمانبندی شما را به هم بریزند.
در توسعه نرمافزار، اعتمادبهنفس بیشازحد خطرناک است! یک لطف کوچک میتواند بهسرعت به یک چالش عظیم تبدیل شود و اهمیت برآورد واقعبینانه وظایف و مدیریت صحیح پروژه را برجسته کند.
چرا پروژههای نرمافزاری شکست میخورند، موضوع جدیدی نیست، و این مقاله هم چیزی انقلابی ارائه نمیدهد. در هفته گذشته، دهها مقاله تخصصی درباره شکست پروژههای نرمافزاری خواندم و سعی کردم آنها را با تجربه خودم ترکیب کنم. این مقاله نتیجه این ترکیب است — و من بر موضوعاتی که قبلاً بهطور گسترده بحث شدهاند تمرکز نمیکنم. در عوض، سعی میکنم دلایلی نهچندان آشکار را نشان دهم که چرا پروژهها شکست میخورند.
توسعهدهندگان بیش از حد مطمئن
اعتمادبهنفس خوب است؛ اما اعتمادبهنفس بیشازحد، نه. یکی از چیزهایی که متوجه شدهام این است که توسعهدهندگان معمولاً نهتنها پیچیدگی وظایف را دستکم میگیرند، بلکه تواناییهای خود را هم دستبالا میگیرند:
- اعتمادبهنفس بیشازحد در مهارتهای کدنویسی.
- اعتمادبهنفس بیشازحد در یادگیری فناوریهای جدید.
- اعتمادبهنفس بیشازحد در انتزاعهای خود.
- اعتمادبهنفس بیشازحد در وابستگیهای خارجی مانند سرویسهای شخص ثالث یا کتابخانههای متنباز.
اگر از یک توسعهدهنده بپرسید که آیا تاکنون کد بدی نوشته است، بهاحتمال زیاد پاسخ منفی خواهد داد. من هم مقصر این موضوع هستم. به یاد ندارم که تاکنون کد بدی نوشته باشم؛ البته، برخی از کدهایم کامل نبوده و قابل بهبود بوده، اما فکر نمیکنم وحشتناک بوده باشد. با این حال، اگر از کسانی که کدهایم را بازبینی کردهاند بپرسیم، احتمالاً پاسخ مثبت است؛ برخی از کدها احتمالاً افتضاح بودهاند.
بهطور میانگین، من کد خوبی مینویسم؛ بهطور میانگین، میتوانم یک وظیفه را نسبتاً سریع حل کنم؛ بهطور میانگین، میتوانم ماژولی را بهموقع بسازم.
برآورد زمانبندی پروژه میتواند یک چالش پرآشوب باشد! برای حفظ پروژههای نرمافزاری در مسیر درست و جلوگیری از شکستهای پرهزینه، باید از اعتمادبهنفس بیشازحد و انتظارات غیرواقعبینانه پرهیز کرد.
اگر از من بپرسید آیا میتوانم ویژگی خاصی را در سه هفته بسازم، پس از تحلیل نیازمندیها، با اعتمادبهنفس به شما میگویم که بر اساس عملکرد گذشتهام، چنین کارهایی را قبلاً انجام دادهام و مطمئنم میتوانم دوباره آن را انجام دهم. اما همیشه موارد استثنایی وجود دارد و ما آنها را در برآوردها نادیده میگیریم. ما، بهعنوان توسعهدهندگان نرمافزار، مقصر اعتمادبهنفس بیشازحد هستیم که به شکست پروژههای نرمافزاری منجر میشود.
💡 همچنین مفهومی به نام «خطای برنامهریزی» وجود دارد که توسط روانشناسان دنیل کانمن (Daniel Kahneman) و آموس تورسکی (Amos Tversky) ابداع شده و به گرایش ما به خوشبینی بیشازحد درباره توانایی تکمیل سریع وظایف اشاره دارد.
یکی دیگر از نمونههای عالی اعتمادبهنفس بیشازحد، انتزاعهای ضعیف است. مگر اینکه در دنیایی کامل زندگی کنید، احتمالاً میدانید که تکرار بهتر از انتزاع بد است. مشکل این جمله در این است که شما همیشه فرض میکنید انتزاع شما بهتر است — شما که یک برنامهنویس تازهکار نیستید، به مهارتهای خود مطمئنید (یا بهتر بگوییم، بیشازحد مطمئنید)، میدانید چه میکنید، میخواهید همه چیز را مرتب و تمیز کنید و قبلاً دهها بار این کار را انجام دادهاید. کد عالی به نظر میرسد و احتمالاً از بازبینی کد هم عبور میکند.
اما پس از مدتی، نیازهای جدیدی ظاهر میشوند که تقریباً با انتزاع موجود مطابقت دارند، اما نه کاملاً — کسی انتزاع را اصلاح میکند، پارامتری اضافه میکند، شرطی اضافه میکند، یا دستورات سوئیچ اضافه میکند. این روند چندین بار تکرار میشود و در نهایت با قطعه کدی مواجه میشوید که آنقدر پیچیده شده که هیچکس نمیخواهد آن را لمس کند. همه به استفاده از این انتزاع بیشازحد ادامه میدهند، چون فکر میکنند این کد توسط کسی که از آنها باهوشتر بوده نوشته شده — و این چرخه ادامه مییابد تا زمانی که کسی شجاعانه با این پیچیدگی مقابله کند و دوباره با افزودن تکرار، کد را ساده کند.
مشکل انتزاعهای بد این است که اثر آنها روی زمانبندی پروژه مانند یک گلوله برفی است. در ابتدای پروژه، هر ویژگی مرتبط با آن انتزاع بهموقع انجام میشود و هیچ هشدار جدیای نمیدهد، اما با طولانیتر شدن پروژه، زمان لازم برای تغییر انتزاع بهصورت تصاعدی افزایش مییابد تا جایی که انتزاع غیرقابلنگهداری و گسترشناپذیر میشود. تأخیرها روی هم انباشته میشوند تا جایی که پروژه متوقف میشود.
یک مثال حتی بهتر از اعتمادبهنفس بیشازحد، منحنی یادگیری فناوریهای جدید است. اگر قبلاً با Golang برنامهنویسی کردهاید و پروژه قرار است با Rust انجام شود، چقدر تلاش نیاز دارید تا در این زبان به مهارت برسید؟ توسعهدهندگان اغلب بدون درک کامل زمان و تلاش لازم برای تسلط بر فناوری جدید، به آن روی میآورند. این دستکم گرفتن منجر به تأخیرهایی میشود، زیرا منحنی یادگیری تند بهاندازه کافی در زمانبندی پروژه یا ارزیابی ریسکها لحاظ نشده است. اگر عمیقتر شویم — فناوریهای جدید همیشه این خطر را دارند که چارچوب/زبان/درایور/آداپتور آنها محدودیتهایی داشته باشد که تیم شما هنوز از آنها آگاه نیست، و این امر به یافتن راهحلهایی برای انجام کارها منجر میشود.
نیاز به یافتن راهحلها حتی در مورد وابستگیهای خارجی و فروشندگان شخص ثالث بیشتر صدق میکند — هر چیزی که مستقیماً تحت کنترل شما نیست، خطر پیچیدگیهای پنهان را به همراه دارد. فرض اینکه سرویسها، کتابخانهها، بستهها یا APIهای شخص ثالث همانطور که انتظار میرود بدون اشکال کار کنند، یک غفلت رایج است. مگر اینکه در حال ساخت برنامههای ساده CRUD باشید، پروژهها اغلب زمانی از مسیر خود خارج میشوند که این وابستگیهای خارجی منسوخ شوند، با سایر وابستگیها ناسازگار شوند، یا بهطور کلی ارائه خدمات را متوقف کنند.
برنامهریزی برای این موارد دشوار است. ما بیشازحد مطمئن هستیم، چون در حالت کلی، اوضاع خوب پیش میرود — مگر زمانی که اینطور نشود. اگر بخواهیم این موضوع را کمی کنیم و احتمال شکست را در تعداد توسعهدهندگان یک پروژه ضرب کنیم، حتی بهترین پروژهها، اگر بهاندازه کافی بزرگ شوند، صددرصد شانس دارند که یا از بودجه فراتر بروند یا با تأخیر تحویل داده شوند.
مدیران بیتجربه
خب، چیز بعدی که نمیتوانید برای آن برنامهریزی کنید چیست؟ حدس زدید: بیتجربگی و/یا بیکفایتی و/یا سهلانگاری. من این مفاهیم را بهطور متناوب استفاده میکنم، چون هرگز نمیدانید کجا یکی تمام میشود و دیگری شروع. فاصله زیادی بین آنچه یک مدیر را در نظر مدیران بالادست موفق میسازد و آنچه واقعاً به نفع پروژه و تیم است وجود دارد.
اولویتهای نامتناسب در جلسات مدیریتی اغلب به شکست پروژهها منجر میشوند. درک این فاصله بین اهداف توسعهدهندگان و تصمیمات رهبری برای موفقیت در نرمافزار بسیار حیاتی است.
در یک سوی طیف، مدیری است که بیشتر به جاهطلبیهای شخصی خود اهمیت میدهد تا موفقیت پروژه. نمونه خوب این مورد توسعه مبتنی بر ترفیع است، جایی که مدیران قبل از تکمیل پروژهها آنها را ترک میکنند و از موقعیت خود برای پیشرفت شغلی استفاده میکنند. قانون پیتر میگوید افراد تا بالاترین سطح بیکفایتی خود ترفیع میگیرند. این به این معنا نیست که این مدیران ذاتاً در کار خود بد هستند؛ فقط مهارتهایی که به آنها ترفیع دادهاند همان مهارتهای لازم برای هدایت پروژه به سمت موفقیت نیستند — اینها مجموعه مهارتهای متفاوتی هستند.
در سوی دیگر، مدیران کمتجربهای قرار دارند که: الف) فرض میکنند شخص دیگری کار را انجام خواهد داد و ب) فکر میکنند کارشان فقط راضی نگهداشتن همه سهامداران و گفتن “بله” به هر چیزی است. آنها ضرورت برنامهریزی محکم و قوی را نادیده میگیرند و باعث ایجاد بدهیهای فرآیندی و گسترش بیرویه پروژه میشوند.
اگر این علائم هشداردهنده را میبینید، باید زنگ خطر را به صدا درآورید:
- اطلاعات از مدیریت بالادست به اشتراک گذاشته نمیشود و تیم را در بیخبری از پیشرفتهای کلی پروژه نگه میدارند. من این را “به من اعتماد کن، در مسیر درستی هستیم” مینامم.
- وظایف بدون ارائه زمینه، منابع لازم یا اطلاعات تماس تنها با ذکر ضربالاجلها واگذار میشوند. من این وظایف را “خودت پیدا کن” مینامم.
- اغلب کار تیم را طوری ارائه میدهند که انگار خودشان مسئول تمام آن بودهاند، از مدیران بالادست تشویق میگیرند اما این تشویق را با تیم به اشتراک نمیگذارند.
- همیشه از پذیرش مسئولیت میترسند، هرگز بهتنهایی تصمیم نمیگیرند، و تصمیمات را به مدیریت بالادست که فقط خودشان اجازه صحبت با آن را دارند واگذار میکنند.
- در مقابل مدیران بالادست، تیم را برای اشتباهات سرزنش میکنند.
اینها تنها برخی از ویژگیهای یک مدیر بیتجربه هستند؛ اگر موارد بیشتری دارید، به من بگویید.
بزرگترین اشتباه یک مدیر بیتجربه این است که تغییرات مکرر در محدوده پروژه را بپذیرد، بهویژه تغییراتی که از سوی مدیران بالاتر اعمال میشوند، بدون در نظر گرفتن پیامدها. برای مثال، “مدیرعامل گفت دخترش فکر میکند که باید گزینه ورود با TikTok به اپلیکیشن بانکداری ما اضافه شود، و به نظرم ایده عالیای است!” این کار باعث ناامیدی تیم، فشار بر منابع و تغییر اولویتها میشود که در نهایت به شکست پروژه منجر میشود.
سهامداران مدیریتنشده
جهتگیری واقعی هر پروژه باید ارزش آن باشد – ارزشی واقعی، ملموس، و همسو با اهداف کسبوکاری که به دنبال تحقق آن است. هیچکس نمیخواهد پروژهای بسازد که فقط منابع را هدر دهد، درست است؟ البته که نه، اما مشکل اینجاست که معمولاً تا دیر نشده نمیتوان فهمید پروژه به یک “زامبی” تبدیل شده است.
ذهن ما گاهی ما را فریب میدهد – تعصب تأییدی باعث میشود نسبت به نشانههایی که نشان میدهند پروژه در مسیر اشتباه قرار دارد، نابینا شویم. از سوی دیگر، “هیوریستیک احساسی” (affect heuristic) باعث میشود جنبههای منفی را نادیده بگیریم و جنبههای مثبت را بزرگ جلوه دهیم، بهویژه وقتی از لحاظ احساسی روی موفقیت پروژه سرمایهگذاری کردهایم.
این پروژهها همیشه با یک وعده شروع میشوند – یک هدف مشخص، یک چشمانداز همسو با استراتژی شرکت، پیشبینیهای مالی معقول، و یک جدول زمانی توسعه مناسب. در ابتدا به نظر میرسد فرصت فوقالعادهای باشد؛ در ۳۰ تا ۴۰ درصد ابتدایی پروژه، سخت است که مشکلی را تشخیص دهید.
اما بعد اوضاع تغییر میکند و چالشهای غیرمنتظره پدیدار میشوند.
فناوریای که به نظر ساده میرسید، سر ناسازگاری میگذارد، رقبا ایدههای مشابهی را عرضه میکنند، شرکای کلیدی از پروژه کنار میکشند، و سهامداران تجاری داخلی روی پروژههایی که “AI” در نامشان باشد تمرکز میکنند. کارها کند میشود و وقتی ماهها به سال تبدیل میشوند، شور و اشتیاق کاهش مییابد.
بعد این وضعیت مثل بهمن ادامه پیدا میکند – اعضای کلیدی تیم پروژه را ترک میکنند و افراد جدید به تیم ملحق میشوند. هر خروجی تغییر کوچکی در مسیر پروژه ایجاد میکند. وقتی یک رهبر فنی جدید وارد میشود و تلاش میکند اثر خود را بگذارد، پروژه بیشتر از مسیر اولیهاش منحرف میشود. در این مرحله، هیچکس نمیداند پروژه به کجا میرود و هیچکس نمیخواهد اعتراف کند که پروژه شکست خورده است. موقعیت دشواری است، بهخصوص وقتی همه تلاش میکنند از شرمساری یا پیامدهای پذیرش شکست دوری کنند.
💡 قاتل خاموش در این سناریو فقط شکست پروژه در ارائه ارزش نیست؛ بلکه بیمیلی جمعی به پذیرش این شکست است. ترس از پذیرش شکست و رویارویی با پیامدهای پروژهای که به بیراهه رفته، مانع پیشرفت تیم میشود.
چرا؟ خب، این کار ناخوشایند است، درست است؟ پذیرفتن شکست یعنی مواجهه با برخی حقایق ناخوشایند. هیچکس نمیخواهد حامل خبر بد باشد؛ هیچکس نمیخواهد نامش با پروژهای که شکست خورده گره بخورد. بنابراین، پروژه را زنده نگه میدارند، از بودجهبندی خلاقانه استفاده میکنند، بیش از حد وعده میدهند و دائماً موفقیت را به آینده موکول میکنند، به این امید که معجزهای رخ دهد یا به پروژه دیگری منتقل شوند.
در عمق وجودشان، همه حقیقت را میدانند، اما هرگز آن را نمیپذیرند. این پروژه به اهدافش نمیرسد؛ یا منتشر نمیشود، یا اگر هم منتشر شود، وضعیت مالی خوبی نخواهد داشت. این پروژه قرار نیست بازار را متحول کند. فقط… به مصرف منابع ادامه میدهد بدون اینکه واقعاً چیزی به دست آورد.
عبور از موانع پروژه نیازمند صداقت و ارتباطات مؤثر است. شناسایی زودهنگام مشکلات میتواند به تصمیمگیری بهتر منجر شود و در نهایت منابع را نجات دهد.
وقتی چنین پروژههای نرمافزاری شروع به شکست میکنند، یک طرز فکر منفی به سرعت گسترش مییابد. بهجای رفع مشکلات، افراد میگویند: “خب، این کار من نیست.” یا “من کار خودم را انجام میدهم؛ بقیه موارد به من ربطی ندارد.” همه در حال محافظت از خودشان هستند و تلاش میکنند از پیامدها دوری کنند. این نگرش مانع از هرگونه تلاش واقعی برای حل مشکلات میشود و مسائل پروژه را عمیقتر کرده و بازیابی را دشوارتر میکند.
وقتی نگرش “مشکل من نیست” غالب میشود، بذر یک فرهنگ سمی کاشته میشود. در چنین محیطی، از مسئولیتپذیری فرار میشود و همکاری کاهش مییابد. اعضای تیم فقط روی وظایف خود تمرکز میکنند و تصویر بزرگتر و هدف جمعی را نادیده میگیرند. این عدم مسئولیت مشترک منجر به انتقال سرزنش در مواقع بروز مشکل میشود و فضایی از بیاعتمادی ایجاد میکند. انرژیای که میتوانست برای حل مشکلات استفاده شود، در سیاستهای داخلی و محافظت از منافع شخصی هدر میرود.
نتیجهگیری
پروژهها شکست میخورند. درست است، دردناک است، اما حقیقت دارد. مسئله فقط کدنویسی ضعیف یا مهلتهای زمانی گذشته نیست. بیتجربگی، غرور، اعتماد به نفس بیش از حد – همه این ویژگیهای انسانی تأثیر زیادی دارند. پس بیایید تلاش کنیم از آنها اجتناب کنیم و الگوهای بهتری باشیم!