چرا بیشتر پروژههای نرمافزاری قبل از شروع توسعه شکست میخورند؟
وقتی مسئله، scope و operational reality روشن نیست، feature list جایگزین strategy میشود — و هزینه بعداً ظاهر میشود.
بسیاری از پروژههای نرمافزاری قبل از اینکه اولین خط کد نوشته شود، نتیجهشان مشخص شده است — نه بهخاطر بدشانسی، بلکه بهخاطر اینکه «شروع توسعه» جایگزین «فهمیدن مسئله» شده است.
در عمل، شکست در این مرحله معمولاً به معنای کنسل شدن پروژه نیست. پروژه ادامه پیدا میکند؛ بودجه خرج میشود؛ تیمها درگیر میشوند؛ ولی محصولی که تحویل داده میشود یا به کار کسی نمیآید، یا بیش از حد برای نگهداری هزینه دارد، یا هر تغییر کوچکش ماهها طول میکشد. از بیرون شبیه «پروژه ناموفق» به نظر میرسد؛ از داخل، بیشتر شبیه مجموعهای از تصمیمهای زودهنگام و برگشتناپذیر است.
وقتی مسئله هنوز تعریف نشده، feature جایگزین strategy میشود
یکی از رایجترین الگوها این است که تیم — یا مشتری — مستقیماً وارد لیست قابلیتها میشود: «پنل ادمین میخواهیم، گزارش میخواهیم، اپ موبایل هم باشد.» هر مورد بهتنهایی منطقی است، اما بدون پاسخ به سؤال «این محصول برای چه کسی و با چه معیار موفقیتی ساخته میشود؟»، feature list فقط یک backlog بدون جهت است.
تعریف مسئله خوب لزوماً سند ۱۰۰ صفحهای نیست. لازم است بدانیم:
- کاربر اصلی کیست و چه کاری را امروز به شکل ضعیفتری انجام میدهد؟
- موفقیت برای کسبوکار یعنی چه — فروش، کاهش هزینه، انطباق، سرعت عملیات؟
- چه چیزی عمداً خارج از scope است؟
وقتی اینها روشن نیست، هر تصمیم فنی بعدی بر پایه حدس بنا میشود. تیم مهندسی مجبور میشود برای سناریوهایی طراحی کند که شاید هیچوقت رخ ندهند، یا برعکس، برای سناریوهای حیاتی آماده نباشد.
feature-first thinking: ساختن قبل از فهمیدن
feature-first thinking یعنی ارزش محصول را با تعداد صفحه، ماژول یا integration اندازه بگیریم. نتیجه معمولاً یک سیستم پر از قابلیتهای نیمهکاره است که هیچکدام end-to-end درست کار نمیکنند.
در Product Discovery — که Marty Cagan در Inspired روی آن تأکید دارد — هدف این نیست که همه چیز را قبل از build قطعی کنیم؛ هدف این است که قبل از commit کردن به یک مسیر گران، ریسکهای اصلی را ارزان آزمایش کنیم. گاهی این آزمایش با مصاحبه کاربر است، گاهی با prototype، گاهی با spike فنی. اما «شروع sprint اول» بدون هیچکدام از اینها، discovery نیست؛ فقط عجله است.
زمینه کاربر و کسبوکار: دادهای که در backlog نیست
backlog میگوید چه بسازیم؛ زمینه میگوید چرا. بدون زمینه، اولویتبندی تبدیل به سلیقه میشود: آخرین نفر مهمترین صدا را دارد، یا featureای که demo خوبی میدهد جلو میافتد.
برای محصول B2B، زمینه شامل فرایند فعلی تیم مشتری، نقشهای تصمیمگیر، و هزینه خطا است. برای محصول consumer، رفتار واقعی مهمتر از نظر اعلامی است. اگر این اطلاعات در discovery جمع نشود، معماری و UX هر دو بر پایه personaهای خیالی طراحی میشوند.
معماری: خیلی زود یا خیلی دیر
دو خطای رایج در معماری وجود دارد:
معماری قبل از فهم مسئله: microservices، event-driven، multi-tenant — همه میتوانند درست باشند، اما اگر قبل از اینکه بدانیم محصول چه scale و چه complexity واقعی دارد انتخاب شوند، فقط operational burden زودتر وارد سیستم میشود.
بدون معماری وارد کدنویسی شدن: «بعداً refactor میکنیم» در تئوری درست است، اما اگر هیچ مرزی بین domainها، لایهها، و مسئولیت سرویسها تعریف نشود، technical debt از هفتههای اول شروع میشود — نه ماهها بعد.
تعادل درست این است: برای ریسکهای شناختهشده تصمیم بگیرید، برای ریسکهای نامشخص مرزهای loose بگذارید. مثلاً اگر integration با ERP قطعی است، adapter layer از روز اول منطقی است. اگر فقط «شاید بعداً CRM وصل کنیم» دارید، abstraction سنگین احتمالاً زود است.
integrationهای پنهان و پیچیدگی عملیاتی
در بسیاری از پروژهها، تخمین فقط frontend/backend را میشمارد. در حالی که بخش قابل توجهی از زمان واقعی صرف میشود برای:
- احراز هویت سازمانی (SSO، SAML، نقشها)
- پرداخت، فاکتور، یا workflow مالی
- migration داده از سیستم قدیمی
- رعایت compliance و نگهداری audit trail
- deploy در محیطی که DevOps بالغ ندارد
این موارد در demo دیده نمیشوند، اما production را میسازند. اگر در discovery کشف نشوند، «تأخیر پروژه» در واقع کشف دیرهنگام complexity است.
technical debt قبل از launch
technical debt همیشه بد نیست؛ borrow کردن عمدی برای یادگیری یا رسیدن به market سریعتر قابل دفاع است. مشکل وقتی است که debt ناخودآگاه و بدون plan بازپرداخت ایجاد شود: بدون test، بدون logging، بدون migration strategy، بدون security review.
یک MVP واقعی — برخلاف تصور رایج — لزوماً «کثیفترین نسخه ممکن» نیست. باید در scope کوچک باشد، اما در مسیرهایی که بعداً غیرقابل برگشت هستند (مدل داده، auth، observability پایه) عمداً کوتاه نیافت.
definition of done: وقتی «تمام شد» معنی ندارد
بدون definition of done مشترک، «done» برای developer یعنی merge شد؛ برای product یعنی deploy شد؛ برای مشتری یعنی کاربر واقعی از آن استفاده میکند و ارزش میگیرد. این سه با هم یکی نیستند.
حداقل DoD برای محصول جدی شامل موارد زیر است:
- تستهای critical path
- monitoring و alerting پایه
- rollback plan
- مستندات operability (نه لزوماً wiki عظیم)
- بازبینی امنیتی برای surfaceهای exposed
اگر DoD قبل از development تعریف نشود، هر sprint «تحویل» میدهد اما محصول به production readiness نزدیک نمیشود.
discovery: چه زمانی لازم است و چه زمانی overkill
discovery برای هر پروژه یکسان نیست. برای landing page ساده، discovery سنگین overkill است. برای SaaS با چند نقش کاربری، workflow مالی، و integration، discovery کوتاهتر از چند هفته معمولاً فقط risk را به فاز build منتقل میکند.
نشانههایی که discovery جدی میخواهد:
- بیش از یک stakeholder با اولویتهای متفاوت
- وابستگی به سیستم legacy
- عدم قطعیت در مدل درآمد یا pricing
- نیاز به compliance
- تیم داخلی مشتری که خودش مسیر فنی را نمیداند
prototype، build، یا «هنوز نساز»
سه مسیر متفاوت است:
Prototype: برای یادگیری UX یا feasibility. ممکن است throwaway باشد.
Spike فنی: برای پاسخ به یک سؤال مشخص («آیا API X latency قابل قبولی دارد؟»).
Build production path: وقتی مسئله و scope به اندازه کافی روشن است که commit کردن به codebase بلندمدت منطقی است.
اشتباه رایج: prototype را بدون refactor plan به production تبدیل کردن. اگر قرار است کد زنده بماند، باید از ابتدا quality bar مشخص شود — حتی اگر scope کوچک باشد.
گاهی بهترین تصمیم engineering این است که هنوز نسازیم: اگر فرضیه اصلی محصول validate نشده، هر هفته development بدون داده، فقط هزینه entrench کردن فرضیههای غلط است.
جمعبندی: شکست زودهنگام vs شکست دیرهنگام
پروژههایی که قبل از development شکست میخورند، اغلب شکست ارزانتری هستند — چون pivot یا توقف هنوز ممکن است. پروژههایی که مسئله را درست تعریف نکردهاند اما با بودجه زیاد وارد build میشوند، شکستشان گرانتر است: reputational cost، rewrite، و تیمهای خسته.
Product Engineering جدی یعنی قبل از نوشتن کد، زمان کافی برای فهمیدن مسئله، کاهش ریسک، و تعریف مرزها صرف شود — نه بهجای build، بلکه برای build درست.
منابع و مراجع
- Inspired: How to Create Tech Products Customers Love — Marty Cagan / SVPG
- Software Engineering Body of Knowledge (SWEBOK) — IEEE Computer Society (2014)
- Technical Debt — Martin Fowler
شروع یک پروژه
وقتی مسئله، scope و operational reality روشن نیست، feature list جایگزین strategy میشود — و هزینه بعداً ظاهر میشود.