<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>پست‌های انتشارات رادیو مهندسی نرم‌افزار</title>
        <link>https://virgool.io/se-radio/feed</link>
        <description>مطالبی که می‌خوانید ترجمه پادکست‌های منتشر شده در رادیو مهندسی نرم‌افزار (se-radio.net) است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره یکی از موضوعات حوزه مهندسی نرم‌افزار با افراد خبره و باتجربه در موضوع مورد بحث ترتیب می‌دهد.</description>
        <language>fa</language>
        <pubDate>2026-06-16 12:03:23</pubDate>
        <image>
            <url>https://files.virgool.io/upload/publication/ebxkazucj4gr/otkdil.png</url>
            <title>رادیو مهندسی نرم‌افزار</title>
            <link>https://virgool.io/se-radio</link>
        </image>

                    <item>
                <title>تحویل مستمر</title>
                <link>https://virgool.io/se-radio/%D8%AA%D8%AD%D9%88%DB%8C%D9%84-%D9%85%D8%B3%D8%AA%D9%85%D8%B1-eg0duwyvvcz9</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۲۲۱ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت یوهانز تونز با جز هامبل در مورد تحویل مستمر (continuous delivery) صحبت می‌کند. جز هامبل هم‌اکنون نائب‌رییس شرکت Chef است. او ۱۴ سال سابقه کار در صنعت IT دارد. به ‌غیر از کار توسعه و مدیریت، مشاوره هم می‌کند. نکته جالب این است که او در ۱۱ سالگی کار برنامه‌نویسی را آغاز کرد و مجذوب کامپیوترهای خانگی ZX Spectrum شد. اما در ادامه از دانشگاه آکسفورد، لیسانس فیزیک و فلسفه گرفت. احتمالاً بیشتر افراد ایشان را از کتاب Continuous Delivery و کتاب Lean Enterprise می‌شناسند. در این مصاحبه، در بحث تحویل مستمر از موضوع‌های خیلی متنوعی صحبت می‌شود: تحویل مستمر و اینکه چطور در GoCD و فریم‌ویر HP انجام شد، منافع تحویل مستمر برای توسعه‌دهنده‌ها، قانون کانوِی و تیم‌های فراعملکردی (cross-functional)، نسخه دادنِ بدون ترس، رفع‌خطای به جلو (fix-forward)، استقرار آبی/سبز، تست A/B، ریشه‌های تحویل مستمر در توسعه ترکه‌ای (lean)، زمان چرخه (cycle time) از ورود کد تا اجرا شدن آن، خط لوله استقرار (deployment pipeline)، مجزا کردن انتشار از استقرار، ارتباط بحث با DevOps، تحویل مستمر در محیط‌های پیرو مقررات، اینکه «همه در ارتباط با فرآیند تحویل مسئولیت دارند»، تغییر فرهنگ به DevOps، متوقف کردن خط تولید، اینکه «همه چیز باید در مخزن کنترل نسخ (version control) باشد»، توسعه مبتنی بر شاخه‌ اصلی (trunk-based development)، مدیریت پیکربندی، مجازی‌سازی محفظه‌ها (container) و ... .آیا ممکن است به طور خیلی خلاصه به ما بگویید که تحویل مستمر چیست؟قطعاً. تحویل مستمر، برآمده از تجربه‌هایی است که من و گروهی از افراد دیگر در شرکت ThoughtWorks داشتیم. ما روی پروژه‌های پیچیده و کاملاً بزرگی کار می‌کردیم و نسخه‌دادن، همواره فرآیند رنج‌آوری داشت. در جایی، کار توسعه انجام می‌شد و بعد نرم‌افزار باید جای دیگری برای اجرا در محیط عملیاتی برپا می‌شد و این کار فرآیند خیلی دشوار و رنج‌آوری داشت. ThoughtWorks در ارتباط با یکپارچه‌سازی مستمر (continuous integration) یکی از پیشگامان و از شرکت‌هایی بود که به محبوب شدن آن کمک کرده بود. بنابراین ما در یکپارچه‌سازی منظم کدها و اجرای منظم تست‌های خودکار خیلی خوب بودیم، اما فهمیدیم تنها این‌ها برای اینکه محصول برای عملیاتی شدن آماده شود، کافی نیست.یکی از پروژه‌هایی که من در آن کار می‌کردم و این مسأله را برایم روشن کرد یک سیستم تأمین پهنای باند بود که برای یک ISP نوشتیم. ما سیستم را بر روی لپ‌تاپ‌های ویندوزی توسعه می‌دادیم اما قرار بود سیستم بر روی یک خوشه سولاریسی استقرار یابد. اولین باری که توانستیم به جایی مشابه با محیط عملیاتی آن دست پیدا کنیم، بیش از ۶ ماه از پروژه گذشته بود و ۲-۳ هفته، از ما وقت گرفت تا توانستیم آن را مستقر کنیم و وقتی آن را مستقر کردیم متوجه مشکلات معماری‌مان شدیم که به علت فرضیات بدی بود که افراد کرده بودند. مثلاً استفاده از حافظه پنهان (cache) بر روی فایل سیستمِ لپ‌تاپ‌های ویندوزی خوب کار می‌کند اما بر روی یک خوشه از کامپیوترها کار نمی‌کند زیرا در آنجا هر سرویسی، فایل سیستم متفاوتی دارد. ما متوجه این مشکلات شدیم اما برطرف کردن آنها واقعاً پرهزینه بود. همین‌طور برای کمک در مستقر کردن سیستم تعدادی اسکریپت‌های خودکار داشتیم که روی ant اجرا می‌شدند اما تیم عملیات (operation team) علاقه‌ای به استفاده از ant نداشت. ما از آنها پرسیدیم می‌خواهید برای عملیاتی کردن سیستم از چه استفاده کنید؟ آنها گفتند که ما فقط از bash استفاده می‌کنیم. بنابراین مجبور شدیم برای استقرار bash بنویسیم. در انتها یک تیم از بهترین‌های ما یک نرم‌افزار اختراع کرده و توسعه داد تا بتوانیم سیستم را به‌صورت منظم در محیط تست مستقر کنیم و بازخورد‌های تست را دریافت کنیم و بعد بتوانیم سیستم را بر روی محیط عملیاتی مستقر کنیم. همه‌ این تکنیک‌ها در کتاب تحویل مستمر گرد آمدند.فکر می‌کنم آنچه باعث موفقیت آن شد این بود که افرادی که بر روی سیستم‌های تحت وبِ با مقیاس بزرگ کار می‌کنند، همه همزمان با هم از تکنیک‌های کاملاً مشابهی استفاده می‌کردند. وقتی ما کتاب را می‌نوشتیم، تیم فیتس درباره تحویل مستمر در شرکت IMUV (همان شرکتی که اریک ریس از بنیانگذارانش بوده) یک پست در وبلاگش گذاشت که البته آنجا، این مسأله طوفان عظیمی ایجاد کرده بود زیرا آنها هر روز چندین بار سیستم عملیاتی را مستقر می‌کردند.در همان زمان افرادی مانند جان آلسپو و پل هاموند در کنفرانس Velocity در سال ۲۰۰۹، آن ارائه با عنوان ۱۰ بار تحویل دادن در روز را داشتند. بعد از آن بود که موارد مرتبط با پردازش ابری و DevOps مطرح شد. بنابراین فکر می‌کنم در یک زمان، افراد مختلفی بودند که به تکنیک‌های مشابهی رسیدند که به تحویل مستمر انجامید. اما اساساً تحویل مستمر همه‌اش در این باره است که فرآیند تحویل نرم‌افزار را طوری تغییر دهیم که اقتصادی شده و در تکه‌های کوچک انجام شود. علتی که ما حتی در بسترهای چابک (agile)، این سبک‌های خیلی آبشاری را داریم این است که فرآیندی که از آغاز پروژه آغاز می‌شود و بعد مراحل تأیید، تخصیص بودجه، نیازسنجی، توسعه، یکپارچه‌سازی و بعد نسخه دادن را طی می‌کند، هنوز فرآیند خیلی پرهزینه‌ای است و اقتصادی نیست که آن را در گام‌ها و تکرارهای کوچک انجام دهید. در واقع آنچه تحویل مستمر انجام می‌دهد این است که اقتصاد آن را تغییر می‌دهد و می‌توانید بر روی تکه‌های کوچک کار کنید و تغییرات کوچکی را از آن طریق انجام دهید.آیا شما این کار را با خودکارسازی همه‌ چیز از آغاز تا انتها و از پذیرش تا تحویل انجام می‌دهید؟این، یک بخش آن است؛ این‌که یک فرآیند خودکار از پذیرش تا نسخه دادن داشته باشید. فکر می‌کنم بخش دیگر آن معماری است و بخش دیگر، مدیریت پیکربندی (configuration management) است. اینکه اطمینان یابید که هر چه برای بازسازی محیط عملیاتی نیاز دارید، در مخزن کنترل نسخ (version control) قرار گرفته است. همین‌طور برای اینکه بتوانیم آن را به‌صورت مؤثر انجام دهیم مجموعه‌ای از رویه‌ها مانند یکپارچه‌سازی مستمر (continuous integration) وجود دارد که باید از آنها پیروی شود.قبل از آنکه درباره مباحث مدیریت پیکربندی و یکپارچه‌سازی مستمر عمیق‌تر شویم آیا ممکن است یک مثال موفق از پروژه‌هایی بزنید که به روش تحویل مستمر انجام داده‌اید تا برایمان ملموس‌تر شود.بله، پروژه ISP یکی از آنهاست. افراد این‌طور فکر می‌کنند که تحویل مستمر مربوط به نرم‌افزارهای تحت وب است اما این‌طور نیست. من مدیر محصول یک ابزار متن‌باز با نام GoCD بودم که یک ابزار برای تحویل مستمر است و یک بسته‌ نرم‌افزاری است (تحت وب نیست) اما آنجا ما تحویل مستمر را پیاده‌سازی کردیم به این معنا که هر تغییری باعث می‌شد که بسته‌ محصول دوباره تولید شود و بعد تست‌های خودکار را اجرا می‌کردیم و بعد برنامه‌های نصب مختلف برای سولاریس، ویندوز، مک او.اس و لینوکس را می‌ساختیم و بعد تست‌های عملیاتی را انجام می‌دادیم. در واقع ما خط تولید استقرار (deployment pipeline) را داشتیم که برنامه‌های نصب مختلف را تولید می‌کرد و کپی‌هایی از انواع محیط‌های عملیاتی مربوط به مشتری‌های مختلف را داشتیم و برنامه‌های نصب در آن محیط‌ها اجرا می‌شد تا عملیات ارتقا (upgrade) انجام شود و مطمئن شویم که فرآیند عملیاتی کردن با برنامه‌های نصب درست کار می‌کند. بنابراین این روش برای بسته‌های نرم‌افزاری هم بسیار خوب بود و خیلی مؤثر بود زیرا نسخه‌ دادن در این حد ساده شده بود که فقط برنامه‌های نصب را در وب‌سایت بارگذاری کنیم.مثال دیگری که واقعاً برایم جالب است و به‌شخصه در آن دخیل بودم، مربوط به کاری است که در HP انجام شد. کتابی با عنوان رهیافتی عمل‌گرا به توسعه چابک بزرگ‌مقیاس  (A Practical Approach to Large-Scale Agile Development) نوشته گری گروور هست که درباره فِرم‌ویر پرینتر لیزرجت HP است و درباره‌ این است که چگونه برای فرم‌ویر لیزرجت HP، سیستم تحویل مستمر راه انداختند. معمولاً افراد فرم‌ویرشان را ۱۰ بار در روز بروز نمی‌کنند. چنین چیزی را خیلی مشاهده نمی‌کنید :-) با این‌ حال آنها تحویل مستمر را راه انداختند تا تست‌های خودکار کاملاً جامعی داشته باشند. یک تیم خیلی بزرگ بر روی آن کار می‌کردند، یک تیم ۴۰۰ نفره‌ پراکنده در ۳ کشور، بر روی مخازن کد داخلی‌شان کار می‌کردند و می‌توانستند روزانه ۴۰۰ تغییر را (به مخزن اصلی) بفرستند. صدها هزار خط کد، هرروزه تغییر می‌کرد. آنها تقریباً هر روز ۱۰ بار بیلد می‌کردند که بر روی آنها مجموعه تست‌های خودکار گسترده‌ای انجام می‌شد و ظرف یک روز یک بازخورد کامل از کیفیت کار دریافت می‌کردند و مطمئن می‌شدند که همه خطاهایی که پیدا شده بود را برطرف کرد‌ه‌اند. بنابراین نرم‌افزار همواره در یک وضعیت قابل نسخه‌دهی قرار داشت. این تفاوت چشم‌گیری در اقتصاد فرآیند ایجاد کرد. آنها توانستند از لحاظ مدت زمانی که تیم برای توسعه ویژگی جدید و یا برطرف کردن خطاها داشت، نسبت به زمانی که تست‌های دستی انجام می‌دادند یا کدهای از انشعاب‌های مختلف را ادغام می‌کردند، ۸ برابر کاراتر شوند. خیلی از فعالیت‌های بی‌ارزش از بین رفت و از آنجایی که آنها یک فاز یکپارچه‌سازی و مرتب‌سازی داشتند می‌توانستند یک ویژگی جدید را در اواخر کار توسعه، انجام دهند، یعنی نسبت به زمانی که قبلاً یک ویژگی باید ثابت (freeze) می‌شد، اکنون می‌توانستند همچنان تغییر داشته باشند و این، نوعِ ارتباطشان با بازار و فروش را نیز تغییر داد.از صحبت‌های شما، به نظر می‌رسد که تحویل مستمر، مزایای زیادی برای کسب و کار دارد اما به‌عنوان یک توسعه‌دهنده، چه چیزی برای من دارد؟ البته به‌غیر از اینکه واضح است که کسب و کار است که هزینه من را می‌دهد.سئوال خوبی است. فکر می‌کنم در تحویل مستمر چیزهای زیادی باشد که توسعه‌دهندگان دوستش نداشته باشند. یکی از مقاله‌های مورد علاقه من درباره تحویل مستمر، مطلبی است که استیو یگ نوشته است البته این مطلب در اصل در مورد تحویل مستمر نیست اما به آن هم اشاره پیدا می‌کند. او در این مورد نوشته که چرا گوگل، سکوی کار (platform) را مشابه با آمازون، نمی‌فهمد. یکی از چیزهایی که در مورد آن صحبت کرده این است که چگونه برخی کارها برای توسعه‌دهندگان در آمازون دردآور است. کارهایی از قبیل اینکه مطمئن شوند کدها در محیط عملیاتی کار خواهند کرد، و بتوانند آن را (در محیط عملیاتی) مانیتور کنند و متوجه عملکردش بشوند. انجام این کارها که اغلب مهندسان، آن را بخشی از شغل خود نمی‌دانند برایشان سخت است. بنابراین باید کارهایی را به جز سروکله زدن با کد انجام دهند که خیلی آزاردهنده است. این از روش وارنر ووگل، مدیر ارشد فنی آمازون برآمده است. او گفته‌ای دارد که «شما می‌سازیدش، شما هم اجرایش می‌کنید.» بنابراین همان افرادی که مسئول ساختن نرم‌افزار هستند، همان‌ها هم آن را در محیط عملیاتی راه می‌اندازند. بنابراین باید یاد بگیرید که چطور این کار را بکنید. این یک تغییر فرهنگی بزرگ برای توسعه‌دهندگان است اما در عین حال بازخورد خیلی مهمی هم ایجاد می‌کند زیرا به این معناست که توسعه‌دهندگان باید معنای کدهای آماده به عملیات را بدانند نه این‌که فقط معنای تمام شدن توسعه کد را بدانند. خیلی مهم است که توسعه‌دهندگان این مفهوم را متوجه شوند زیرا وقتی می‌خواهند کد را توسعه دهند باید چیزهای زیادی را در ذهن داشته باشند و نگرانش باشند مثلاً چیزهایی از قبیل مقیاس‌پذیری، دسترس‌پذیری، نوشتن پیام‌های لاگی که بکار آید و فقط صفحات متوالی از خطاهای اشاره‌گر تهی (null pointer) نباشد و مسائل دیگری از قبیل آرشیو‌ کردن داده‌ها. در غیر این صورت، نمی‌توانید آن چرخه بازخورد را بسازید تا بفهمید که چه چیز از نرم‌افزاری که ساخته‌اید در محیط عملیاتی عمل نکرده است. یادگیری این چیزها برای توسعه‌دهنده‌ها خیلی سخت است و می‌تواند برای آنها خیلی آزاردهنده باشد.مورد دیگر که یک تغییر فرهنگی برای توسعه‌دهندگان به حساب می‌آید این است که هنگامی که بر روی پیاده‌سازی ویژگی‌های بزرگ کار می‌کنند آنها را به گام‌های افزایشی کوچک بشکنند که بتواند قابل تحویل باشد یعنی حتی اگر پیاده‌سازی ویژگی پایان نیافته، به جای اینکه در یک انشعاب (branch) مربوط به ویژ‌گی‌های جدید قرار بگیرد، بتواند در شاخه اصلی (trunk) قرار بگیرد که قرار است تحویل شود. این هم یک تغییر فرهنگی بزرگ برای توسعه‌دهندگان است زیرا باعث کند شدن آنها می‌شود چراکه اگر قرار باشد از ابتدا تا انتهای کار، در گام‌های کوچک افزایشی انجام شود، بیشتر طول می‌کشد تا اینکه کار در یک انشعاب مربوط به ویژگی جدید انجام شود.اما فکر می‌کنم آنچه واقعاً خوب است این است که شما به‌عنوان توسعه‌دهنده، می‌توانید یک ایده دریافت کنید، آن را به محیط عملیاتی ببرید و بلافاصله تأثیر آن را ببینید؛ به این ترتیب، چرخه‌ بازخورد خیلی سریعی خواهید داشت. کاری را انجام می‌دهید و حتی ممکن است بتوانید در همان روز و قطعاً در همان هفته، تعامل افراد با آن کد را ببینید. در عوض، در مدل سنتی باید هفته‌ها بلکه ماه‌ها منتظر می‌شدید تا نرم‌افزار در محیط عملیاتی اجرا شود و حتی ممکن بود شما از پروژه رفته باشید و کار را به کس دیگری سپرده باشید. بنابراین در این شرایط هیچ‌گاه کار کردن افراد با آن را نمی‌دیدید. برای توسعه‌دهندگان چنین چیزی خیلی تیره‌بختی است. در واقع اینکه بتوانید کار را به محیط ببرید و استفاده کردن افراد و بازخورد آن را ببینید، خیلی خوب است. من فکر می‌کنم این خیلی خیلی ارزشمند است.آیا از زمانی که به گفته خود به مشتری و کاربران نزدیک‌تر شده‌اید، رهیافت توسعه نرم‌افزارتان تغییر کرده است؟جالب است زیرا من هیچ‌گاه، واقعاً روش بد آن را تجربه نکرده‌ام. بعد از فارغ‌التحصیل شدن از کالج، اولین تجربه‌ام کار در یک استارتاپ در لندن بود. می‌توانم به طنز بگویم که آنجا ما تحویل مستمر و حتی استقرار مستمر (continuous deployment) داشتیم زیرا ما فایل‌ها را مستقیماً با ftp از ایستگاه‌ها (workstation) به محیط عملیاتی می‌فرستادیم. در سال ۲۰۰۰ ما حتی از مخزن کنترل نسخ (version control) استفاده نمی‌کردیم. فقط من بودم و فردی که مدیر ارشد فنی به حساب می‌آمد و فقط از ftp استفاده می‌کردیم. البته قطعاً این روشی نیست که بخواهم الان آن را توصیه کنم. بعد از آن پیشرفت کردم و در پروژه‌های بزرگ کار کردم که در آنجا بود که با این مشکلاتی که در موردش صحبت کردیم برخوردم.از آنجایی که اولین تجربه من، کار در یک محیط استقرار مستمر بود قطعاً درد نداشتن تحویل مستمر را حس می‌کردم، اینکه هفته‌ها کد را شخم بزنید اما هیچ نسخه‌ای منتشر نشود. وقتی نمی‌توانید ببینید که مزایای کار چه بوده است این درد دو چندان می‌شود. فکر می‌کنم این مشکل عمومی توسعه‌دهنده‌ها است.من قبل از آنکه به شرکت ThoughtWorks بپیوندم هیچ نوعی از TDD را تجربه نکرده بودم. آن زمان بود که به تیمی پیوستم که همه به این روش کار می‌کردند. آن موقع بود که شستشوی مغزی شدم و از آن به بعد همین روش را ادامه دادم و عاشقش هستم، من دیگر هیچ‌گاه به روش دیگری کار نخواهم کرد. من این تجربه تغییر مسیر دادن را داشته‌ام. به خاطر دارم که وقتی کتاب XP آمد، آن را خواندم و گفتم این هیچ وقت جواب نمی‌دهد. بعد وقتی برای کار به ThoughtWorks رفتم، افرادی را دیدم که TDD کار می‌کردند و نرم‌افزار را دقیقاً به همین روش تولید می‌کردند. آن موقع با خودم گفتم: خدای من! نه تنها جواب می‌دهد بلکه نسبت به هر روش دیگر توسعه نرم‌افزار، کلی هم جذاب‌تر است.بنابراین فکر می‌کنم که خیلی دشوار است که بخواهیم با منطق کار کنیم و با استدلال‌های منطقی افراد را مجاب کنیم. تنها راهش این است که خودتان آن را امتحان کنید و با افرادی کار کنید که این روش کار را دوست دارند. البته حتی در این‌ صورت هم ماه‌ها طول می‌کشد تا یاد بگیرید که چطور آن را انجام دهید.این نکته‌ خوبی بود.با فرض اینکه یک وب‌سایت بزرگ چند میلیون کاربری داشته باشم، چطور باید راه‌اندازی تحویل مستمر را آغاز نمایم؟سئوال خوب و البته سختی است زیرا چیزهای زیادی باید عوض شود. فقط فرآیند توسعه نرم‌افزار نیست بلکه در مورد نحوه تفکر شما در مورد مدیریت پروژه، حتی نحوه تفکر شما در مورد تخصیص بودجه و مدیریت ریسک هم هست. همه اینها باید تغییر کند. فکر می‌کنم تنها روشش این است که آن را گام‌به‌گام و افزایشی انجام دهید.مورد خاصی که با آن شروع می‌کنید چیست؟من برایتان مثالی از آمازون می‌زنم. آمازون یک تغییر معماری از یک معماری برآمده از مدل (model driven architecture) به یک معماری سرویس‌گرا (service oriented architecture) داشت. این کار ۴ سال طول کشید. آن‌ها از الگویی استفاده کردند که مارتین فاولر و دیگران زیاد در مورد آن در وبلاگ‌شان نوشته‌اند. این الگو، الگوی برنامه‌ خفه‌کننده (strangler application) نام دارد. عملاً معماری، بزرگ‌ترین یا یکی از بزرگترین موانع دستیابی به تحویل مستمر است. اگر مجبور باشید که همه چیز سیستم را با هم به روش انفجار بزرگ (big bang) تحویل دهید، خیلی سخت است که به مزایای آن برسید.بنابراین آنچه آمازون انجام داد این بود که تغییر معماری به یک معماری سرویس‌گرا داشتند اما این کار را گام‌به‌گام انجام دادند. آنها یک سرویس خاص را برمی‌داشتند و آن را مجدداً پیاده‌سازی می‌کردند و در طی زمان، به تدریج سرویس‌های بیشتری برداشته شده بود.در مورد برنامه خفه‌کننده، تشبیهی که می‌شود این است که مانند جنگل‌های انبوه استوایی است که درختان زیادی وجود دارد و بعد یک درخت تاک پهن، دور درخت دیگری را می‌گیرد و به تدریج آن را دربرگرفته و خفه می‌کند. این همان روشی است که ما به تدریج یک معماری را بنا می‌کنیم. ما به تدریج سرویس‌هایی را جدا می‌کنیم و در نهایت برنامه یکپارچه (monolithic) را خفه می‌کنیم.فکر می‌کنم کار واقعاً هوشمندانه‌ای که آمازون انجام داد این بود که این‌ کار را با تغییرات سازمانی ترکیب کرد. یعنی همان تغییر که: «شما می‌سازیدش، شما هم اجرایش می‌کنید.» این ایده که برای هر سرویس تیمی داشتند که مسئول آن سرویس در تمامی چرخه زندگی‌اش (life cycle) بود. همین‌طور، ایده‌ تیم‌های دو پیتزایی را مطرح کردند: «نباید تیمی باشد که نتوان آن را با دو پیتزا تغذیه کرد»، که تقریباً معادل ۱۰ نفر است. و آن تیم مسئول آن سرویس در تمامی طول چرخه زندگی‌اش بود. این بر روی اندازه سرویس تأثیر داشت که همان معماری ریزسرویس‌ها را تعریف می‌کند که بحث‌هایی درباره‌اش هست و آمازون از پیشگامانش است. یکی از کارهای هوشمندانه‌ای که آمازون کرد، به خدمت گرفتن قانون کانوِی بود. قانون کانوی می‌گوید معماری سیستم، انعکاس یافته از ساختار ارتباطات سازمان است و یا معماری براساس ساختار ارتباطات سازمانی که آن معماری را می‌سازد، شکل می‌گیرد.بنابراین با گفتن اینکه می‌خواهید معماری سرویس‌گرا داشته باشید و می‌خواهید برای هر سرویس یک تیم داشته باشید، یک حرکت هوشمندانه ایجاد شد. آنها یک تیم تکاورهای مخصوص استخدام کردند که وظیفه‌شان این بود که به همه تیم‌ها سر بزنند و اطمینان یابند که تیم‌ها با پایگاه داده تیم‌های دیگر صحبت نمی‌کنند! آنها اگر متوجه می‌شدند که دارید بدون واسطه لایه سرویس با پایگاه داده یک تیم دیگر صحبت می‌کنید، دخلتان را می‌آوردند و اگر تلاش می‌کردید که به این‌کار ادامه دهید، اخراج می‌شدید.اگر به قانون کانوِی برگردیم، آنچه شما می‌گویید این است که با دادن مسئولیت به افراد تیم توسعه -طوری‌ که در کنار تیم کسب و کار در قبال عملیات (operations)، مسئول باشند- نیاز به تحویل مستمر را ایجاد می‌کنید. زیرا وقتی افراد کنار یکدیگر می‌نشینند و با یکدیگر کار می‌کنند و رئیس یکسانی دارند، شروع می‌کنند که با همدیگر تحویل دادن، را آغاز کنند که به تحویل مستمر می‌انجامد.درست است. و همین‌طور معماری [هم هست] زیرا معماری یک جزء کلیدی است. با ایده اقتصادی کردن کار با داشتن بسته‌های کوچک تغییرات که قبلاً بیان شد، بخش معماری کار را ایجاد می‌کنید و با داشتن نوعی ساختار تیمی که در آن افراد می‌توانند تغییرات را خودشان در محیط عملیاتی اعمال کنند (که نیازی ندارید که از خلال یک فرآیند مدیریت تغییرات متمرکز، این کار را انجام دهید و می‌توانید تغییرات را داخل تیم خودتان اعمال کنید)، بخش سازمانی کار را انجام می‌دهید. بنابراین، بله، به این ترتیب بخش معماری و بخش سازمانی را دارید که با هم همراستا شده‌اند.بیایید موضوع را مقداری عوض کنیم و در مورد فرآیند تحویل مستمر عمیق‌تر شویم. شما در کتاب‌تان گفته‌اید که نسخه دادن نباید ترسناک باشد. چرا امروزه نسخه دادن ترسناک است؟فکر می‌کنم به چند دلیل، ترسناک است. اول اینکه در خیلی از سازمان‌ها، نرم‌افزارشان را برای تحویل مستمر معماری‌ نکرده‌اند و این به نسخه رسیدن، کاری طاقت‌فرساست. قطعاً برخی افراد که به این مصاحبه گوش می‌دهند، نسخه را در خارج از ساعت اداری منتشر می‌کنند (شب‌ها، تعطیلات آخر هفته و ...) و این کاری است که چند ساعت به طول می‌انجامد. فکر می‌کنم دو معیار وجود دارد. یک معیار تعداد ساعاتی است که خارج از وقت معمول اداری برای فراهم کردن نسخه سپری می‌کنید و دیگری، تعداد خطاهایی است که باید بعد از آن به صورت اورژانسی برطرف شود. این‌ها دو معیار مفید هستند. چیز دیگری که ترسناک است این است که آیا این ویژگی‌ها برای کسب و کار یا مشتری‌ها ارزشی ایجاد کرده است یا خیر؟ در این زمینه رونی کاهاوی مقاله خیلی خوبی دارد. او از کسانی بود که چارچوب تست A/B را در آمازون راه انداخت و بعداً به مایکروسافت رفت و سکوی (platform) آزمایشی خود (بینگ) را راه انداختند. او داده‌هایی از تست A/B دارد که نشان می‌دهد که دو سوم از ویژگی‌هایی که افراد فکر می‌کنند ایده‌های خیلی خوبی است برای مشتری‌‌ها ارزش صفر یا منفی ایجاد می‌کند. اگر این داده‌ها را عمومیت دهید به این معناست که دو سوم ویژگی‌هایی که ما می‌سازیم و فکر می‌کنیم ارزش دارند، برای مشتری‌ها ارزش صفر یا منفی ایجاد می‌کنند. این باید ترسناک باشد. و اگر شما بر روی نسخه‌های ۳ ماهه کار کنید، چگونه می‌خواهید محاسبه کنید که کدام‌یک از این ویژگی‌ها باعث افزایش یا کاهش معیارهای کسب و کاری که به آنها توجه دارید -مثلاً سود حاصل شده از هر مشتری- شده‌اند؟چون خیلی چیزها تغییر کرده‌اند...بله، چیزهای زیادی تغییر کرده‌اند و حالا چطور می‌خواهید ردیابی کنید که کدام‌یک از کارهایی که انجام داده‌اید واقعاً ارزش‌آفرین بوده‌اند. جاشوآ کریوفسکی می‌گوید شما باید بتوانید به هر خط از کد یک ارزش دلاری انتساب دهید. اگر نمی‌توانیم این کار را بکنیم، لااقل باید بتوانیم با (نسخه دادن در) بسته‌های کوچک و تست‌های A/B بفهمیم که کدام ویژگی‌ها واقعاً ارزش ایجاد کرده‌اند.چرا خودکار کردن نسخه‌دهی و انجام بیشتر آن‌ها، کمتر ترسناک باشد؟سئوال خوبی است. این غیرمنطقی به نظر می‌رسد. اگر تحویل دادن دردآور است، بیشتر انجام دادن آن احمقانه به نظر می‌رسد.باعث درد بیشتر می‌شود...بله، به نظر می‌رسد دردآورتر می‌شود. اما نکته این است که چیز کمتری را تحویل می‌دهید. به چند دلیل (کار ساده‌تر می‌شود). اول اینکه، آن را بیشتر تجربه می‌کنید و این می‌تواند شما را مجبور به ساده‌سازی کند. آنچه ناچار است با خودکارسازی، همراه شود، ساده‌سازی است. اگر یک فرآیند دستی زجرآور را بردارید و همان را خودکار کنید، به یک فرآیند زجرآور شکننده خودکار می‌رسید که واقعاً بهبودی حاصل نمی‌شود. بلکه باید معماری فرآیند خود را طوری سازماندهی مجدد کنید تا تحویلش ساده شود که مربوط به بخش معماری کار است. بنابراین ساده‌سازی هم همراه با خودکارسازی می‌آید و این باعث کاهش مقداری از ریسک‌ها می‌شود. مرتب نسخه دادن نیز مقداری از ریسک‌ها را می‌کاهد. همین‌طور از آنجایی‌که چیزهای کمتری در هر نسخه تغییر می‌کند، اگر چیزی اشتباه باشد، پیدا کردن آن و برطرف کردنش خیلی ساده‌تر خواهد بود چون توجه دارید که ما نمی‌گوییم که ۳ ماه کار کنید و آن را ۱۰ بار در روز منتشر کنید بلکه می‌گوییم به‌قدر یک دهم روز کار کنید و آن را ۱۰ بار در روز منتشر کنید که می‌تواند تغییر در یک خط کد یا تغییری در یکپارچه‌سازی‌ها باشد.من می‌خواهم در اینجا به اصطلاح رفع‌خطای به جلو (fix-forward) اشاره کنم. آیا ممکن است در مورد آن توضیح بیشتری بدهید.این چیزی است که در سازمان‌های کارآمد می‌بینیم و مدت‌هاست که آن را اجرا می‌کنند. آنها هیچ‌گاه عقب‌گرد نمی‌کنند و همواره اگر مشکلی پیدا شود رو به جلو حرکت می‌کنند. یکی از تکنیک‌هایی که ما در کتاب توضیح داده‌ایم استقرار سبز/آبی (blue/green deployment) است. استقرار سبز/آبی این ایده است که شما اساساً دو نسخه از محصول عملیاتی را دارید که یکی از آنها زنده (در حال اجرا) است و دیگری زنده نیست که می‌توانید آن را نسخه صحنه (Staging) بنامید. کاری که انجام می‌دهید این است که (نسخه را) در محیط صحنه، مستقر می‌کنید و مسیریاب (router) یا DNS یا ترازگر بار (load balancer) را تنظیم می‌کنید که به محیط صحنه مسیردهی کند تا صحنه، زنده شود و آنچه قبلاً زنده بوده، تبدیل به صحنه شود.این همان چیزی است که Netflix هم در مورد آن صحبت کرده است و به آن استقرار قرمز/سیاه می‌گوید. در واقع آنچه انجام می‌دهند این است که (نسخه را) بر روی صحنه، استقرار می‌دهند و به آرامی، کاربران را از نسخه زنده به نسخه صحنه، مهاجرت می‌دهند. و من فکر می‌کنم در حال حاضر اروپا محیط صحنه آن‌ها است :-) اگر در جریان استقرار به مشکلی بخورند، دوباره به نسخه‌ای که قبلاً زنده بود جابجا می‌شوند در نتیجه هیچ‌گاه نیاز به عقب‌گرد ندارند. آنها فقط نسخه جدید را در محیط صحنه مستقر می‌کنند و به تدریج کاربران را به آن مهاجرت می‌دهند و عقب‌گرد فقط به این معناست که کاربران به نسخه زنده اصلی برگشت داده شوند.سازمان‌هایی که این کار را می‌کنند فقط رو به جلو حرکت می‌کنند. به عنوان مثال از دایان مارش که مدیر ابزارهای مهندسی در Netflix است، پرسیده شد که آیا شما اصلاً نسخه‌های ساخته شده [قبل] خود را نگه می‌دارید؟ و او گفت هرچند ما آن‌ها را در جایی نگهداری می‌کنیم، اما هیچ‌گاه به عقب برنخواهیم گشت و هیچ‌گاه نیاز نداریم که آن‌ها را دوباره تحویل دهیم.آیا این به آن معنی است که از آنجایی‌ که من بیشتر تحویل دارم، سریع‌تر هم می‌توانم خطاهایی که از زیر دستم در رفته را برطرف کنم؟بله، زیرا تغییر تنظیمات یک مسیریاب (router) نسبت به یک بازگشت به عقب کامل و مستقر کردن دوباره نسخه قبلی سریع‌تر است. و همین‌طور این رویه‌ای نیست که ما زیاد تستش کرده باشیم. مستقر کردن در محیط عملیاتی با مستقر کردن در صحنه‌‌ها مثلاً محیط تست متفاوت است زیرا باید نگران داده‌ها در محصول عملیاتی باشید. اغلب بازگشت به عقب، شامل تغییر در داده‌ها هم هست که واقعاً فرآیند پرخطری است و چیزی نیست که افراد خیلی زیاد آن را تست کرده باشند. بنابراین بازگشت به عقب می‌تواند خیلی خیلی خطر داشته باشد.شما چندین بار به تست A/B اشاره داشتید. ممکن است به اختصار توضیح دهید تست A/B چیست و چرا در تحویل مستمر اهمیت دارد؟قطعاً. تست A/B در واقع از تجارت ارسال نامه می‌آید. افرادی که نامه‌های تبلیغاتی به صندوق‌های نامه واقعی و فیزیکی می‌فرستادند، نسخه‌های مختلفی از آن تبلیغات را به افراد مختلف می‌فرستادند و می‌دیدند که کدام‌یک از آن نسخه‌های تبلیغاتی، نرخ پاسخ بیشتری داشته است.اما این را در نرم‌افزار به چه شکل خواهید دید؟ به این‌صورت خواهد بود که دو نسخه مختلف از یک صفحه خواهید داشت؛ به برخی از کاربران یک نسخه و به بقیه نسخه دیگر را نمایش می‌دهید و باید آنها را در تمام مدت جلسه (session) ردیابی کنید. در این‌جا آنچه می‌سازید دسته (cohort) نام دارد که دسته‌ای از کاربران هستند که تقریباً در یک زمان به وب‌سایت وارد می‌شوند و شما جلو رفتن آنها در وب‌سایت را ردیابی می‌کنید که این ردیابی شامل این هم می‌شود که آیا نسخه A یا نسخه B از یک صفحه خاص را دیده‌اند؛ بعد در انتهای این گشت‌وگذار، می‌بینید که کدام‌یک از آنها، رفتار مطلوب را داشته‌اند مثلاً در مورد وب‌سایت آمازون این رفتار مطلوب می‌تواند این باشد که آخرسر چه مقدار خرید داشته‌اند.یک پی‌آمد اصلی برایش تعریف می‌کنید...بله، این نتیجه ارزیابی کلی آزمایش نامیده می‌شود و باید در طی زمان، انبوهی از این داده‌ها را جمع کنید تا بتوانید اطلاعات آماری مهم را تولید کنید. بنابراین در طی زمان این داده‌ها را از دسته‌های مختلف جمع می‌کنید تا بفهمید کدام صفحه، پی‌آمد درست را داشته است. در آمازون یا بینگ و ... چندین تست A/B مختلف در نسخه عملیاتی دارند. ده‌ها و در برخی شرایط صدها تست A/B در جریان است اما آنها کاملاً بادقت بررسی می‌کنند که هر دسته کاربران، کدام‌یک از این ترکیب‌ها را مشاهده کرده است زیرا روشن است که نمی‌خواهید تست‌ها با هم تداخل پیدا کنند.بله، تست‌های چند متغیره، زجرآور است.درست است.بیایید تمرکزمان را از اینکه چرا آن را انجام می‌دهیم به این معطوف کنیم که چگونه سازمان‌‌مان و فرهنگ سازمانی‌مان باید تغییر یابد. شما در کتاب گفته‌اید که تحویل مستمر از روش تَرکه‌ای (lean) نشأت می‌گیرد. آیا ممکن است توضیح دهید که منظورتان چیست؟اگر به سال‌های ۲۰۰۴ و ۲۰۰۵ برگردیم، آن زمان من کتاب مری پاپندیک و تام پاپندیک با عنوان توسعه نرم‌افزار به روش ترکه‌ای را خوانده بودم که انقلاب بزرگی بود. وقتی من به‌همراه دِیو کتاب تحویل مستمر را می‌نوشتیم مجموعه نوشتارهای دیگری هم درباره روش تَرکه‌ای خواندیم و به این نتیجه رسیدم که خیلی از ایده‌ها (در تحویل مستمر) ریشه در فلسفه تَرکه‌ای دارد.یکی از آن ایده‌ها که از فلسفه تَرکه‌ای آمده است و دوست دارم درباره‌اش صحبت کنم جیدوکا (Jidoka) است که در واقع مفهومی است که در سال ۱۹۹۴ توسط یکی از افراد خانواده تویوتا که فکر می‌کنم ساکیچی تویودا باشد، ابداع شد. تویوتا قبل از اینکه به سراغ خودرو برود، بر روی ماشین‌های بافندگی کار می‌کرد. در آن زمان، محصولی با نام ماشین بافندگی خودکار نوع G را عرضه کردند که یک ویژگی نوآورانه داشت که می‌توانست اگر مشکلی در فرآیند بافندگی روی داده باشد مثلاً اگر نخ پاره شده باشد یا نخ ماسوره تمام شده باشد، شناسایی کرده و به‌طور خودکار متوقف شود.چیزی مشابه با یکپارچه‌سازی مستمر (continuous integration) این روزها.دقیقاً. درست است، آن هم همین رویه را دارد که اگر مشکلی وجود داشت همان وقت آن را بفهمید. در مورد ماشین‌های بافندگی، آنچه به ارمغان آورد این بود که به جای این‌که هر ماشین بافندگی یک اپراتور داشته باشد، می‌توانستند یک اتاق پر از ماشین‌های بافندگی داشته باشند که فقط یک اپراتور داشته باشد زیرا ماشین به شما می‌گفت که اتفاق بدی افتاده است. همان‌طور که شما اشاره کردید این همان چیزی است که در یکپارچه‌سازی مستمر هم داریم.یک فرآیند مشابه دیگر که داریم این است که به‌جای داشتن تستر‌هایی که به‌صورت دستی، نرم افزار را تست کنند، تست‌های خودکاری داشته باشید که اگر پَسرفت عملکرد جدی وجود داشت همان موقع آن را بفهمند و بتوانید همان موقع کار را متوقف کرده و مشکل را برطرف کنید. این ایده که کیفیت را در داخل خودِ کار بسازیم، فرآیند توسعه نرم‌افزار را خیلی کاراتر می‌کند. این همان ایده‌ای است که دمینگ در جنبش اجتماعی افزایش کیفیت در مورد آن صحبت کرده است. خیلی از ایده‌ها از جمله همین ایده از فلسفه تَرکه‌ای می‌آید.مسئله دیگری که در کتاب در ارتباط با فرهنگ به آن اشاره کرده‌اید ایده کاهش زمان چرخه (cycle time) است. در اینجا چرخه به چه معناست؟این سئوال خوبی است. دوباره اگر پیام تَرکه‌ای را درنظر آوریم، تعریف کردن زمان چرخه خیلی ساده است زیرا می‌توانید به سادگی، حرکت فیزیکی تولیدات در کارخانه را ببینید. می‌توانید خودروها را ببینید که وارد خط تولید می‌شوند. در نرم‌افزار، لمس این تولیدات خیلی سخت‌‌تر است.ما تعداد زیادی چرخه داریم. تکرار‌ها (iteration) را داریم و ...بله، ما ویژگی‌ها (feature) را داریم. اگر تولیدات ما ویژگی‌ها باشند، چگونه باید حرکت ویژگی‌ها را اندازه بگیریم؟ نقطه شروع یک ویژگی چیست؟ آیا آن زمانی است که از ابتدا ایده‌اش را دارید؟ آیا زمانی است که آن ایده را در یک سیستم ردگیری (tracking system) یا بر روی یک کارت ثبت می‌کنید؟ یا زمانی است که آن را بر روی انباره (backlog) اولویت‌بندی شده خود می‌آورید؟ چه زمانی دکمه شروع را می‌زنید؟بله، چه زمانی دکمه شروع و چه زمانی دکمه پایان را می‌زنید؟فکر می‌کنم به‌شکل خاص در مورد تحویل مستمر، یکی از وضعیت‌هایی که خیلی قابل مشاهده واقعی باشد، زمانی است که آن را در مخزن کنترل نسخ (version control) وارد می‌کنید. این تعریف، در واقع تمامی چرخه نیست و باید به این دقت کنیم که روند ایده‌سازی و تحلیل را نادیده نگیریم اما اگر چرخه را از زمان قرار گرفتن در مخزن کنترل نسخ تا زمان قرار گرفتن در سیستم عملیاتی تعریف کنیم، می‌توان به صورت قطعی آن را اندازه‌گیری کرد. در این‌صورت در قیاس خط تولیدی که در کتاب تحویل مستمر برای نرم‌افزار به‌کار رفته است، فرآیندی است که شما تغییری را در سیستم کنترل نسخ وارد می‌کنید و بعد تست‌‌ها را بر روی آن اجرا می‌کنید و بعد آنها را در بسته‌هایی قرار می‌دهید و به صورت خودکار در محیط عملیاتی مستقر می‌کنید یا بسته را برای کاربران، منتشر می‌کنید.این همان چیزی است که آن را خط لوله استقرار (deployment pipeline) نامیده‌اید.بله، خط لوله استقرار.و آیا خط لوله استقرار باید حتما خودکار باشد؟ آیا ختما باید اسکریپت‌هایی داشته باشیم که این کارِ خط لوله استقرار را انجام دهند؟بله، می‌توانید، هر چند که من فکر می‌کنم عموماً ارزیابی‌های دستی هم وجود دارد. در اغلب موارد نمی‌توانیم این‌قدر خوشبخت باشیم که نرم‌افزاری که تست‌های خودکار را قبول شده است را یک‌راست به محیط عملیاتی بفرستیم. شما می‌خواهید برخی تست‌های کاربری یا شاید تست‌های A/B داشته باشید. و نیز پیچیدگی‌هایی در مورد روانه کردن پنهان (dark launching) وجود دارد.روانه کردن پنهان به چه معناست؟این اصطلاحی است که فکر می‌کنم توسط فیسبوک ابداع شد و بوسیله Etsy پیشرفت کرد. به این معناست که کدی را در نسخه عملیاتی قرار می‌دهید اما آن بخش از کدها اجرا نمی‌شوند.ویژگی‌ها را خاموش و روشن می‌کنید.بله، ویژگی‌ها را خاموش و روشن می‌کنید یا این‌که آن را در بخشی از API قرار می‌دهید که هیچ چیزی در واسط کاربری به آن متصل نیست. این یک راه دیگر آن است. به عنوان مثال در Etsy اغلب تغییرات، به‌صورت پنهان وارد می‌شوند و بعداً به نوعی اتصالاتشان برقرار می‌شود. فیسبوک تکه نرم‌افزاری با عنوان محافظ خاکستری دارد که کنترل می‌کند که چه ویژگی‌هایی را بتوانید ببینید، می‌توانید یک ویژگی را انتخاب کرده و آن را تنها به یک جامعه خاص آماری نشان دهید یا آن را تنها به یک درصد از کاربران نمایش دهید که می‌تواند به منظور تست A/B باشد و یا در راه‌اندازی نهایی باشد و یا حتی برای مدیریت بار باشد، اگر بر روی یک ویژگی، حجم زیاد بار غیرعادی باشد، می‌توانید برخی ویژگی‌های پرهزینه را از مدار خارج کنید. این چیزی است که بسیاری از سازمان‌ها تجربه می‌کنند. بنابراین روانه کردن پنهان، برای اهداف مختلفی می‌تواند به‌کار آید.من در اینباره مطلبی شنیده‌ام که این باعث مجزا شدن انتشار از استقرار می‌شود.بله، این چیزی است که خیلی دوست دارم در مورد آن صحبت کنم. این را بعد از منتشر شدن کتاب واقعاً درک کردم.شاید گفته شما باشد اما واقعاً نمی‌دانم کجا خواندمش.من قطعاً دراین باره نوشته‌ام اما نمی‌دانم که آیا من شخصی هستم که این مفهوم را ابداع کرده یا خیر. ایده این است که استقرار به معنای ساختن و گذاشتن در محیط است اما انتشار، در دسترس قرار دادن ویژگی برای کاربران است. و این دو، اعمال کاملاً مستقلی است. اغلب ما آنها را به هم گره می‌زنیم و از طریق استقرار به انتشار می‌رسیم اما این‌کار خیلی پرخطر است. راه کم‌خطر این است که همه ویژگی‌ها را به‌صورت پنهان روانه استقرار کنیم، اما انتشار به معنای در دسترس قرار دادن ویژگی‌ها برای کاربران، روند خیلی آهسته‌تری داشته باشد و کاملاً مستقل از فرآیند استقرار باشد و به‌وسیله کسب و کار انجام ‌شود، با تست‌های A/B انجام ‌شود و با به‌آهستگی در مدار آوردن عملکردها انجام ‌شود.و خاموش کردن آنها در صورت شکست خوردنشان...بله، خاموش کردن آنها در صورت شکست خوردنشان و یا در صورتی که بار زیادی داشته باشند و چیزهای مشابه آن.بخش مهمی از تحویل مستمر که هنوز در مورد آن صحبت نکرده‌ایم، بخش عملیات (operations) است. تحویل مستمر چه ارتباطی با DevOps و فرهنگ DevOps پیدا می‌کند؟سئوال جالبی است زیرا در زمانی که کتاب را می‌نوشتم، جنبش DevOps داشت فراگیر می‌شد تا جایی که اصطلاح DevOps را در کتاب آوردیم و به خاطر دارم که مجموعه‌ای از مطالعات در زمینه DevOps انجام دادیم و در مورد آن با افراد صحبت می‌کردیم و خیلی در موردش علاقه‌مند شده بودیم.اگر امروز می‌خواستید کتاب را نامگذاری کنید نامش را کتاب مقدس DevOps یا چنین چیزی می‌گذاشتید؟ :-)نه، من واقعاً از عنوان کتاب راضیم و فکر می‌کنم درست باشد. اما DevOps قطعاً بخشی از آن محسوب می‌شود. فکر می‌کنم DevOps از جنبش WebOps می‌آید. در واقع کتابی که قبل از تحویل مستمر آمد، کتاب Web Operations بود.عملیات وب (web operations) چیست؟ و چرا با DevOps متفاوت است؟کتاب عملیات وب، توسط جان آلسپو و جسی روبینز نوشته شده است. در آن زمان، جسی روبینز پست ارشد در حوادث (master of disaster) در آمازون را داشت و جان آلسپاو در Flickr کار عملیات می‌کرد. این کتاب در واقع، نزدیک به همان چیزی است که باید باشد و شامل مجموعه‌ای کامل از مطالب مختلف از افرادی شامل انجی شیفر، اریک ریس و دسته‌ای از افراد دیگر است که الان خیلی شناخته شده هستند اما در آن زمان کمتر شناخته شده بودند. این کتاب در مورد نحوه ساختن سیستم‌های در مقیاس وب مانند فیسبوک و آمازون است. در اصل جنبش DevOps از اینجا نشأت گرفت.سیستم‌های غیر از وب هم می‌توانند از چیزهای WebOps استفاده کنند؟آنها [نویسندگان کتاب] به این چیزها اهمیتی نمی‌دادند. به ساخت بسته‌های نرم‌افزاری یا برنامه نصب اهمیت نمی‌دادند. آنها به‌شکل خالص، بر روی وب‌سایت‌های با حجم بالا تمرکز کردند و DevOps از آنجا آمد. آنها واقعاً به هیچ وجه بر روی هیچ حوزه دیگری تمرکز نمی‌کردند. در حالی‌ که فکر می‌کنم تحویل مستمر از پیش‌زمینه کاملاً متفاوتی آمد. ما فهمیدیم که خیلی از ایده‌های فلسفه تَرکه‌ای، خیلی از رویه‌ها و فرهنگ‌ها، همگی به یک چیز ختم شد. این چیزی است که برای ما خیلی جالب است و فکر می‌کنم به یک تغییر اساسی در نرم‌افزار انجامید. ما فهمیدیم که ایده‌های در زمینه فرهنگ‌ها و رویه‌ها که در حوزه‌های مختلف وجود دارد از تولید وب‌سایت‌های با مقیاس بالا گرفته تا تولید فرم‌ویرها و یا تولید بسته‌های نرم‌افزاری، ایده‌های یکسانی است. در واقع می‌توانید ایده‌های یکسانی را در این حوزه‌های مختلف به‌کار ببرید و نتایج واقعاً خوبی داشته باشید زیرا آنها اساساً به همان مقداری که در مورد یک رویه خاص بودند، به همان میزان، در مورد ساختن سازمان‌های پایدار و منعطف و تغییرات فرهنگی هم بودند.یکی از چیزهایی که من را آزار می‌دهد این است که به جایی بروید و بگویید: «این چیزها خیلی خوب به نظر می‌رسد اما برای ما جواب نمی‌دهد زیرا ما فیسبوک نیستیم، ما سرویس‌های مالی ارائه می‌کنیم.»که تا حدی درست است...هم هست، هم نیست. مشکل این است که من دیده‌ام که این رویه‌ها در زمینه سرویس‌های مالی هم کار کرده است. من در سال ۲۰۱۴، به مدت ۴ هفته، برای یک بانک سرمایه‌گذاری کار کردم، ما در آنجا دسته‌ای از رویه‌هایی که در کتاب تحویل مستمر گفته شده بود را اجرا کردیم که خیلی مؤثر بود و تفاوت زیادی ایجاد کرد. من در سیستم‌هایی کار کرده‌ام که در آن صدها میلیون‌ دلار، مبادله اموال صورت می‌گیرد. در آنجا ریسک قابل توجهی وجود دارد اما ما این رویه‌ها را به کار می‌بریم زیرا آنها را واقعاً امن‌تر می‌کند.مسئله این است که افراد می‌آیند و می‌گویند برای ما کار نمی‌کند. واقعاً؟! اینکه باعث افزایش کیفیت نرم‌افزار و پیدا شدن سریع‌تر خطاها می‌شود [کار نمی‌کند]؟! این چیزی است که به نظر من خیلی عجیب و غریب است که افراد می‌گویند برای ما کار نمی‌کند چون برایمان ریسک دارد. این رویه‌ها برای این طراحی شده‌اند که ریسک را کمتر کنند و کیفیت را افزایش دهند. بنابراین آنچه آن‌ها می‌گویند این است که ما نمی‌خواهیم آن را انجام دهیم و می‌خواهیم همان رویه‌های گاوچرانی خودمان را ادامه دهیم که در واقع کارها را خراب‌تر می‌کند!من در تهیه گزارش وضعیت DevOps سال ۲۰۱۴ دخالت داشتم. یکی از چیزهایی که دنبالش بودیم اندازه‌گیری کارایی IT بود که بررسی از لحاظ بازدهی (همان فراوانی نسخه دادن)، از لحاظ زمان به ثمر رسیدن تغییر (change lead time)، از لحاظ پایداری از نظر زمان بازراه‌انداری سرویس به‌هنگام خرابی و تنزل (time to restore service) ، همین‌طور از لحاظ نرخ شکست تغییرات (نرخی از تغییرات که بعد از استقرار، شکست می‌خورند و مجبور به برطرف کردن مشکل یا برگشت به عقب می‌شوید) بود.واضح است که بسیاری از فرآیندهای سنگین مدیریت تغییرات مانند داشتن هیأت مشاور تغییرات (change advisory board) و ... که خیلی از شرکت‌های بزرگ استفاده می‌کنند، بازدهی را می‌کاهد اما آنچه ما متوجهش شدیم و نتایج خیلی غافلگیر‌کننده‌ای بود، این بود که باعث افزایش پایداری هم نمی‌شدند. ما افرادی که برای تغییرات، این‌گونه فرآیندهای سنگین را داشتند با سازمان‌هایی مقایسه کردیم که از بازبینی توسط همتا (pair review) استفاده می‌کردند و در آنها توسعه‌دهندگان کارهای همدیگر را یا از طریق یک فرآیند سبُک پذیرش تغییرات یا از طریق برنامه‌نویسی زوج (pair programming) بررسی می‌کردند. ما انتظار داشتیم (که فرآیندهای سبک‌تر) باعث کاهش پایداری شود اما در عین شگفتی متوجه شدیم که اصلاً این‌طور نیست و به‌همان میزان فرآیندهای سنگینِ مدیریت تغییرات، پایداری دارند.بنابراین این ایده که این چیزها، برای ما کار نمی‌کند، غلط است. از لحاظ روانشاسانه، می‌توانم بفهمم چرا افراد این‌طور فکر می‌کنند. زیرا با خود می‌گویند ما و آمازون، مشکلات متفاوتی داریم، اما فراموش کرده‌اند که آن‌ها شرکت‌ ثبت‌شده‌ای هستند که PCI DSS دارند (PCI DSS مخفف Payment Card Industry Security Standards است که یک‌سری استانداردهای امنیتی است که سازمان‌های رسیدگی کننده به تراکنش‌های مالی مربوط به کارت‌های visa، master، american express و ... ملزم به رعایت آن هستند- مترجم). آن‌ها با آن حجم کاری، احتمالاً فرآیندی دارند که بیشترین تعداد اقدامات احتیاطی نسبت به هر شرکت دیگری در دنیا را دارند. بنابراین آن‌ها هم در معرض این مقررات هستند. خطایی که افراد در این سازمان‌های بزرگ می‌کنند این است که می‌خواهند برای همه یک نسخه بپیچند. آن‌ها می‌گویند که: این مقررات ماست و می‌خواهیم آن را در همه سیستم‌های مختلف‌مان بکار ببریم. اما شرکت‌های با کارآمدی بالا این کار را نمی‌کنند. آنها می‌گویند: همه نرم‌افزارهای ما در پردازش‌های حساس دخیل نیستند. فقط این سرویس خاص است که پردازش حساسی را انجام می‌دهد بنابراین کاری که می‌کنیم این است که حیطه مقررات را به کمترین سطح ممکن محدود می‌کنیم و طوری معماری می‌کنیم که نرم‌افزاری که آن کار را می‌کند تا حد ممکن کوچک باشد. بنابراین شما از رهیافتی با تفاوت ناچیز در مدیریت ریسک بهره می‌گیرید که در واقع در آن می‌گویید: مناطق ریسک کجاست؟ و چطور می‌توانیم مدیریت ریسک را طوری بکار بگیریم که بر کل سیستم اثر نگذارد؟ بنابراین برای برخی از سیستم‌ها، توسعه‌دهندگان می‌توانند تغییرات را به محیط عملیاتی بفرستند و برای برخی دیگر که داده‌های حساس دارد، از رهیافت متفاوت استفاده می‌کنیم.شرکت Etsy هم PCI DSS دارد. PCI DSS بیان‌گر جداسازی وظایف است. به عبارت دیگر فردی که تغییرات را تأیید می‌کند به سراغ کسی که کد را می‌نویسد می‌رود اما هیچ‌گاه گفته نشده که این دو فرد نمی‌توانند کنار یکدیگر بنشینند. به عنوان مثال درEtsy افرادی که درمحیط PCI DSS کار می‌کنند شامل توسعه‌دهنده‌ها، تسترها، مسئولین عملیات، همگی در یک اتاق با هم هستند و کل وقت با هم صحبت می‌کنند. آن‌ها مقررات را به روشی پیاده‌سازی کرده‌اند که از روح و هم لفظ قوانین پیروی کنند اما خیلی مهم است که به روشی نباشد که خیلی سنگین و جداسازی شده باشد.من نقلی از کتاب‌تان خواندم که: &quot;هر کسی مسئول فرآیند تحویل است.&quot; آیا این جمع‌بندی DevOps است؟بله، جمع‌بندی خیلی خوبی است. درست است، هر کسی مسئول فرآیند تحویل است. من فکر می‌کنم همه مسئول همه چیز هستند. اگر به سازمان‌های با کارآمدی بالا توجه کنید، توسعه‌دهندگان خود را مسئول نتایج کسب و کار می‌دانند. این‌طور نیست که بگویند شغل و مسئولیت من فلان چیز است و به‌غیر از آن، چیزهای دیگر، مشکل من نیست و مربوط به دیگران است. در سازمان‌های با کارآمدی بالا افراد این‌طور فکر نمی‌کنند. آن‌ها فکر می‌کنند همه چیز مشکل خودشان است.سئوالی که در گزارش وضعیت DevOps پرسیدیم این بود که وقتی Dev و Ops با هم تعامل می‌کنند، آیا عموماً نتیجه برد-برد خواهد بود؟ و آیا این سئوال کلیدی بود که باعث توجه به DevOps شد؟ اگر به زمینه‌های فرهنگی که این خروجی‌های خوب را تولید کرده است نگاه کنید، به این صورت است که توسعه‌دهندگان، مسئولیت عملیات (operations) را می‌پذیرند و اگر مشکلی در عملیات رخ دهد، این‌طور برخورد نمی‌کنند که این اشتباه Ops است. به طریق مشابه، اگر فرآیند استقرار شکست بخورد، این‌طور برخورد نمی‌شود که از توسعه دهندگان نادان بوده است بلکه با هم کار می‌کنند و شرکت را طوری سازماندهی می‌کنیم تا همه افراد (توسعه‌دهندگان و بقیه) تا حد ممکن با مشتریان در تماس باشند. این هم ایده دیگری است که به روش تَرکه‌ای (lean)  برمی‌گردد.آیا مهم است که افرادی که بر روی توسعه تمرکز دارند و افرادی که بر عملیات تمرکز دارند کنار یکدیگر بنشینند؟من فکر می‌کنم خیلی مهم است. یکی از کتاب‌های واقعاً خوبی که در ارتباط با روش تَرکه‌ای (lean) دوست دارم، کتاب تویوتا کاتا نوشته مایک رودر است. تویوتا کاتا، کتابی است که فلسفه مدیریتی بهبود مستمری که تویوتا از آن پیروی می‌کند را توضیح می‌دهد که واقعاً برای پیاده‌سازی این ایده‌ها کلیدی است. یکی از چیزهایی که او می‌گوید این است که شکل سازمان‌ها نیست که تعیین کننده است، بلکه رفتار افراد است. خیلی از شرکت‌ها برای رسیدن به برخی چیزهایی که در مورد آن صحبت کردیم، به نوعی تغییر ساختاری می‌پردازند اما لزوماً تغییر ساختار برای رسیدن به نتیجه کافی نیست، آن‌چه باید تغییر کند، رفتار افراد است.و اگر کنار یکدیگر ننشینند، چطور می‌توان رفتار افراد را تغییر داد؟این سئوال خیلی خوبی است و فکر می‌کنم کاملاً درست است یعنی کنار یکدیگر نشستن یکی از راه‌های این کار است. اگر به شرکت‌هایی مانند گوگل و فیسبوک نگاه کنید البته گوگل را که می‌دانم قطعاً این‌جور است، آن‌ها سرویس‌هایی دارند و این‌طور نیست که بر روی یک سرویس مثلاً دو تیم یا تنها ده نفر کار کند بلکه در مورد برخی سرویس‌ها، ده‌ها فرد با هم فعال هستند. آن‌ها اطمینان یافته‌اند که این افراد در یک طبقه باشند. ممکن است یک میز داشته باشید که تعدادی توسعه‌دهنده دور آن باشند و یک میز داشته باشید که تعدادی کارمند عملیات آنجا باشند، همگی دور یک میز نیستند اما همگی در یک طبقه هستند.اما گوگل و آمازون توسعه‌دهنده‌های روشن فکر و با تفکرات رو به جلویی دارند و نه آدم‌های قدیمی که نمی‌خواهند تغییری بدهند.درسته. این یکی از مؤلفه‌هایش است. داستان مورد علاقه من در ارتباط با تغییر فرهنگی، مجدداً یک مطالعه موردی از تویوتا است البته این فقط یکی از منابع است چون ما مدت طولانی است که داریم این کار را انجام می‌دهیم و داستان‌های خوب زیادی وجود دارد. این داستان، که در شبکه این زندگی آمریکایی، منتشر شده است در واقع یکی از پادکست‌های مورد علاقه من است. در آنجا در مورد NUMMI (مخفف New United Motor Manufacturing Inc)‌ صحبت می‌شود که یک طرح مشارکتی است که بین تویوتا و جنرال موتورز آمریکا، تنظیم شده است. من در کالیفرنیا زندگی می‌کنم، NUMMI در همان سایت قبلی جنرال موتورز بود که «فری‌مانت اسمبلی» خوانده می‌شد. فری‌مانت اسمبلی، بسته شد زیرا کیفیت خودروهای تولیدی واقعاً افتضاح بود. در آنجا، کارمندان خط تولید آدم‌های نگون‌بختی بودند که از شغل‌شان متنفر بودند و در کارشان خراب‌کاری می‌کردند. مثلاً قوطی‌های خالی نوشابه را درون در ماشین قرار می‌دادند تا موقع باز و بسته کردن سر و صدا کند یا این‌که هنگام کار الکل می‌نوشیدند بنابراین، کارخانه به علت به صرفه نبودن و کیفیت پایین بسته شد. وقتی تویوتا برای تولید خودرو به آمریکا آمد -چون کنگره، تعرفه‌ای برای ماشین‌های تولید خارج در نظر گرفته بود- جی‌.ام می‌خواست یاد بگیرد که چطور خودروهای کوچک بسازد زیرا جی‌.ام و دیگر تولیدکنندگان خودرو در آن زمان، خیلی سوخت مصرف می‌کردند و می‌خواستند بدانند چطور خودروهای کوچک اقتصادی بسازند. بنابراین آن طرح مشارکتی را در اوایل دهه ۸۰ بنا کردند. آن‌چه آن‌ها انجام دادند که خیلی غیرمعمول بود، این بود که از همان نیروی کار [قبلی] استفاده کردند. مدیر فری‌مانت اسمبلی، تویوتا را قانع کرد که همان نیروی کار قبلی را استخدام کند که [به نظر] کار احمقانه‌ای بود. اما آن‌ها، آن افراد را دوباره استخدام کردند و به شهر تویوتا در ژاپن فرستادند و آن‌ها را در سیستم تولید تویوتا، آموزش دادند و بعد همه آن‌ها برگشتند تا کار در NUMMI را آغاز کنند. بعد از چند هفته، آنها خودروهایی تولید می‌کردند که به همان کیفیت خودروهای تویوتا که در ژاپن تولید می‌شد، بود. آن‌ها تویوتای کَمِری می‌ساختند. آن‌ها خودروهایی می‌ساختند که از همه خودرو‌هایی که تا آن موقع جی‌.ام ساخته بود، با کیفیت‌تر بود. آن‌چه مشخص شد این بود که افراد مشکل نبودند، این سیستم بود که مشکل بود.آن‌ها به غیر از این‌که یک سفر خوب به ژاپن داشتند، چه کردند؟[سفر] یکی از مؤلفه‌های آن بود :-) مؤلفه‌ دیگر این بود که آن‌ها تازه اخراج شده بودند و آماده انجام هر کاری بودند. فکر می‌کنم هر دو مهم است اما نکته کلیدی که در پادکست در مورد تفاوت سیستم تولید در تویوتا به آن اشاره می‌شود، کار گروهی است. این‌که همه با هم کار می‌کنند تا به خروجی مطلوب مشتری برسند که در این مورد قبلاً هم صحبت کردیم.یک رویه‌ای که همه در مورد آن صحبت می‌کنند این است که بتوان خط تولید را متوقف کرد. در کارخانه قبلی جی.ام چیزی که رخ می‌داد به این صورت بود که یک خودرو وارد خط تولید می‌شد و شما به‌عنوان یک کارگر، زمان مشخصی قبل از آنکه خودرو از محدوده شما خارج شود، برای انجام کارتان در کل آن فرآیند را داشتید و به‌عنوان مثال اگر نمی‌توانستید درِ خودرو را در زمانی که داشتید متصل کنید، خودرو راهش را به سمت فرد دیگر ادامه می‌داد و اتفاقی که می‌افتاد این بود که خودروهایی در خط جریان می‌یافتند که کارهایشان بد انجام شده بود یا درست کار نمی‌کرد. در انتها، انبوهی از آن‌ها در پارکینگ جمع می‌شد تا بعداً درست شود.در تویوتا، کارها این‌طور انجام نمی‌شود. در تویوتا اگر نتوانید در مثلاً دو سوم زمان تعیین شده کار را انجام دهید، می‌توانید یک طناب که طناب اَندن (andon cord) نامیده می‌شود را بکشید تا یک علامت را روشن کند و مدیر برای کمک شما بیاید. در آن زمان این ایده که مدیر برای کمک شما بیاید برای جی‌.ام خیلی غیرمعمول بود :-) زیرا آنجا یک رابطه خیلی خصومت‌آمیزی بود اما در تویوتا، مدیر به کمک شما می‌آمد و اگر نمی‌توانستید کارتان را انجام دهید، دوباره طناب را می‌کشید و کل خط تولید را متوقف می‌کردید. این صحبت‌ها برای کارمندان جی‌.ام احمقانه به نظر می‌رسید و متوجه نشده بودند که هر چند یک‌بار طناب اندن، کشیده خواهد شد. ممکن است فکر کنید که طناب چند بار در روز کشیده می‌شود اما در تویوتا، طناب اندن، هزاران بار در روز کشیده می‌شود.این‌ها باعث متوقف شدن خط می‌شود یا به معنای این است که من به کمک نیاز دارم؟هر روزه چندین هزار بار به معنای من به کمک نیاز دارم کشیده می‌شود.و برای متوقف کردن خط فقط چند بار در روز است؟من دقیقاً نمی‌دانم هرچند یک‌بار خط متوقف می‌شود اما قطعاً این اتفاق می‌افتد. ایده این است که همه با هم کار می‌کنند و در این‌جا مهم‌ترین چیز، دوباره همان مفهوم جیدوکا است، این ایده که کیفیت را درون کار قرار دهید که یک روش کاملاً متفاوت است. جان شوک در مقاله‌ای که فکر می‌کنم در مجله مرور مدیریت سلحشوری (sloan management review) منتشر شد می‌گوید: «چیز بزرگی که تغییر کرد، دادن ابزار و مهارت‌ به کارگران برای انجام کارشان و قدرت بخشیدن به آن‌ها برای رسیدن به خروجی مطلوب مشتریان بود.» این تغییرات رفتاری است که خیلی اساسی است.بنابراین در قیاس، [در مهندسی نرم‌افزار شامل] این‌ها است: پیاده‌سازی یکپارچه‌سازی مستمر، اجازه دادن به مهندسان که ابزار خودشان را انتخاب کنند، اجازه دادن به مهندسان که کدها را به محیط عملیاتی بفرستند، توانایی دادن به مهندسان برای تأثیرگذاری بر روی خروجی‌های قابل عرضه به مشتری، توانایی دادن به ایشان برای یادگیری خروجی‌های مطلوب مشتریان، در تماس قرار دادن آن‌ها با مشتری، دادن ابزارهایی که برای کار به آن نیاز دارند، همین‌طور آموختن به ایشان که ماحصل مطلوب ما به‌عنوان یک شرکت چیست، نگفتن اینکه چه ویژگی‌هایی می‌خواهیم بلکه گفتن خروجی‌های کسب و کار که می‌خواهیم به آن برسیم به ایشان و این‌که آن‌ها، مسئول آن ویژگی‌هایی هستند که می‌خواهیم بسازیم.بیایید کمی از فرهنگ به سمت رویه‌ها جابجا شویم. از گفته‌های شما است که یکی از مهمترین رویه‌ها این است که همه چیز در مخزن کنترل نسخ (source control) قرار بگیرد. چرا این‌طور است؟قرار دادن همه چیز در مخزن کنترل نسخ به چند دلیل اهمیت دارد: نخست آنکه می‌توانید تست‌های خودکار در سطح سیستم انجام دهید. دوست دارم بگویم که از کار انداختن یک سیستم وب با استفاده از تغییر در تنظیمات فایروال نسبت به از کار انداختن آن با تغییر در تنظیمات کد، بسیار ساده‌تر است. بنابراین می‌توانیم این تغییرات پرریسک را با همان نرخی تست کنیم که تغییرات کد را تست می‌کنیم. فکر می‌کنم مسائلی از قبیل شبکه‌های تعریف شده با نرم‌افزار (software defined networking) آن را در آینده حتی ساده‌تر هم خواهد کرد. ما باید تغییرات در شِمای پایگاه داده را تست کنیم. همه این جور تغییرات مختلف باید تست شود. بنابراین تا زمانی‌ که چیزها در مخزن کنترل نسخ قرار نگرفته باشد، نمی‌توانید تدارک چنین کارهایی را ببینید و تست‌های مربوط به تغییرات پایگاه داده را در فرآیند تست خودکار اجرا کنید.دلیل دیگری که اهمیت دارد، به لحاظ معیارهای پایداری است. ما در این مورد صحبت کردیم که زمان بازراه‌اندازی یک سرویس، چه معیار مهمی است. در هنگام رخداد خرابی، مهم است که بتوانید سرویس را در یک مدت زمان قابل پیش‌بینی، بازراه‌اندازی کنید. تنها راهی که می‌توانید این‌کار را انجام دهید این است که پیکربندی سیستم عملیاتی خود را مجدداً از اطلاعات موجود در مخزن کنترل نسخ، بسازید. بنابراین تنها از لحاظ ترمیم خرابی هم که در نظر بگیریم، مسأله خیلی مهمی است که بتوانیم این کار را انجام دهیم. هر چیزی که بخشی از داده‌های شماست باید در مخزن کنترل نسخ قرار بگیرد.اینجا هم تقریباً مانند همیشه همین‌طور است که چیزهایی که باعث افزایش توان عملیاتی (throughput) می‌شوند، باعث افزایش پایداری (stability) هم می‌شوند. بنابراین قرار دادن چیزها در مخزن کنترل نسخ، باعث افزایش هر دو این‌ها می‌شود، باعث افزایش توان عملیاتی می‌شود چراکه این امکان را می‌دهد که محیط تست خود را خیلی سریع‌تر تدارک ببینید و همین‌طور باعث افزایش پایداری می‌شود زیرا این امکان را می‌دهد که هنگام ترمیم خرابی سریع‌تر سیستم را مستقر کنید.شما کمی قبل از این مصاحبه یک صحبت داشتید که در آن گفتید که اگر انشعاب (Branch) بگیرید، دیگر یکپارچه‌سازی مستمر ندارید. آیا ممکن است برای افرادی که آنجا نبوده‌اند، دراین‌باره توضیح دهید.بله، فکر می‌کنم الان، این بحث‌برانگیزترین چیزی باشد که می‌گویم. این‌که انشعاب‌های مربوط به ویژگی‌های جدید (feature branch) اساساً ایده بدی است. من می‌توانم آن را به‌عنوان شعار بکار برم اما حقیقت ظریف‌تر از این است. مشکل، انشعاب‌‌های مربوط به ویژگی‌ها نیستند بلکه انشعاب‌های طولانی‌مدت ویژگی‌ها هستند و به طور خاص، انشعاب‌های ویژگی که تغییرات زیادی در آن‌ها قرار دارد.در واقع مشکل از انشعاب گرفتن نیست، مشکل از ادغام کردن (merge) است. اگر تنها دو توسعه‌دهنده باشند، خوب است اما وقتی تعداد توسعه‌دهندگان افزایش می‌یابد، آنچه رخ می‌دهد این است که من بر روی کدهایم در انشعاب مربوط به یک ویژگی کار می‌کنم و ممکن است تولید آن ویژگی چند روز طول بکشد و بعد یک سری ریفاکتورهای خیلی خوب پیدا کنم که کد را خیلی بهتر کند. بنابراین در یک ارسال شبانه، آن ریفاکتورها را به شاخه اصلی (master) می‌فرستم. در همان زمان، شما دارید بر روی ویژگی دیگری کار می‌کنید و احتمالاً چند روزی است که دارید روی آن کار می‌کنید. شما تغییرات من که شامل ریفاکتورهای من است را می‌گیرید اما بالقوه ادغام کردن آن ریفاکتورها خصوصاً اگر یک معماری ایده‌آل نداشته باشید، ممکن است برای شما زجرآور باشد. این زجر با افزایش تعداد افراد تیم به‌صورت غیرخطی افزایش می‌یابد. هر چه تعداد افراد تیم بیشتر باشد، ادغام زجرآورتر می‌شود و هر چه که طول انشعاب‌ها بیشتر باشد، باز هم زجرآورتر می‌شود. در واقع، وقتی عادات خوبی از قبیل ریفاکتور، دارید از آنجایی که همه افراد تیم که چند روزی است بر روی چیزهای دیگر کار می‌کنند، را مجبور می‌کنید که آن را گرفته و ادغام کنند و این می‌تواند بر روی کار همه آن‌ها تأثیر بگذارد. در این شرایط، ممکن است به ناگاه خیلی معروف ‌شوید :-)فقط برای این که روشن‌تر شود، منظورتان از ادغام، بخش فنی آن نیست زیرا با ابزار git، ادغام در سطح کد خیلی راحت انجام می‌شود.این هست اما ادغام معنایی را (semantic marge) هم داریم که متفاوت با ادغام متنی (text merge) است. من این را تجربه کرده‌ام و مطمئنم خیلی از مخاطبین شما هم این را تجربه کرده‌اند که کدی را داشته‌اند که خیلی خوب ادغام می‌شده اما همچنان باعث خرابی چیزی می‌شده است. زیرا ادغام ، شامل ناسازگاری (conflict) دو خط از کد نبوده، بلکه شامل ناسازگاری از این جهت بوده که یک جا یک تابع یا متدی فراخوانی می‌‌‌شده اما الان به‌جای آن، متد دیگری فراخوانی می‌شود اما فرد دیگری آن متد را عوض کرده است. در این شرایط ناسازگاری (متنی) وجود ندارد اما رفتار سیستم عوض شده است و ما متوجهش نشده‌ایم.و اگر خوش‌شانس باشید کامپایلر یا تست‌های واحد (unit tests) متوجهش می‌شوند.قطعاً، اگر کار نوشتن تست‌های واحد (unit test) را خوب انجام داده باشید، آن‌ها متوجهش می‌شوند. اما [این خطاها] تنها زمانی کشف می‌شوند که کدهایی که از لحاظ معنایی با یکدیگر در تعارض‌اند در یک مخزن کد (code base) قرار داشته باشند. وقتی ادغام بین انشعاب‌های مربوط به ویژگی‌ها فقط از طریق ادغام شاخه اصلی در یک انشعاب مربوط به ویژگی انجام می‌شود، این شرایط می‌تواند رخ دهد. تنها راهی که بتوانید سیستم را عملیاتی کنید این است که همه انشعاب‌های مربوط به ویژگی‌ها را با هم ادغام کنید و این یک مسأله ترکیبی (combinatorical) و نه خطی است.بسیار خوب، روشن است که یک بخش از این گفته که همه چیز باید در مخزن کنترل نسخ قرار گیرد همان مبحث مدیریت پیکربندی (configuration management) است. مدیریت پیکربندی چیست؟سئوال خوبی است زیرا افراد مختلف، آن را به روش‌‌های مختلفی بکار می‌برند. من فکر می‌کنم مدیریت پیکربندی، برنامه‌ریزی چگونگی تبدیل چیزهای موجود در مخزن کنترل نسخ به یک سیستم اجرایی است.بنابراین ما داریم در مورد ابزارهایی از قبیل Puppet ، Chef و Ansible صحبت می‌کنیم.بله، طیف کاملی از آنها وجود دارد. معلوم است که من در Chef هستم و نمی‌توانم بگویم که خیلی خوب کار می‌کند. اما طیف کاملی از ابزارها در بازار وجود دارند که تکه‌ها را از مخزن کنترل نسخ برمی‌دارند و آن‌ها را به یک سیستم اجرایی تبدیل می‌کنند. معمولاً فقط به ابزار مدیریت پیکربندی نیاز ندارید بلکه به دسته‌ای از ابزارهای دیگر هم نیاز دارید، هر کاری در این حیطه قرار می‌گیرد: ساختن بسته نرم‌افزار، امور شبکه (networking)، ذخیره‌سازی (storage)، ...و پیکربندی فایروال‌ها یا سرورهای برنامه (application servers)، ...قطعاً. هر چیزی، هر چیزی که برای بازسازی یک سیستم اجرایی نیاز داشته باشید، در این حیطه قرار می‌گیرد. این‌ها ساده‌تر شده است اما قطعاً یک مسأله حل شده به‌شمار نمی‌رود.اخیراً جنبشی هست که از مدیریت پیکربندی، به سمت محفظه‌سازی (containerization) برویم مانند آنچه با Docker انجام می‌دهید. آیا این نیز در برنامه تحویل مستمر قرار دارد؟بله، فکر می‌کنم Netflix از پیشگامان این قضیه بود. Netflix این ایده را داشت که واحدی که برای استقرار یا بسته‌بندی نرم‌افزار باید داشته باشیم، AMI است.این AMI از چیزهای مربوط به مجازی‌سازی در آمازون است. درسته؟بله، مخفف تصویر ماشین آمازون (Amazon Machine Image) است. در Netflix کاری که در خط لوله استقرار می‌کنند این است که یک AMI می‌سازند و این AMI در خط لوله تا محیط عملیاتی پیش می‌رود بنابراین واحد بسته‌بندی و استقرارشان است. آن‌ها یک ابزار دارند که آن‌طور که یک نفر می‌گفت، Bakery خوانده می‌شود که آن AMI را می‌سازد و به خط تولید منتقل می‌کند.آنچه ما در ابزارهایی مانند Docker می‌بینیم همان‌طور که شما اشاره کردید، حرکت به سمت این نوع واحد استقرار است. این نه تنها بر روی چرخه کار سیستم عملیاتی بلکه بر روی چرخه کار توسعه‌دهند‌ه‌ها هم تأثیر شگرفی دارد. فکر می‌کنم Vagrant با فراهم کردن این قابلیت که در سیستم‌های توسعه‌دهندگان، محیط‌های مشابه سیستم عملیاتی داشته باشیم، در روش تست نرم‌افزار، انقلابی ایجاد کرد. با ابزارهایی مانند Docker، می‌توانید همان کار را کرده و از آنها در همه مسیر فرآیند از توسعه‌دهنده تا محیط عملیاتی استفاده نمایید. بنابراین، بله، فکر می‌کنم این‌ها تغییرات شگرفی هستند و باید معماری سیستم‌تان را با درنظر گرفتن آن‌ها تنظیم کنید. اما اگر روی یک سیستم بدون پیشینه (greenfield system) کار نمی‌کنید، خیلی دشوار است که این چیزها را به آن بخورانید. و البته همواره جایی برای Chef و ابزارهای مدیریت پیکربندی هست زیرا فقط در آن ارتباط نیست بلکه در مورد همه زیرساخت‌های پشتیبانی شده است و یک بخش سطح بالا از این هم‌نوایی ابزارها را تشکیل می‌دهد. و همین‌طور همه موارد، مربوط به محفظه‌ها (container) نیست بلکه بعد از آن، باید آن‌ها (محفظه‌ها و سرورها) را به خوبی به هم متصل کنید تا به درستی کار کنند.ما اخیراً اپیزودی در مورد Vagrant داشته‌ایم. در آینده نیز اپیزودهایی در مورد وب‌سرویس‌های آمازون و Docker خواهیم داشت. مخاطبان می‌توانند برای یادگیری بیشتر در مورد این ابزارها به آنها مراجعه کنند. فکر می‌کنم که آن‌چه می‌‌خواستم گفته شود به خوبی پوشش داده شد. آیا چیزی هست که بخواهید بگویید و من در موردش نپرسیده باشم؟مورد دیگری که به نظر من خیلی جذاب است، خصوصاً در گزارش وضعیت DevOps آن را انجام دادیم، این است که می‌توانیم فرهنگ را کمّی‌سازی کنیم. مدلی که برای کمّی‌سازی فرهنگ استفاده کردیم، توسط ران وستروم ابداع شده بود. او یک روانشناس است که در ارتباط با ایمنی در حوزه صنایع بهداشت و هوانوردی مطالعه می‌کند. او مدلی ساخته است که بوسیله آن می‌تواند خروجی این‌گونه صنایع را پیش‌بینی کند. نکته جالب این بود که ما از مدل او در گزارش وضعیت DevOps استفاده کردیم تا کارایی صنعت IT را پیش‌بینی کنیم، همان مدلی که فرهنگ را پیش‌بینی می‌کرد، می‌توانست خلاقیت، پایداری و بازدهی را نیز پیش‌بینی کند. این مسئله چشم من را باز کرد. شما می‌توانید به گزارش وضعیت DevOps مراجعه کرده و ببینید که مدل وستروم چیست. در واقع آن را جان آلسپو برایم فرستاد. جان آلسپاور هم‌اکنون رئیس DevOps در Etsy است. من به او ایمیل می‌زنم و او با pdf های مربوط به مقالاتی که اخیراً خوانده و واقعاً دوست داشته جواب می‌دهد. به این روش من چیزهای زیادی از او گرفته‌ام و این مقاله یکی از آن‌ها است. در حال حاضر او در مقطع کارشناسی ارشد رشته ایمنی در دانشگاه لاند در سوئد درس می‌خواند.به نظر من با تعامل داشتن با افرادی که در حوزه‌ها و صنایع دیگری مشغول هستند، می‌توانیم چیزهای زیادی یاد بگیریم و این مدل‌هایی که سال‌هاست که در حوزه‌های دیگر استفاده شده‌اند، کاربردهای واقعاً مهمی در توسعه نرم‌افزار دارند.شما اخیراً از ThoughtWorks به Chef رفته‌اید. افراد چطور می‌توانند با شما در تعامل باشند؟ نقش شما در کسب و کار آن‌جا چیست؟در Chef من یک نقش متمرکز داخلی دارم که با بکارگیری همه چیزهایی که در موردش صحبت کردم، کمک ‌کنم که سازمانی بسازم که‌ در همه بخش‌ها، سریع‌تر حرکت کند. من کتابی دارم، که Lean Enterprise نام دارد. این کتاب، اساساً به این شکل طراحی شده است که درباره همه موارد سازمانی، فرهنگی و معماری که افراد را از تحویل مستمر باز می‌دارد (همه مباحثی که پیش از این در موردش صحبت کردیم)، صحبت کرده و افراد را در این زمینه‌ها کمک می‌کند. معمولاً می‌گویند که: این روش خوبی به نظر می‌رسد اما به فلان دلیل یا بهمان دلیل، اینجا کار نمی‌کند. ما به این فلان و بهمان‌ها در این کتاب اشاره کرده‌ایم: دلایل مالی، مالکیتی، مدیریت ریسک، مدیریت پروژه، امور اداری و ... . همه این موارد در کتاب پوشش داده شده است. من خیلی از این ایده‌ها را به کار گرفته‌ام تا کمک کنم که Chef در همه بخش‌ها، سریع‌تر حرکت کند.بسیار خوب، جالبه. چگونه می‌توانیم اطلاعات بیشتری از شما بدست آوریم؟ شما در توییتر هستید؟بله، به آدرس jezhumble@. من یک وب‌سایت به آدرس continuousdelivery.com دارم. آدرس ایمیل من jez@chef.com است. اما بله، توییتر بهترین روش در تماس بودن با من است.بسیار خوب، این قسمت تمام می‌شود. از وقتی که گذاشتید خیلی ممنونم. فکر می‌کنم خیلی جذاب بود.از اینکه دعوتم کردید خیلی متشکرم.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Sun, 26 Feb 2023 23:02:52 +0330</pubDate>
            </item>
                    <item>
                <title>تبدیل شدن به یک رهبر فنی</title>
                <link>https://virgool.io/se-radio/se-radio-tech-lead-t8eioiy13dxd</link>
                <description>مطلبی که می‌خوانید ترجمه‌ی قسمت ۲۶۵ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت یوهان سوِن با پاتریک کوآ درباره‌ی نقش رهبر فنی (Technical Lead) و چگونگی تبدیل شدنِ یک فرد به رهبر فنی صحبت می‌کند. تعریف رهبر فنی، مسئولیت‌های این نقش و چالش‌های تبدیل شدن به یک رهبر فنی از جمله موضوعاتی هستند که در این گفتگو مطرح می‌شود.به یک برنامه‌ی دیگر از رادیوی مهندسی نرم‌افزار خوش آمدید. امروز با پاتریک کوا هستم. به رادیوی مهندسی نرم‌افزار خوش آمد پاتریک! خوشحالیم که با ما هستی.ممنونم که مرا دعوت کردید، خوشحالم که با شما صحبت می‌کنم.پاتریک کوا یک مشاور ارشد و یک رهبر فنی در Thoughtworks است. معمولاً در لندن زندگی می‌کند، هرچند در حال حاضر در برلین کار می‌کند. او در زمینه‌ی توسعه‌ی نرم‌افزار بیش از یک دهه تجربه دارد و تمرکزش بر افراد، کسب و کار و فناوری است. ممکن است او را به واسطه‌ی کتاب «دفترچه راهنمای گذشته‌نگر» (The Retrospective Handbook) و یا کتاب جدیدترش «گفتگو با رهبران فنی» (Talking with Tech Leads) بشناسید. پاتریک همچنین در زمینه‌ی آموزش رهبری فنی، هم به صورت داخلی در Thoughtworks و هم در خارج از آن فعالیت داشته است. من در یکی از این آموزش‌های او بوده‌ام. موضوع این برنامه چگونگی تبدیل شدن به یک رهبر فنی است که کاملاً منطبق [با تجربیات او] است.پاتریک آیا چیز دیگری هست که بخواهی در مورد خودت بگویی؟نه، خیلی خوب خلاصه‌اش کردی.برای این‌که جای ابهامی باقی نماند، هم من و هم پاتریک در Thoughtworks کار می‌کنیم. برای همین من در یکی از آموزش‌های او شرکت کردم. اولین سؤالی که هنگام صحبت کردن در مورد رهبری فنی به ذهن می‌رسد این است که نقش رهبر فنی چیست؟ وقتی من یک رهبر فنی می‌شوم چه مسئولیت‌هایی دارم؟این سوال خیلی خوبی است. اول از همه باید بگویم که فقط یک تعریف خوب در این مورد وجود ندارد، چون هر سازمانی این نقش را به شکلی متفاوت تلقی می‌کند. من با تعداد زیادی از مشتریان در سازمان‌های متفاوت کار کرده‌ام؛ فکر می‌کنم بتوانم آن‌چه که به نظرم ویژگی‌های مشترک مسئولیت‌های یک رهبر فنی است را بگویم.در برخی سازمان‌ها به رهبر فنی، توسعه‌دهنده‌ی پیشرو اطلاق می‌شود؛ در سایر سازمان‌ها به آن معمار می‌گویند. به نظر من، ترکیب این دو تفکر این است که رهبر فنی، نقشِ یک معمار نیست که خارج از تیم است. در واقع یک توسعه‌دهنده است. کسی که دارای مهارت‌های توسعه است و مسئولیت رهبری تیم را بر عهده دارد. این نقش با نقش توسعه دهنده‌ی ارشد کاملاً متفاوت است، که هدایت یک حوزه در بخشی از سیستم را بر عهده دارد. رهبر فنی سعی می‌کند بر اثرگذاری کلی تیم تمرکز کند. من انتظار دارم که یک رهبر فنی تا حدی کد بنویسد و همچنین در سطوح فنی کار کند.آنچه که به نظر من رهبر فنی نیست، چیزی است که افراد اغلب به آن مدیر فنی می‌گویند. کسی که بیشتر مسئولِ پیشرفت افراد و گزارش‌هاست اما لزوماً درگیر معماری نیست. حتی اگر پیش‌زمینه‌ی فنی داشته باشد لزوماً بر سیستم متمرکز نیست. انتظار دارم که مدیران فنی با رهبر فنی در تعامل باشند.در بسیاری شرکت‌های دیگر استاد اسکرام (Scrum Master) نقش خیلی محبوبی است و به نظر من، این نقش خیلی متفاوت [از رهبر فنی] است، هر چند یک رهبر فنی می‌تواند استاد اسکرام هم باشد. استاد اسکرام بودن، لزوماً به صورت خودکار از شما یک رهبر فنی نمی‌سازد.این جنبه، شاخص است که رهبر فنی همچنان یک توسعه‌دهنده است که بر اثرگذاری تیم تمرکز دارد.درست است.آیا در مقام مقایسه موافقید که مدیر فنی منحصراً بر تیم تمرکز دارد، معمار منحصراً بر فناوری تمرکز دارد، و توسعه‌دهنده‌ی ارشد کسی است که مالک بخش خاصی از سیستم است؟بله، درست است. تأکید می‌کنم که این‌ها مربوط به نقش‌ها هستند، و این به آن معنی نیست که یک سازمان برای هر یک از نقش‌ها فرد مجزایی خواهد داشت. گاهی یک فرد چند تا از این نقش‌ها را بازی می‌کند. ممکن است رهبر فنی نقش مدیر فنی را هم داشته باشد که مراقب افرادِ خط تولید است و ممکن است در عین حال ارشدترین عضو تیم هم باشد. اما در شرایط دیگر مثلاً از نظر اندازه‌ی تیم یا نحوه‌ی ساختاردهی یک سازمان، ممکن است نقش‌های جداگانه‌ای هم باشند.من نوعی از تقسیم [وظایف] را [در نقش رهبر فنی] می‌بینم؛ یک جنبه‌ی فنی که مربوط به معماری و مسیر سیستم است، و جنبه‌ی مدیریت افراد و پروژه که ممکن است بیشتر مربوط به مدیر فنی باشد. این یک الگوی متداول است که می‌بینم. اما تأکید می‌کنم که این یک نقش است و به این معنی است که مجموعه‌ای از مسئولیت‌ها را شامل می‌شود.پیش از آن‌که در این موضوع عمیق‌تر شویم آیا ممکن است توضیح دهید که دقیقاً چرا به رهبر فنی نیاز داریم؟بله، این سؤال خیلی خوبی است. وقتی در کنفرانس‌ها در مورد این‌که رهبر فنی چیست صحبت می‌کنم، یکی از سؤالاتی که عموماً پرسیده می‌شود این است که «چرا به آن نیاز داریم؟» قطعاً می‌توانم شرایطی را تصور کنم که در یک تیم کوچک کار می‌کنید و همه به خوبی با هم کنار می‌آیند و هر کس می‌داند که باید چه کاری انجام دهد؛ در چنین شرایطی شاید به یک رهبر فنی احتیاجی نباشد، چون همه کارشان را می‌دانند و به خوبی هماهنگ شده‌اند. این یک وضعیت ایده‌آل است و بسیاری تیم‌ها هستند که در وضعیت آشفته‌تری هستند و ترکیبی از مهارت‌های متفاوت دارند. عموماً ممکن است درباره‌ی نحوه‌ی پیاده‌سازی یا مسیر سیستم و معماری ابهاماتی وجود داشته باشد. خیلی خوب است که توسعه‌دهندگانی که توانایی گرفتن چنین تصمیماتی دارند، این تصمیمات را در کارهای خودشان بگیرند. اما زمانی که افراد در مقابل یکدیگر قرار می‌گیرند با یک آشفتگی مواجه می‌شوید. به نظر من یکی از وظایف یک رهبر فنی این است که کاری کند توسعه‌دهندگان به شکلی اثربخش در یک جهت فعالیت کنند.حتی یک تیم پایدار که به خوبی با هم کنار می‌آیند ممکن است روزی در در انتخاب مسیر، یک چارچوب کاری، یک ابزار، و یا یک ویژگی اختلاف نظر پیدا کنند و با تفرقه مواجه شوید. نقش رهبر فنی این است که به نحوی از تیم مراقبت کند که تیم در مسیر مشخصی قدم بردارد و بیشترین اثرگذاری را داشته باشد.به خاطر دارم که یک توئیت را در ارائه‌تان به اشتراک گذاشته بودید: «در آخرین پروژه‌ام ده نفر بودند که همه‌شان عقایدی سرسختانه داشتند که در کد نشان داده شده بود.» آیا به همین مسئله اشاره دارید؟بله، دقیقاً. این توئیت را در آن‌جا قرار دادم چون این مسئله را از دیدگاه دیگری خلاصه می‌کند. [فرض کنید] مخزن کدی (Codebase) را باز کرده‌اید که آن را نمی‌شناسید (یک مخزن کد غریبه) و بخش‌های مختلف سیستم را باز می‌کنید. در این‌صورت، یک نشانه از رهبری فنی کارآمد و کار تیمی این است که در حالت کلی این حس وجود داشته باشد که همه چیز با یک طرز تفکر در توسعه نوشته شده است. اگر ده نوع شخصیت متفاوت داشته باشید که به ده شکل مختلف کد بنویسند اولاً نگه‌داری آن به یک کابوس تبدیل می‌شود، و [دوماً] به انزوای بیشتری ختم می‌شود. به طور کلی این برای من یک نگرانی در مورد کارایی تیمی است.بله، بسیار خوب. شما در جاهای مختلفی رهبر فنی بوده‌اید و خیلی با تجربه شده‌اید. البته زمانی بوده که شما برای اولین بار رهبر فنی شدید. می‌شود حس‌تان و این‌که چطور این اتفاق افتاد را شرح دهید؟بله، قطعاً. فکر می‌کنم اولین تجربه‌ام خیلی تکان‌دهنده بود. به تازگی از تعطیلات برگشته بودم و داشتم در یک تیم کار می‌کردم. روزی که داشتم بر می‌گشتم در فرودگاه با من تماس گرفتند و گفتند که به عنوان رهبر فنی‌ِ تیم دیگری شروع به کار خواهم کرد. به خاطر این‌که یک توسعه‌دهنده بودم و الان باید کار دیگری انجام دهم شوکه‌ شده بودم. نمی‌دانستم معنی آن چیست. فکر می‌کنم برای بسیاری از افراد که خود را در این نقش می‌یابند، همین نگرانی‌ها وجود دارد. در نقش رهبری فنی، مجموعه‌ای از مسئولیت‌های توصیف نشده و کارهایی که باید به عنوان یک رهبر فنی انجام شود، وجود دارد. شاید به عنوان توسعه‌دهنده به خود اطمینان داشته باشند، اما ندانند که این‌ها چه تفاوتی با کار توسعه دارد. بسیاری از تجربیات من در این زمینه بود که بفهمم این نقش چیست. چون در واقع در آن زمان نمی‌دانستم برای یافتن این اطلاعات باید به کجا مراجعه کنم. خوشبختانه با افراد دیگری که به آن‌ها احترام می‌گذاشتم و به آن‌ها دسترسی داشتم، صحبت کردم و از آن‌ها در مورد رویکردشان سؤال کردم. اما می‌توانم بگویم که احساس می‌کردم حمایت نشده‌ام چون احساس امنیت نداشتم.آن ها در مورد نقش رهبری فنی چه گفتند؟برخی از آن‌ها در مورد مسائلی که به نظرشان مهم بود و رویکرد خودشان به این نقش، صحبت کردند. به خاطر دارم که یکی از آن‌ها در مورد تصویر بزرگ‌تر و معماری صحبت می‌کرد. وقتی یک توسعه دهنده هستید، احتمالاً بیشتر به تمیزی کدی که می‌نویسید و قابل تست بودن آن و طراحی خوب مؤلفه‌تان، فکر می‌کنید. اما گاهی فراموش می‌کنید که جای آن در تصویر بزرگ‌تر چیست. فکر می‌کنم این حس را در فضای چابک (Agile) دارم. عمدتاً در مورد معماری حرف نمی‌زنیم. من از داشتن نقش معمار و این‌که فقط چنین شخصی بر معماری تمرکز کند دفاع نمی‌کنم. در واقع اعتقاد دارم همه باید به معماری فکر کنند. در واقع بخشی از کار یک معمار این است که در برخی مقاطع به تیم کمک کند که در مسیر درستی قرار داشته باشند.نکته‌ی دیگری که یک نفر به من گفت این بود که هر چند رهبر فنی هستی بخشی از کارَت ارتباط با سایر اعضاست. زمانی که یک توسعه‌دهنده هستید و مناقشه‌ای میان دو توسعه‌دهنده در تیم می‌بینید، یک راهبرد عمومی این است که به کار خودتان ادامه دهید و آن را به عنوان مشکلِ خودتان به حساب نیاورید. اما به عنوان یک رهبر فنی تلاش برای برطرف کردن مناقشه یا جدال‌های طراحی میان دو توسعه‌دهنده، کار مهمی است. چون می‌خواهید همه در مسیر کلی توافق داشته باشند. لزوماً این‌که کدام راه‌حل درست است اهمیت ندارد، بلکه می‌خواهید همه سهمی در [تعیین] تصویر کلی داشته باشند.آیا در اولین تجربه‌ی رهبری فنی، مناقشه داشتید؟بله. پیش‌زمینه‌ی من به عنوان یک توسعه‌دهنده بیشتر فنی و مربوط به مهارت‌های معماری بود. فکر می‌کنم کارکردن با انسان‌ها باعث شد متوجه شوم افراد چقدر متفاوت هستند. این‌که افراد در کار با افرادی که پیش‌زمینه متفاوت و یا مهارت‌ها و توانایی‌های متفاوتی دارند، چقدر عجیب عمل می‌کنند.ممکن است با یک مثال این را توضیح دهید؟بله. ما معمولاً به روش برنامه‌نویسی دونفره (Pair Programming) کار می‌کردیم که در آن دو نفر پشت یک کامپیوتر می‌نشینند و روی یک داستان (Story) یا ویژگی (Feature) کار می‌کنند. یک زوج خاص را به خاطر دارم که یکی از آن‌ها فردی تحریک‌پذیر بود که می‌خواست کار را [به سرعت] انجام دهد. روش توسعه‌ی نفر دوم بیشتر این بود که باید کمی به این مسئله فکر کنم و می‌خواهم بروم و آن را مدل کنم، شکل بکشم. منظورم چند هفته یا چند روز نیست، بلکه نیاز به کمی زمان [داشت]. یادم می‌آید که مقداری آزردگی در تیم به خاطر این مسئله به وجود آمده بود. یکی از آن‌ها می‌گفت که می‌خواهم کار را انجام دهم و دیگری می‌گفت به نظرم آماده نیستیم و نمی‌دانم می‌خواهیم چه کنیم. به نظر من، این صرفاً دو سبک متفاوت است. آن‌ها نمی‌دانستند که هر کدام سبک متفاوتی دارند و نتوانسته بودند راهی برای کار کردن با یکدیگر پیدا کنند.پیش از آن تعطیلات مهم، پیش از آن تماس، با چنین شرایطی چطور عکس‌العمل نشان می‌دادید؟ به عنوان یک رهبر فنی چطور؟فکر می‌کنم قبل از تعطیلات احتمالاً می‌گفتم این مسئله به من مربوط نیست. مسئولیت رهبر فنی یا مدیر پروژه است که به آن رسیدگی کند.بنابراین حداکثر کاری که می‌کردید صحبت کردن با رهبر فنی یا مدیر پروژه بود؟احتمالاً آن را هم پشت گوش می‌انداختم. کمی عجیب است که در مناقشاتی که در آن قرار ندارید دخالت کنید. وقتی بعد از تعطیلات در این نقش قرار گرفتم احساس کردم این‌که تمام توسعه‌دهندگان بتوانند با هم صحبت کنند و توانایی‌های یکدیگر را درک کنند و با هم کنار بیایند، واقعاً مهم است. در چنین شرایطی، در نهایت هر دو طرف را به اتاقی بردم تا در مورد بازخوردهای صریح در مورد آن‌چه که می‌دیدم صحبت کنیم. این‌طور نبود که تلاش کنم آن‌ها را خجالت‌زده کنم، بیشتر این‌طور بود که متوجه شوم موضع هر طرف و ریشه‌ی آن چیست. به نظرم صحبت کردن در مورد این‌که برای هر کدام چه چیزی اهمیت دارد و دوست دارند چطور کار کنند، مفید بود. فکر می‌کنم این‌که به افراد اجازه دهیم نظرات‌شان را در محیطی امن‌تر بیان کنند مسئله‌ی مهمی بود.در نهایت آن‌ها روی یک سبک‌ کاری به توافق رسیدند؟بله. در نهایت چیزی که به آن رسیدند این بود که وقتی کار جدیدی را شروع می‌کنند، برای مدتی جدا از هم کار کنند. فردی که دوست داشت ادامه بدهد احتمالاً شروع به ساختن نمونه‌ی اولیه می‌شد و یا در مورد ابزارها و تکنولوژی‌های مرتبط با کارشان مطالعه می‌کرد. شخص دیگر هم به طراحی و مدل‌سازی می‌پرداخت. پس از یکی دو ساعت گرد هم می‌آمدند تا در مورد نحوه‌ی پیاده‌سازی با هم صحبت کنند.داستان خوبی است. با این داستان خیلی سطحی در مورد وظایف رهبر فنی صحبت کردیم. بنابراین باید چشم‌انداز پروژه و معماری کلی آن را در ذهن داشته باشید. یک برنامه‌ی خوب در مورد طرح‌های معماری نرم‌افزار داریم که توسط سایمون براون ارائه شده است که ممکن است ارزش شنیدن را داشته باشد. او نویسنده‌ی کتاب «معماری نرم‌افزار برای توسعه‌دهندگان» ( Software Architecture for Developers) است (اشاره به قسمت ۲۲۸ است-مترجم).این در مورد کار کردن با افراد بود که در مثالی که درباره مناقشه داشتید به آن اشاره کردید. چه کارهای دیگری را به عنوان مسئولیت‌های یک رهبر فنی می‌بینید؟در یکی از نوشته‌های بلاگم مدلی دارم که شبیه به نمودار وِن است. اگر دنبالش بگردید شاید آن را پیدا کنید. موضوعش درباره‌ی نقش رهبر فنی است. آن‌جا در مورد هم‌پوشانی سه حوزه صحبت می‌کنم. یکی از آن‌ها مهارت‌های توسعه است. برای من خیلی اهمیت دارد که یک رهبر فنی بتواند کد بنویسد و بتواند با سیستمی که ساخته می‌شود کار کند. معنی‌اش این نیست که فقط کد بنویسد اما باید بتواند این کار را انجام دهد و بتواند در هر مقطعی با توسعه‌دهندگان کار کند.حوزه‌ای مربوط به رهبری عمومی هم وجود دارد. منظور از آن مثلاً رسیدگی به مناقشات است. اما به نظرم چیزهای زیادی درباره‌ی رهبری وجود دارد که یک رهبری فنی کارآمد از آن بهره می‌گیرد. بخشی از آن این است که افرادِ در حوزه‌ی کسب و کار را متقاعد کند که باید به صورت تیمی به مسائل فنی بپردازند. چون باید این زمان را صرف کرده باشید تا بتوانید در برخورد با مسائل فنی عمیق و یا مسائل زیرساختی به صورت کارآمدتری عمل کنید. مثل یک خیابان دوطرفه است. باید توسعه‌دهندگان را هم متقاعد کنید که فقط روی مسائل فنی کار نکنند تا اطمینان داشته باشند میان چیزی که روی آن کار می‌کنند و کمک به کسب و کار، ارتباطی وجود داشته باشد. چون به این ترتیب می‌خواهید میان افراد فنی و کسب و کار اعتمادسازی کنید. بنابراین رهبر فنی به نوعی نقش یک پل را ایفا می‌کند. کمی در مورد مدیریت مخاطرات (Risk) صحبت کردم. به نظرم این یک مسئله‌ی خیلی بزرگ است که یک رهبری فنی باید به آن بیاندیشد. در بیشتر سازمان‌ها این نقش معمولاً مرتبط با افراد دیگری خارج از تیم است. این افراد ممکن است افراد تیم عملیات (Operations) یا پشتیبانی باشند که باید نرم‌افزار ساخته شده را اجرا کنند. همچنین ممکن است افراد حوزه‌ی بازاریابی و مالی باشند که در با پیامدها و ویژگی‌های نرم‌افزار [سروکار دارند]. در واقع هدف این است که یک نفر به طور کلی نگرانی‌های مخاطرات را در نظر دارد؛ برخی تیم‌ها ممکن است مدیر پروژه داشته باشند یا نه. رهبر فنی باید در مورد مخاطرات فنی هم بیاندیشد. مثلاً آیا وقتی نرم‌افزار در محیط محصول قرار می‌گیرد به اندازه‌ی کافی زیرساخت برای لاگ وجود دارد تا اگر چیزی خراب شد بتوان از آن پشتیبانی کرد؟ آیا تصمیمات فنی درستی گرفته‌ایم تا به نقشه‌ی راه یک فروشنده‌ی خاص وابسته نشویم و اگر آن فروشنده از بین برود نرم‌افزار ما هم دچار مشکل شود. آیا به اندازه‌ی کافی وقت صرف تمیز نگه داشتن کد و بازسازی (Refactor) آن می‌کنیم؟ چون در نهایت این منجر به کاهش اثرگذاری تیم می‌شود. فکر می‌کنم این‌ها مسئولیت‌های رهبری عمومی هستند.حوزه‌ی سوم مربوط به معماری است. یعنی تلاش برای این‌که افراد بیشتر به ساختن یک سیستم فکر کنند تا به نوشتن نرم‌افزار. یعنی فقط به ویژگی‌هایی که می‌نویسند فکر نکنند بلکه به زیست‌بومی (Ecosystem) که نرم‌افزار در آن زندگی خواهد کرد هم فکر کنند.یعنی فکر کردن به این‌که آیا باید با یک محفظه‌ی داکِر در فضای ابری (Cloud) مستقر شود یا چنین چیزهایی؟دقیقاً. فکر می‌کنم در هر تیم، متفاوت باشد. برخی‌ها خودشان سیستم‌شان را اجرا می‌کنند و آن را در محیط محصول مستقر می‌کنند. برخی دیگر، نرم‌افزار در حال اجرایشان را نمی‌بینند چون به بخش‌های دیگری در سازمان سپرده شده است. اما این موضوع اهمیت دارد که رهبر فنی به افراد کمک کند پیامدِ بازخوردهایشان را درک کنند؛ همچنین تلاش می‌کند توسعه‌دهندگان هم بازخوردهای مربوط به نرم‌افزاری که می‌نویسند را دریافت کنند. بخشی از آن هم این است که توسعه‌دهندگان درک کنند چه اتفاقی برای نرم‌افزارشان در محیط محصول رخ می‌دهد.عنوان نوشته‌ی بلاگی که به آن اشاره کردید «رهبر فنی-حوزه‌های مسئولیت» است. می‌خواهم کمی در مورد برخی چیزهایی که مطرح شد عمیق‌تر صحبت کنیم. چیزهایی مثل رهبری و همین‌طور امور مربوط به توسعه از جمله شئ‌گرایی، ‌کدنویسی، معماری تکاملی، و … . به نظرم تا حدی شبیه به مدیریت فرهنگ تیم است. آیا شما این را هم مسئولیت خود می‌بینید؟بله، قطعاً. فکر می‌کنم فرهنگ تیم یک بخش مهم است. در یکی از سخنرانی‌هایی که داشتم که عنوانش «راهنمای رهبری یک تیم برای یک خوره‌ی نرم‌افزار» (The geek&amp;#x27;s guide to leading a team) است در این مورد صحبت کردم که یک رهبر فنی باید بر چه چیزهایی از جنبه‌ی فرهنگ تیمی تمرکز کند. من آن را با رهبر تیم مقایسه می‌کنم، که روی نحوه‌ی تعامل اعضای تیم با یکدیگر کار می‌کند. در نقش رهبر فنی یک مسأله فرهنگی این است که افراد چه رویکردی نسبت به کدی که می‌نویسند دارند؟ مثلاً این‌که به دنبال ترویج چه نوعی از فرهنگ توسعه هستید؟ چون توانایی تأثیرگذاری بر آن را دارید.یک مثال از آن این است که اگر یکپارچه‌سازی مستمر (Continuous Integration) دارید، [ممکن است] یک بیلد (Build) خراب شود. من در تیم‌هایی کار کرده‌ام که در آن این خرابی ادامه پیدا می‌کرد چون نگاه این بود که مشکل کسِ دیگری است. این نشان از نوعی از [مشکل] فرهنگ تیمی بود که رهبر فنی روی آن تمرکز نکرده بود. این در مقابل تیمی است که به محض این‌که یک بیلد خراب شود، یک نفر به سوی آن می‌شتابد و پرچمی افراشته می‌شود که مشخص می‌کند چه کسی در حال درست کردن آن است.برای ایجاد و حمایت از این فرهنگ تیمی معمولاً چه می‌کنید؟بخش زیادی از این مسائل این است که تیم را در مقاطعی، دور هم جمع کنیم تا با هم یک‌سو شویم. به نظر من یک‌سویی خود به خود و در نتیجه‌ی کار کردن کنار یکدیگر رخ نمی‌دهد. احتمال دارد این اتفاق رخ دهد اما در بیشتر مواقع افراد پشت کامپیوترهایشان می‌مانند و در مورد مسائل بزرگ صحبت نمی‌کنند. یکی از فعالیت‌هایی که به عنوان یک رهبر فنی به آن فکر می‌کنم جمع کردن تیم توسعه در یک اتاق است. با این هدف که در مورد نگرانی‌هایی که برای همه وجود دارد صحبت کنیم و به توافق برسیم. مثلاً ممکن است افراد لاگ‌ها را در قالب‌های متفاوتی ثبت کنند. در این صورت بحث در مورد رویکردمان به لاگ است و این‌که چطور اطمینان حاصل کنیم که سطح درستی از اطلاعات را لاگ کرده‌ایم.یک راه دیگر برای یک‌سو شدن این است که یک توسعه‌دهنده، بخشی از سیستم را توضیح دهد (شاید در مورد تعامل با واسط‌های برنامه‌نویسی (API) خارجی یا سایر وابستگی‌های خارجی باشد) و سپس ببینیم آیا یک رویکرد عمومیِ سازگار در آن وجود دارد یا خیر. حتی در یک تیم هشت نفره ممکن است با سه راهبرد برای تعامل با سیستم‌های خارجی مواجه شوید و افراد می‌توانند از این یاد بگیرند.آن‌چه متوجه شدم این است که آن‌چه شما می‌گویید کمی شبیه به اجتماعات فنی (Tech Huddle) است که در آن تیم گرد هم آمده و در مورد فناوری‌ها صحبت می‌کنند. آیا منظور همین است؟بله، قطعاً. اجتماع فنی یک نام آن و یک راه برای رسیدن به آن است. برخی تیم‌ها یک بازبینی کد (Code Review) کاملاً گروهی انجام می‌دهند. شرکتی به نام Unruly در انگلیس هست که به خاطر فراتر بردن XP، (مخفف Extreme Programming) شناخته شده است. آن‌ها برنامه‌نویسی گروهی (Mob Programming) را اتخاذ کرده‌اند که در آن تمام تیم در یک زمان در حال برنامه‌نویسی است.اجازه بدهید از فرهنگ تیم به موضوع رشد توسعه‌دهنده و رشد افراد، برویم. فکر می‌کنم این به کار رهبر فنی مربوط باشد. رویکرد شما به آن چطور است؟بگذارید اول توضیح دهم چرا این مسئله مهم است. یک ضدالگو که در میان رهبران فنی تازه‌کار خیلی متداول است این است که بسیاری از شرکت‌ها بهترین توسعه‌دهندشان را در این نقش قرار می‌دهند. به نظر من لازم نیست که برای قرار گرفتن در این نقش بهترین توسعه‌دهنده باشید؛ کافی است توسعه‌دهنده‌ی خوبی باشید که همه به او احترام می‌گذارند. یکی از عواقب این‌که بهترین توسعه‌دهنده ارتقاء پیدا کند این است که می‌خواهد به نوشتن کد به بهترین شکل ادامه دهد. این منجر به ایجاد یک چرخه‌ی سیستمی بد می‌شود که او می‌خواهد تمام مسائل جالب و راه‌حل‌های سخت را به عهده بگیرد و مسائل ساده را به توسعه‌دهندگان بسپرد. اگر به سوی دیگر نگاه کنیم که شما یک توسعه‌دهنده در تیم هستید کار کردن روی مسائلی که جالب نیستند خیلی هیجان‌انگیز و الها‌م‌بخش نیست. در همین حال این رهبر فنی، درگیر جلسات و مسائل دیگری است که مسئول آن است و برایش سخت است که مانند قبل روی مسائل متمرکز شود و کارها را به همان خوبی انجام دهد. برای همین فکر می‌کنم تقویت سایر توسعه‌دهندگان مهم است. این‌که چطور توسعه‌دهندگان جدیدی را از طریق فراهم کردن فرصت‌های جدیدی که قبلاً نداشتند و حمایت کردن آن‌ها، تربیت کنید. این‌که افراد را به کار روی زمینه‌ها و فناوری‌هایی که قبلاً با آن مواجه نشده‌اند، تشویق کنید و خودتان یا شخص دیگری ایده‌پردازی کنید و رویکردهای حل مسئله را طراحی کنید.می‌شود مثالی از انجام این کار با یک شخص بزنید؟در یکی از تیم‌هایی که کار می‌کردم ما مفهوم رهبر ویژگی (Feature Lead) را مطرح کردیم. ایده، این بود که من به عنوان یک رهبر فنی بدانم در هر زمینه چه رویکردی داریم. هر توسعه‌دهنده صاحب یک ویژگی و نحوه‌ی پیاده‌سازی در آن زمینه شد. رویکرد احراز هویت یک مثال از آن است. افراد را دو به دو تقسیم کردم تا توسط یکدیگر حمایت شوند. سپس آن‌ها نیازمندی‌های مربوط به احراز هویت را کاوش می‌کردند؛ در مورد ابزارها و کتابخانه‌هایی که می‌توانیم از آن استفاده کنیم، رویکرد ما به مسئله، راه‌حل‌های بالقوه‌ و طراحی آن صحبت می‌کردند. این تا جایی پیش می‌رفت و سپس من آن را بازبینی می‌کردم تا مطمئن شوم مشکل وجود ندارد و در راستای سایر چیزها قرار دارد. پس از این‌که به راه‌حل مناسب رسیدیم، آن را با آن‌چه که به آن اجتماع فنی گفتید همراه می‌کردیم و تمام تیم را در جریان آن قرار می‌دادیم تا بدانند رویکرد کلی ما چیست.مسئله‌ی جالب این بود که برخی از مسئولان ویژگی به مراتب در اینکه راه حل را به تنهایی ارائه کنند، موفق‌تر بودند. اما در موارد دیگر افراد نیاز به زمان بیشتری داشتند و می‌گفتند حتی نمی‌دانیم از کجا شروع کنیم و ما با هم روی رویکردها و گزینه‌های متفاوتی که قابل بررسی بود، کار می‌کردیم. این کمک می‌کرد افراد رشد کنند و از راه‌هایی متفاوت به هدف برسند.راهبرد رهبر ویژگی اساساً به این معنی است که به افراد صراحتاً مسئولیت‌هایی در تیم سپرده شود و از کسانی که به تنهایی از پسِ آن بر نمی‌آیند حمایت شود.بله، دقیقاً.چطور از من حمایت می‌کنید؟ اگر من رهبر ویژگی احراز هویت باشم و ندانم چطور شروع کنم به من چه می‌گویید؟کمی در مورد آن‌چه از یک رهبر ویژگی انتظار دارم صحبت می‌کنم. این‌که اطمینان حاصل کنیم تمام نیازمندی‌های کسب و کار برآورده شده است و تمامی مخاطراتِ موارد کاربرد مربوط به احراز هویت که نیاز داریم ارزیابی می‌شود. بخشی از آن احتمالاً این است که باید با چنین افرادی صحبت کنی تا بفهمی چطور می‌خواهند با سیستم تعامل می‌کنند. سپس او به این کار می‌پردازد و سپس در مورد رویکرد فنی به این مسئله صحبت می‌کند. یک عادت خوب رهبر فنی این است که جواب کامل را بلافاصله ندهد و اجازه دهد افراد خود به آن دست یابند. من سؤالات زیادی می‌پرسم تا بفهمم افراد چه علاقه‌مندی‌هایی دارند و چه دانشی دارند. در مثالی که زدید اگر اصلاً ندانند از کجا باید شروع کرد، کمی واضح‌تر می‌گویم: «آیا OAuth و کتابخانه‌های مربوط به این زمینه را دیده‌ای؟ آیا به احراز هویت دوگانه (Two Factor Authentication) نیاز داریم؟» سپس افراد آن را بررسی کرده و راه‌حل مناسب را با توجه به پشته‌ی فناوری‌ای که داریم پیدا می‌کنند. حتی ممکن است بگویم «برو و یک Spike اجرا کن.» که یک تحقیق فنی با زمان محدود است که در آن فرد، یک نمونه‌ی اولیه‌ی کوچک ارائه می‌کند و از آن یاد می‌گیریم.وقتی من در این شرایط هستم معمولاً می‌گویم: «این‌ها عباراتی است که در گوگل جستجو می‌کنم.» شما هم این کار را می‌کنید؟بله، قطعاً این هم یک گزینه است.بسیار خوب. به رهبر ویژگی اشاره کردیم که به این معنی است که بخشی از وظایف یک رهبر فنی را به شخص دیگری می‌سپارید تا رشد کند. آیا نکته‌ای در انتخاب فرد مناسب برای این کار وجود دارد؟من مدل به طرف خود کشیدن (Pull) را ترجیح می‌دهم. من به عنوان یک رهبر فنی می‌خواهم تمام افراد از کاری که می‌کنند حمایت کنند، چون افرادی می‌خواهم که به موضوع اهمیت دهند. در بسیاری از موارد سعی می‌کنم افراد را صراحتاً انتخاب نکنم و افرادی را بیابم که بخواهند در آن زمینه کار کنند. بخشی از کار که یک مهارت ارتباطی است، این است که افراد را با جذابیت‌های زمینه‌های مختلف به هیجان بیاوریم. گاهی اوقات در مورد اشکالات در سیستم‌های مختلف صحبت می‌کنید، یا این‌که کار باید ادامه پیدا کند اما برخی از مشکلات هم باید برطرف شوند و فرصت‌های دیگری هم هستند. من ترجیح می‌دهم بگویم:‌ «باید به مدیریت فعالیت نگاهی کنیم و باید راهی برای یکپارچه‌سازی راه‌حل فنی با نحوه‌ی اجرای فعالیت‌های مربوط به محصول، پیدا کنیم. یک نفر می‌خواهیم که راه‌حل فنی و رویکرد کلی به این مسئله را پیدا کند... این‌ها هم فرصت‌های جذاب و افرادی هستند که با آن‌ها کار خواهید کرد که معمولاً پیش نمی‌آید.» سپس به دنبال داوطلب می‌گردم. گاهی اوقات ممکن است داوطلب وجود نداشته باشد و مجبور هستید که انتخاب کنید. بخشی از این کار بر عهده‌ی شما به عنوان یک رهبر است که برای توسعه‌دهندگان، اعتماد سازی کنید.آیا تا به حال در شرایطی بوده‌اید که یک نفر، زیادی داوطلب شود؟بله، قطعاً. معمولاً این را صراحتاً می‌گویم. بخشی از کار من به عنوان یک رهبر فنی، که تلاش می‌کند از موفقیت افراد حمایت کند، این هم هست که مراقب باشم افراد چه مقدار کار بر می‌دارند و آن را مدیریت کنم. در یکی از تیم‌هایی که در آن کار می‌کردم یک قانون راهنما داشتیم «صرفاً به این دلیل که کار زیاد است، نباید کسی روی بیش از دو ویژگی کار کند.»در آموزش‌ها هم به خاطر دارم که شما در فهمیدن این‌که افراد در چه زمینه‌هایی می‌خواهند کار کنند، خیلی سنجیده عمل می‌کنید. می‌شود کمی در این مورد توضیح دهید؟این مربوط به شناخت افراد است. ابزاری که می‌توانید از آن استفاده کنید گفتگوهای دو نفره است. از افراد بپرسید به چه چیزی علاقه‌مند هستند؟ چه کار می‌خواهند انجام دهند؟ وقتی این را از افراد بپرسید، بسیاری از افراد معمولاً جوابی ندارند چون در واقع به آن فکر نمی‌کنند. برخی هم اهداف واضحی دارند. بنابراین بخشی از آن این است که بفهمید افراد به چه علاقه‌مند هستند، اهداف واقعی آن‌ها چیست و به کدام سو می‌روند. من به عنوان یک رهبر فنی به دنبال این هستم که در محیطی که در آن هستیم کارهای در دسترسِ قابل انجام را با فرصت‌هایی که افراد دوست دارند و شاید هنوز نمی‌دانند، همسو کنم. برای مثال، توسعه‌دهندگانی داشته‌ام که می‌خواستند وارد فضای ذهنی توسعه-عملیات (DevOps) و کار با زیرساخت شوند و روی خودکارسازی، با مثلاً Puppet یا Chef و چنین چیزهایی کار کنند. در حالی که سایر توسعه‌دهندگان اصلاً نمی‌خواستند با آن سر و کار داشته باشند. بیشتر می‌خواستند بر جلوی‌کار (Frontend) و واسط کاربری متمرکز باشند. یا گروه دیگری که نمی‌خواهند حتی به واسط کاربری نگاه کنند :-) و می‌خواهند در توسعه‌ی سرویس‌های سرسخت پشتِ‌کار (Backend) و واسط‌های برنامه‌نویسی، رشد کنند. اگر از افراد نپرسید این‌ها را نخواهید فهمید. این‌جاست که صَرف وقت برای هر توسعه‌دهنده مفید است. شاید حتی به صورت گروهی هم بتوانید آن را انجام دهید.باز هم موضوع را کمی عوض کنیم. در ابتدا اشاره کردید که به عنوان یک رهبر فنی باید خودتان هم کد بنویسید. چرا؟فکر می‌کنم یک مسئله‌ی کلیدی است. برای من به این معنی است که بتوانید کد سیستم را بنویسید. مقاله‌ای در ComputerWorld یا InfoWorld هم هست که به آن ارجاع می‌کنم. نویسنده در آن در مورد این صحبت می‌کند که توسعه‌دهندگان به این خاطر به سایر توسعه‌دهندگان احترام می‌گذارند که کدِ آن‌ها را می‌بینند. یک مثال از اوایل فعالیت حرفه‌ایم دارم. در شرکتی کار می‌کردم که چند مدیر فنی داشت. یکی از مدیران فنی می‌خواست در ارتباط با اتمام یک ابزار جلسه داشته باشیم که در آن زمان سیستم کنترل نسخه‌ها (CVS) را به سیستم داخلی کنترل کدهای منبع‌شان (Source Control) متصل می‌کرد. این ابزار وابستگی‌هایی به Perl و ... داشت و ساعات آخر روز جمعه بود. مدیر آمد و گفت «خیلی مهم است که این کار قبل از پایان روز به اتمام برسد.» صحبت از ساعت ۳ بعد از ظهر روز جمعه است :-) و من تقریباً مطمئن هستم که نمی‌توانیم آن را تمام کنیم. گفتم بیایید بنشینیم و با هم روی آن کار کنیم و کیبورد را به مدیر فنی دادم. چهره‌اش طوری بود که می‌گفت چه کنم؟ برای من واضح بود که او نمی‌تواند کد Perl بنویسد و نمی‌دانستم با کنار من نشستن می‌خواست به چه چیزی دست یابد. من در ابتدای فعالیت حرفه‌ایم متوجه شدم که «بسیار خوب، این فرد را در زمره‌ی افراد غیر فنی قرار می‌دهم» و در این نقطه، دیدگاه‌تان تغییر خواهد کرد.اگر توسعه‌دهندگان در نوشتنِ کدِ سیستم برای شما احترامی قائل نباشند، زمانی که می‌خواهید در تصمیم‌گیری گروهی درباره‌ی مسیری متفاوت، به آن‌ها کمک کنید، احتمالاً تصمیم‌های اشتباهی خواهید گرفت. همچنین توسعه‌دهندگان احتمالاً از آن حمایت نخواهند کرد. برای من واقعاً اهمیت دارد که رهبر فنی بداند در کد چه خبر است. احتمالاً بیش‌تر به خواندن کد عادت خواهید کرد تا نوشتن آن. با این‌حال فکر می‌کنم این‌که رهبر فنی بتواند در سیستم مشارکت داشته باشد، اهمیت دارد. این‌که بداند برای فلان زمینه به کجا برود و چطور ویژگی‌های جدید را اضافه کند و تست‌ها کجا هستند و ... چون این مسئله در حفظ درک متقابل خیلی اهمیت دارد. در آگاهی از معماری فنی کلی و مخاطرات هم همین‌طور.بنابراین برای این‌که احترام توسعه‌دهندگان را به همراه داشته باشم و بتوانم رهبر فنی موفقی باشم، باید کد بزنم. جنبه‌ی دومی که به آن اشاره کردید این است که رهبر فنی باید بداند در کد چه خبر است.بله، قطعاً. زیاد می‌بینم که رهبران فنی، به ویژه آن‌هایی که بی‌مقدمه در این نقش قرار گرفته‌اند، به تیم اعتماد می‌کنند. وقتی شش ماه بعد به سراغ کد می‌روند می‌گویند: «چرا کلاس‌های ما سیصد خط هستند؟ تست‌ها کجا هستند؟» و به دنبال تمامی انتظاراتشان از کد خوب می‌گردند که در واقع محقق نشده‌اند،‌ چون تیم این تصمیم‌ها را گرفته است. این برای من به منزله‌ی مدیریت مخاطرات فنی (Technical Risk Management) است. یعنی خیلی خوب است که به توسعه‌دهندگان اعتماد کنید و بخواهید به آن‌ها این حد از آزادی و درک را بدهید. اما در عین حال به یک حلقه‌ی بازخورد نیاز دارید تا آن‌چه که فکر می‌کنید در حال رخ دادن است محقق شود. این برای من یک مسئله‌ی کلیدی است. به عنوان یک رهبر فنی باید بدانید وضعیت فعلی سیستم چیست تا بتوانید موازنه برقرار کنید. موازنه‌ای میان سرعت اضافه کردن ویژگی‌ها و یا بازطراحی و رویکردهای معماری در یک بخش سیستم.وقتی به عنوان یک رهبر فنی کد می‌نویسید، آیا دو نفری (Pair) کد می‌زنید و یا به تنهایی و یا به شکل دیگری است؟سؤال خوبی است. به شدت توصیه می‌کنم که از تبدیل شدن به یک تکاورِ تنها که روی ویژگی‌های بحرانی و حساس به زمان کار می‌کند، خودداری کنید. چون تبدیل به مسدودکننده کار می‌شوید. فکر می‌کنم یکی از دشواری‌هایی که بعداً در مورد آن صحبت خواهیم کرد مربوط به مدیریت زمان است. یعنی نمی‌توانید مداوم روی یک چیز کار کنید و باید از کار کردن روی چیزهایی که در مسیر بحرانی قرار دارند پرهیز کنید. به نظرم دو نفری کار کردن راه خیلی خوبی است. وقتی برای [پیاده‌سازی] یک ویژگی یا یک داستان (Story) گرد هم می‌آییم، در مورد رویکرد کلی و کاری که باید انجام دهیم صحبت می‌کنیم. صراحتاً در مورد کارهایی که می‌خواهیم انجام دهیم حرف می‌زنیم تا اگر من مجبور به ترک کار شدم یا باید به جلسه می‌رفتم آن شخص بتواند کار را ادامه دهد و امیدوار باشم تا وقتی برمی‌گردم کار از مسیر خارج نشده یا حداقل می‌شود درباره‌ی آن صحبت کرد. این کار، یکی دو مزیت دارد. شخصی که با او کار می‌کنید اطلاعاتی از یک دیدگاه دیگر دریافت می‌کند. شما هم نقطه‌ی تماسی با آن ویژگی پیدا می‌کنید و می‌فهمید در کد چه خبر است.بنابراین وقتی دونفری کار می‌کنید مسیر پیاده‌سازی را طراحی می‌کنید تا در صورتی که لازم شد به جلسه بروید شخص دیگر بتواند به تنهایی کار را ادامه دهد؟بله. می‌خواهم یک ضدالگوی دیگر را مطرح کنم چون فکر می‌کنم خیلی حساس است. این مسئله در همان پروژه‌ای اتفاق افتاد که در آن توسعه‌دهنده بودم و بعد از آن رهبر فنی شدم. رهبر فنی ما در آن زمان در برخورد با چیزهایی که دوست نداشت، سبک خاصی داشت. وقتی ما توسعه‌دهندگان شب به خانه می‌رفتیم او به شکلی جادویی در نیمه‌ی شب همه چیز را بازسازی (refactor) می‌کرد و آن را در مخزن کد قرار می‌داد. وقتی ما صبح سر کار بر می‌گشتیم، می‌گفتیم چرا همه چیز بازنویسی شده است؟ گفتگویی در مورد این‌که چرا این کار انجام شده بود و یا این‌که آیا بهتر است یا نه وجود نداشت. نگه‌داری آن برای ما سخت و گیج‌کننده بود. این باعث به وجود آمدن حس تضعیف شده بود. می‌خواهم این موضوع را به عنوان یک ضد الگوی مهم رهبری فنی مطرح کنم. این‌که کد افراد را از نو بنویسید چون با آن مخالفید.این ما را به موضوع دیگری هدایت می‌کند. وقتی توسعه‌دهنده هستید، همکاران‌تان در کنارتان هستند. اما در شرایطی که توسعه‌دهنده و رهبر فنی وجود دارند، آن‌طور که توضیح دادید این یک نقش منفرد است. یک رهبر فنی تا چه حد عضوی از تیم است و تا چه حد از تیم توسعه متفاوت است؟به نظر من رهبر فنی عضوی از تیم است. برخی از مسئولیت‌ها و دیدگاه‌ها این حس را به وجود می‌آورد که میان دو دنیا در تقلا هستید. بخشی از آن کار کردن با تیم و کد زدن است. اما در عین حال به سمت چیزهای دیگری کشیده می‌شوید. شاید کسب و کار نیز ویژگی جدیدی دارد و شما تحت فشار تحویل چیزهای جدید هستید. شاید یک توسعه‌دهنده با موضوع حساسی که نگرانش کرده نزد شما می‌آید که به خاطر شخصی بودن موضوع، نمی‌شود آن را با سایرین مطرح کرد. این جایی است که خود را هم داخل تیم و هم خارج از آن احساس می‌کنید. به عنوان یک توسعه‌دهنده که در این نقش قرار گرفته، این می‌تواند خیلی دشوار باشد. نقش‌های دیگری هم در تیم توسعه هستند که منحصر به فردتر هستند. مثلاً شاید یک آزمون‌گر (Tester) یا یک مدیر پروژه داشته باشید. اما یک توسعه‌دهنده معمولاً در کنار توسعه‌دهندگان دیگر قرار دارد. وقتی در نقش رهبری فنی قرار می‌گیرید هم حس می‌کنید جزئی از تیم هستند و هم حس می‌کنید خارج از آن هستید. این تنهایی می‌تواند خیلی آزاردهنده باشد.فارغ از این تنهایی، تبدیل شدن به یک رهبر فنی به چه معناست؟برخی از این‌ها را از راه سخت‌اش یاد گرفتم :-) این‌که می‌توانید خودتان با مشکلات روبرو شوید. دلیلی داشته که شما در این نقش قرار گرفته‌اید، بنابراین شایستگی انجام آن را دارید. اما مهم است که شبکه‌ی حمایتی خود را بسازید. یعنی در برخی موضوع‌ها بهتر است با افراد دیگری که به محیط فعلی شما ارتباطی ندارند، صحبت کنید. این چیزی است که در کلاس‌هایی که ارائه می‌دهم زیاد درباره‌اش صحبت می‌کنم؛ ساختن شبکه‌ی حمایتی. در برخی سازمان‌ها ممکن است خوش‌شانس باشید و با رهبران فنی تیم‌های دیگر کار کنید. یا ممکن است رهبران فنی زیادی در یک طبقه داشته باشید. در این‌صورت این مزیت را دارید که چیزی مثل آن‌چه ما به آن «نهار رهبران فنی» می‌گفتیم را هماهنگ کنید. جلساتی که در آن رهبران فنی را جمع کرده و در مورد مسائلی صحبت کنید که صحبت کردن در مورد آن‌ها با تیم‌تان سخت است. ممکن است مربوط به مدیریت وقت و تقویم و کنار آمدن با برگشتن به کد زدن باشد. شاید مربوط به بهترین راهِ حل و فصلِ مناقشات در تیم باشد. یا مثلاً اینکه سایر تیم‌ها چه ابزارها و فناوری‌های استفاده می‌کنند که ما حتی از آن خبر نداریم چون در تیم ما کسی از آن خبر ندارد. چیزهایی که بازخورد گرفتن در مورد آن در تیم سخت است. به این نوع از پشتیبانی احتیاج دارید.یک بار در جلسه‌ای بودم، [پرسیدم] کدام یک از شما مدیر، کدام توسعه‌دهنده و کدام‌یک معمار است؟ او گفت مدیر کسی است که سرش مدام در ایمیل است. توسعه‌دهنده مدام در IDE و معمار در PowerPoint است :-) و من گفتم رهبر فنی همیشه سرش در تقویم‌اش است :-)در این نهارها در این مورد هم صحبت می‌کنید؟ می‌توانید صحبت‌هایی که در این جلسات اتفاق می‌‌افتاد را به اشتراک بگذارید؟بله. Thoughtworks یک شرکت مشاوره‌ای است و با مشتریان متفاوتی کار می‌کند. اما من این شانس را داشتم که نزدیک به تیم‌هایی باشم که با مشتریانی کار می‌کردند که در همسایگی ما هستند. وقت نهار گرد هم می‌آمدیم چون این راحت‌ترین راه بود که در جایی خنثی کنار هم باشیم. سپس روی یکی از موضوعات روز تمرکز می‌کردیم. لیستی از موضوعاتی که می‌خواستیم درباره‌ی آن صحبت کنیم داشتیم. یکی از این موضوعات مدیریت زمان بود: «چطور خود را از جلسات رها کنید؟» موضوع دیگر هم بود که درباره‌ی نحوه‌ی تعامل با مشکلات توسعه‌دهندگان بود. مثلاً شاید توسعه‌دهنده‌ای باشد که با سایر اعضای تیم وفق نمی‌شود. دیگران چه راهبردهایی در کمک به برطرف کردن این مسئله استفاده می‌کنند؟ این به یک‌سو کردن راهبردها در این نوع مسائل کمک می‌کند. گاهی اوقات صحبت از مسائل فنی بود. مثلاً بازبینی معماری‌مان و این‌که آیا مناسب است یا این‌که شما رویکردی دیگری به آن می‌داشتید؟ تلاش می‌کردیم روی چیزهایی که خیلی مربوط به توسعه‌دهنده هستند، تمرکز نکنیم. چون در این مسائل می‌توانید با تیم‌تان صحبت کنید: «الگوی طراحی درست برای این ویژگی چیست؟ و ...» بیشتر روی مسائلی تمرکز می‌کردیم که فکر می‌کردیم مناسبِ همکارانِ در آن سطح بود.به نظر می‌رسد ایجاد شبکه‌ی حمایتی راهبرد خوبی باشد. بیایید به فرایندِ تبدیل شدن به رهبر فنی نگاه کنیم. وقتی که از تعطیلات بر می‌گشتید در فرودگاه با شما تماس گرفتند و با این یک تماس شما از یک توسعه‌دهنده به یک رهبر فنی تبدیل شدید. آیا در این مسیر قدم برمی‌داشتید یا اتفاقی بود؟فکر می‌کنم «بر سرم آمد» بهترین راه توصیف آن باشد. من راهی جز صحبت کردن با دیگران برای یافتن حمایت و پشتیبانی نداشتم. خوش‌حالم که افرادی بودند که با آن‌ها صحبت کنم اما اگر می‌دانستم مسئولیت‌هایم چه هستند و چطور باید آن را انجام دهم، خیلی بهتر بود.بعد از این تجربه به دنبال کتاب‌هایی در این موضوع گشتم. قدیمی‌ترین کتابی که پیدا کردم «رهبر فنی شدن» (Becoming Technical Leader) نوشته‌ی جرالد واینبرگ بود. کتاب خیلی خوبی بود و ابزارهای خوبی در اختیار قرار می‌دهد اما فکر می‌کنم به درد هر کسی در هر محیط فنی بخورد و خاص رهبران فنی نیست. در کمک کردن به افراد برای این‌که معنی رهبر فنی موفق را درک کنند، یک جای خالی را حس می‌کردم. این یکی از دلایلی بود که نوشتن کتابم را شروع کردم که مجموعه‌ای از مصاحبه‌هاست با عنوان «گفتگو با رهبران فنی» (Talking with Tech Leads).بعداً کمی در مورد کتاب صحبت می‌کنیم. کنجکاوم بدانم که وقتی به طرز ناگهانی در نقش دیگری شروع به کار می‌کنید،‌ متوجه چه چیزهایی می‌شوید؟ وقتی به رهبر فنی تبدیل می‌شوید چه چیزهایی تفاوت می‌کنند؟ این‌طور نیست که یک روزه آدم دیگری بشوید؟نه :-) فکر می‌کنم بخشی از دشواری این است که اولاً وقتی کسی این نقش را به شما می‌دهد، عدم قطعیت وجود دارد. اغلب میزان زیادی اضطراب دارید: «آیا کارم را به درستی انجام می‌دهم؟» خیلی دشوار است که فهرستی از مسئولیت‌ها یا زمینه‌هایی که باید بر آن تمرکز کنید، تهیه کرد. من از چیزهایی که نمی‌دانستم، آگاهی نداشتم و می‌دانستم که احتمالاً چیزهایی هستند که باید به دنبال آن باشم اما درباره‌شان نمی‌دانم. سعی می‌کردم با افراد درباره‌ی کارهایی که انجام نمی‌دهم ولی باید انجام دهم، صحبت کنم. در عین حال تلاش کردم به خودم بفهمانم: من از سطح مهارت‌های توسعه‌ی خودم راضی‌ام اما قطعاً مهارت‌های رهبری هم هست که در عنوان این نقش هست. این‌ها به چه معنی است؟ کجا می‌توانم آن‌ها را بهبود بخشم؟ درک نحوه ی ارتباط کارآمد، خصوصاً با ذی‌نفعان غیرفنی و فنی. چطور به مناقشات رسیدگی کنم؟ چطور بدون نوشتن کد، روی افراد تأثیر بگذرام؟ این مسائل مربوط به معماری رهبر فنی چه هستند؟ و تلاش کنم در این زمینه‌ها مهارت پیدا کنم.آیا توسعه‌دهندگان تیم شما کاری انجام دادند که در این فرایند جابجایی به شما کمک کند؟ آیا به طور عمومی، توسعه‌دهندگان می‌توانند کاری در در حمایت از یک رهبر فنی تازه‌کار انجام دهند؟بله. اگر به چند تا از تیم‌های قبلی‌ام فکر کنم، دریافت بازخورد از چند منبع به من کمک کرد. یکی از ابزارهای مورد علاقه‌ی من برای این‌کار، چرخه‌ی بازخورد ۳۶۰ درجه است، که در جلسات دو نفره یا سایر جلسات از آن استفاده می‌کردم. گاهی اوقات می‌توانیم کنار هم بنشینیم. دیده‌ام که سایر رهبران فنی فکر می‌کنند که کارشان عالی است، اما توسعه‌دهندگان نظر متفاوتی دارند. فکر می‌کنم یک رهبر فنی باید خود را مجبور به دریافت بازخورد از منظر توسعه‌دهندگان کند. اگر اعتمادسازی نکرده باشید، کار سختی است اما فکر می‌کنم واقعاً امر مهمی است و اگر این رفتار را با تیم‌تان داشته باشید اعتماد،‌ عمیق‌تر می‌شود.اگر بتوانید این سؤالات را مطرح کنید «من به عنوان یک رهبر فنی چه می‌کنم و تو چه انتظاراتی داری؟ آیا من آن‌ها را برآورده می‌کنم؟ فکر می‌کنی در کدام زمینه ضعیف‌تر هستم یا می‌توانم بهبود پیدا کنم؟ در کدام زمینه کارم را خوب انجام می‌دهم؟» در اینصورت دیدگاه بهتری نسبت به آن خواهید داشت و می‌توانید آن را در سطح تیم بررسی کنید.بنابراین بازخورد گرفتن ابزار مهمی است. اگر مایل هستید بگویید خود شما چه بازخوردهایی دریافت کردید؟بازخوردی که من از تیمم دریافت کردم -که یک مسئله‌ی شخصی است- این بود که وقتی زیاد بین مسائل جابجا می‌شوم چون وظیفه‌گرا هستم، خیلی آمرانه برخورد می‌کنم. بازخوردی که گرفتم این بود که خصوصاً وقتی مضطرب هستم، به افراد برای صحبت کردن در مورد مسائل و مشکلات فرصت کافی نمی‌دهم و فقط روی این‌که «چطور آن را برطرف کنیم» تمرکز می‌کنم. این برای من یک نقطه‌ی عطف بود. چون اولاً وقتی مضطرب هستید نمی‌دانید چقدر روی رفتار شما تأثیر گذار است و هر کدام از ما به شکل متفاوتی با آن برخورد می‌کنیم. به علاوه، این به من کمک کرد بفهمم که تیم چه مشکلی دارد و روی سازوکاری برای کنار آمدن با اضطراب و جابجا شدن بین مسائل توافق کنیم. یعنی زمان‌هایی برای تمرکز بیشتر داشته باشم و در سایر اوقات افراد بتوانند به من مراجعه کنند.همچنین این مسئله به من کمک کرد بفهمم وقتی مضطرب هستم چطور با افراد رفتار می‌کنم. تلاش کردم به جای این‌که به سرعت به سمت یک راه‌حل خاص بروم به افراد زمان بیشتری بدهم تا با شرایط آشنا شوند.بسیار خوب. بگذارید وارد جمع‌بندی شویم. یک سؤال آزاردهنده در مورد کسانی که برای اولین بار رهبری فنی را تجربه می‌کنند، باقی‌مانده است. آن سؤال این است که از کجا بدانم رهبری فنی‌ام خوب است؟این سؤال خیلی خوبی است :) واقعاً تا به حال به آن فکر نکرده‌ام. هر کس سبک رهبری فنی خودش را دارد. آن‌چه به نظر من خوب است این است که باید رویکردتان به مسائل را درک کنید و بشناسید. یک نشانه از کارامدی رهبر فنی این است که هر روز به او نیاز ندارید. اگر رهبری فنی مدام درگیر جلسات و جواب دادن به همه‌ی مسائل است، احتمالاً رهبر فنی کارآمدی نیست. به یکی از اولین سؤالات شما برگردیم «اصلاً چرا به رهبر فنی احتیاج داریم؟» اگر رهبر فنی کارآمدی باشید، به نقش توسعه‌دهنده برمی‌گردید و هنوز می‌توانید روی تصویر کلی تمرکز داشته باشید و مراقب ناهمسویی‌ها باشید. اگر کارتان را به خوبی انجام دهید، تیم باید [با تصویر کلی] همسو باشد و نباید مناقشات زیادی وجود داشته باشد، یا اگر هم هست خودشان باید بتوانند آن را برطرف کنند و این توافق عمومی باید وجود داشته باشد.بسیار خوب. شما کتابی با عنوان «گفتگو با رهبران فنی» (Talking with Tech Leads) نوشته‌اید. در این کتاب با تعداد زیادی از رهبران فنی مصاحبه کرده‌اید و سؤالاتی یکسان را از آن‌ها پرسیده‌اید. در این کتاب چند دیدگاه در مورد نحوه‌ی رهبری فنی وجود دارد. آن‌چه من درباره‌ی این کتاب دوست دارم این است که نشان می‌دهد هر رهبر فنی سبک خاص خودش را دارد. حین انجام دادن این مصاحبه‌ها چه یاد گرفتید؟اول آن چیزی که شما هم به آن اشاره کردید. این‌که رویکردهای متفاوتی برای انجام این کار هست که همه‌ی آن‌ها درست‌اند. وقتی وارد این نقش می‌شوید از خود می‌پرسید:‌‌ «آیا کار درستی انجام می‌دهم؟» شما سبک خود را دارید و صرفاً به این دلیل که یک رهبر فنی در تیم دیگری رویکرد متفاوتی دارد به این معنی نیست که کار شما اشتباه است.ابزارها و رویکردهای متفاوتی وجود داشت که افراد از آن استفاده می‌کردند. یکی از بزرگ‌ترین درس‌هایی که گرفتم این بود که وقتی در نقش رهبر فنی هستم زمان کافی برای خودم صرف نمی‌کنم. این یک مشاهده‌ی جالب از جان پیتر در کتاب بود. او تمرکز زیادی بر تعمق (Meditation) و حضور در لحظه داشت تا اطمینان حاصل کند زمان کافی برای کاری که انجام می‌دهد را دارد و زمانش را اولویت‌بندی کند. این یکی از بزرگ‌ترین درس‌هایی بود که از این کتاب گرفتم. این‌که برای خودتان زمان کافی صرف کنید.با چند رهبر فنی صحبت کردید؟فکر می‌کنم در نهایت با ۳۷ نفر صحبت کردم. چند نفر دیگر هم بودند اما خواستم [مطلب] عمق بیشتری داشته باشد. همچنین تلاش کردم رهبران فنی خانم را پیدا کنم. این جالب بود، چون ما به عنوان یک صنعت در جذب توسعه‌دهندگان خانم مشکل داریم و وارد کردن رهبران فنی خانم در کتاب برای من یک هدف شخصی بود. کمک خواستن از شبکه‌ی افرادی که می‌شناختم برای اینکه در این مورد با چه کسی صحبت کنم، برایم جالب بود.رهبران فنی در مورد چه چیزی حرف می‌زدند؟ موضوعات اصلی چه بودند؟کتاب به دو بخش تقسیم می‌شود. یک بخش روی تازه‌کارها تمرکز دارد و بخش دیگری که افراد باتجربه‌تری در آن هستند و گاهاً به آن‌ها متخصص گفته می‌شود. جالب بود که برای تازه‌کارها اشتراک زیادی در زمینه‌ی شوکه شدن وجود داشت. اینکه: «من یک توسعه‌دهنده بوده‌ام و الان در نقش رهبر فنی هستم. این به چه معنی است؟» این برای من جالب بود که همه، مشکلات مشابهی داشتند چون امیدوارم این به افراد کمک کند که بدانند اگر برای نخستین بار به این نقش وارد می‌شوند، این مسئله عادی است.در بخش دوم کتاب، موضوعات دیگری مطرح شدند. یکی مسئله، مدیریت خودتان بود که یک موضوع کامل بود. این موضوع بر اولویت‌بندی زمان و اطمینان حاصل کردن از این‌که آیا زمان‌تان را به کارآمدترین شکل صرف می‌کنید، تمرکز می‌کرد: این‌که ایرادی ندارد زمانی را صرف این کنید که زمان‌تان را صرف چه کاری کنید. فکر می‌کنم این مسئله‌ی مهمی است.بخش دیگری در مورد افراد وجود دارد. فکر می‌کنم پیشرفت در این بخش برای توسعه‌دهندگان دشوارتر باشد. فکر می‌کنم توسعه‌دهندگان به صورت طبیعی به سوی افکار فنی و معماری کشیده می‌شوند که مربوط به بخش فنیِ رهبری فنی است. اما درک سروکار داشتن با شرایطِ دشوارِ مربوط به افراد مسئله‌ای است که به عنوان یک توسعه‌دهنده خیلی به آن نمی‌پردازید. تجربه‌ای ندارید که از آن شروع کنید و زمانی که به این نقش وارد می‌شوید به آن نیاز دارید.بخش آخر مربوط به ارتباط برقرار کردن میان بخش فنی و کسب و کار است. خیلی در مورد آن صحبت نکردیم چون از لحاظ معماری و فنی خیلی مسئله‌ی داخلی‌ای است. نقش رهبر فنی در بسیاری از سازمان‌ها مربوط به ارتباط برقرار کردن با کسب و کار است: تلاش برای این‌که آن‌چه تیم فنی تحویل می‌دهد، ارزش کسب و کار ایجاد کند، به کسب و کار کمک کند معنی اصطلاحات فنی و معماری را بفهمد و پیامدهای هر تصمیم را بداند. این‌که کسب و کار بداند هر تصمیم، فرصت‌های کسب و کار را چطور تحت تأثیر قرار می‌دهد.این آخرین سؤال من بود. الان فرصت دارید که به هر سؤالی که باید می‌پرسیدم جواب دهید. آیا می‌خواهید چیزی بگویید؟ شاید آخرین دُرهای حکمت؟امیدوارم حیطه‌ی وظایف رهبر فنی در نتیجه‌ی برخی کارهایی که انجام داده‌ام، کمی روشن‌تر شده باشد. امیدوارم به افراد کمک کرده باشد که بفهمند مجموعه‌ای از مهارت‌ها و زمینه‌های متفاوت است. پس از آن می‌توان راهی برای تمرین در هر یک از این مهارت‌ها پیدا کرد تا آن را بهبود داد. قطعاً خواهم گفت که شبکه‌ی پشتیبانی خود را بسازید. این یک مسئله‌ی کلیدی است. رهبر فنی بودن نباید یک مسئله‌ی خجالت‌آور باشد. برخی افراد فکر می‌کنند این به معنی گذر کردن از کار فنی است، در حالی‌که به معنی تأثیرگذاری مثبت است. گاهی اوقات به عنوان یک توسعه‌دهنده از محیطی که در آن هستید خسته می‌شوید اما به عنوان یک رهبر فنی شما این محیط را شکل می‌دهید. این یک فرصت جذاب است.خیلی متشکرم. افراد چطور درباره‌ی این موضوع بیشتر اطلاعات کسب کنند؟ واضح است که می‌توانند کتاب را بخرند و بخوانند.من زیاد در مورد این موضوعات مربوط به رهبری فنی، بلاگ می‌نویسم. آدرس آن www.patkua.com است. در توئیتر هم خیلی فعال هستم و خیلی دوست دارم سؤالات، معماها و افکار شما در مورد رهبر فنی را بشنوم. من فکر می‌کنم از صحبت کردن با افراد و مشکلاتی که دارند خیلی یاد می‌گیرم و دوست دارم تجربه‌هایم را به اشتراک بگذارم. آدرس توئیتر من patkua@ است. سایت کتاب هم هست که می‌توانید آن را در leanpub پیدا کنید.پاتریک، بابت این مصاحبه خیلی از شما متشکرم. فکر می‌کنم خیلی جالب بود.متشکرم که من را دعوت کردید. سؤالات خوبی داشتید و من از بحث لذت بردم.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>سید مرتضی هاشمی</author>
                <pubDate>Sat, 09 Jul 2022 19:33:13 +0430</pubDate>
            </item>
                    <item>
                <title>استخدام در صنعت نرم‌افزار</title>
                <link>https://virgool.io/se-radio/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%AF%D8%B1-%D8%B5%D9%86%D8%B9%D8%AA-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-afos11wy511f</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۲۰۸ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت، توبیاس کاتز با رندی شاپ، CTO سابق شرکت کیکسای در مورد استخدام در صنعت نرم‌افزار صحبت می‌کند. رندی تجربه کار در شرکت‌های بزرگی از جمله اوراکل، eBay و گوگل را دارد. پیش از کیکسای، رندی در گوگل به‌عنوان مدیر مهندسی برای پروژه موتور برنامه‌های گوگل (Google app engine) و به‌عنوان مدیر ارشد و معمار برجسته در eBay کار کرده است. رندی در موارد متعددی درباره چگونگی استخدام افراد عالی برای تیم‌های با کارایی بالا و تجربه خودش دراین‌باره صحبت کرده است. در این مصاحبه، رندی در این مورد  صحبت می‌کند که: چطور شرکت‌ها می‌توانند کاندیدهای درست را پیدا کنند، چطور کاندید‌ها می‌توانند توجه شرکت‌هایی که می‌خواهند با آن‌‌ها کار کنند را جلب کنند و مصاحبه‌ها و شبکه‌های اجتماعی چطور می‌توانند در این فرآیند کمک کنند. او و توبیاس درباره ایده همواره استخدام کردن «بازیگران سطح A» و تأثیر آن بر روی تیم‌ها و تأثیر آن بر افرادی صحبت می‌کند که در چنین محیطی هستند که تنها «بازیگران سطح A» استخدام می‌شوند.  به‌علاوه، آن‌ها درباره «روش گوگل در استخدام» صحبت می‌کنند و اینکه چطور بگذاریم کاندیدها حتی اگر در نوبت اول، رَد شده‌اند برای مصاحبه دوم بیایند.سلام رندی، به رادیو مهندسی نرم‌افزار خوش آمدی. دفعه قبل که با تو مصاحبه کردیم (قسمت ۱۰۹) در مورد معماری نرم‌افزار در eBay صحبت کردی اما الان در صنعت بازی‌سازی کار می‌کنی. چطور شد؟این جابجایی مفرحی بود. من در eBay به‌عنوان مدیر ارشد برای ۶ سال و نیم کار کردم و همان طور که گفتی در قسمت ۱۰۹ در مورد تجربه‌هایی که در آنجا داشتم صحبت کردم. بعد از آن یک استارتاپ کوچک برای خودم راه انداختم. از درآمدش نتوانستم جزیره اختصاصی برای خودم بخرم اما در نهایت چیزهای خیلی زیادی آموختم. بعد از آن در گوگل به‌عنوان مدیر فنی پروژه موتور برنامه‌های گوگل (Google app engine) کار کردم که یک سکو به‌عنوان سرویس (platform as a service) بود که ۳ میلیون برنامه مختلف بر روی آن پلتفرم اجرا می‌شدند اما در سال گذشته به‌عنوان مدیر ارشد فنی یک شرکت بازی‌سازی در سانفرانسیسکو با نام کیکسای کار کرده‌ام. این جابجایی، یک جابجایی جذاب بود. به من در گوگل و eBay خیلی خوش گذشت و چیزهای زیادی در مورد ساختن سیستم‌های خیلی بزرگ و بزرگ کردن مقیاس سازمان آموختم. یکی از کارهایی که در کیکسای در حال انجام است همین بزرگ شدن است و به همین دلیل آن‌ها به کسی که تجربه چنین کارهایی را داشته باشد علاقه نشان می‌دهند که هم در مورد بزرگ کردن مقیاس زیرساخت‌ها برای پشتیبانی از ده‌ها بلکه صدها میلیون کاربر تجربه داشته باشد و هم بداند چطور می‌توان مقیاس سازمان را برای پشتیبانی از این حجم عظیم، بزرگ کرد. من از زمانی که در کیکسای گذرانده‌ام لذت برده‌ام. صنعت بازی‌سازی به شدت با هیجان، مفرح و دوست‌داشتنی است. آنچه من می‌توانستم [برایشان] بیاورم، زیرساخت‌های برای مقیاس‌های بالای اینترنتی و رهیافت‌های eBay و گوگل برای کارهای سمت سرور (server-side) بود که بیشتر کارهایم در آن ارتباط بوده است و آنچه می‌آموختم نیمه دیگر بازی‌سازی بود که خیلی جذاب بود یعنی مباحث مربوط به گرافیک، بازی کردن، موتورهای بازی‌سازی، شبیه‌سازی و خیلی جنبه‌های دیگر علوم کامپیوتر که در ۲۰ سال گذشته هیچ‌گاه با آن تماس نداشتم. برایم خیلی مفرح بود.خیلی خوبه. اما فکر کنم هنوز گام‌های زیادی در پیش داشته باشید.بله، همان طور که گفتم من این فرصت را دارم که در زمینه تکنیک‌های سمت سرور مربوط به مقیاس‌های بالا که در گوگل و eBay آموخته‌‌ام به آن‌ها کمک کنم و آن‌ها را در حوزه کاملاً جدیدی بکار بگیریم. کیکسای هم بر روی وب و هم بر روی دستگاه‌های موبایل، بازی‌های استراتژیک بلادرنگ می‌سازد. بخش جالب مهندسی ماجرا، بلادرنگ بودن آن است. بنابراین همه چیزی که ما باید یاد بگیریم این است که سیستم‌های با مقیاس بالایی داشته باشیم که تأخیر (latency) به شدت پایینی داشته باشد و سرعت واکنش بالا داشته باشد. این‌ها می‌تواند در مورد موتور برنامه‌های گوگل به‌عنوان پلتفرم بکارگرفته شود یا به‌صورت یک وبسایت تجارت الکترونیک مانند eBay باشد و یا می‌تواند در بازی‌ها مثل کیکسای باشد. بنابراین خیلی از آموخته‌هایم بلکه همه آن‌ها، مستقیماً بکار می‌آید و این برای من ارزنده بوده است.موضوعی که امروز می‌خواهیم داشته باشیم یک بحث عمومی برای همه مخاطبان است که البته شامل خود من هم می‌شود اما شما در این موضوع، صحبت کرده‌اید. چرا تصمیم گرفتید که بیایید و عقاید خود در مورد استخدام و فرهنگ و این‌جور موارد را به اشتراک بگذارید.متشکرم. سئوال خوبی است. فکر می‌کنم همان طور که گفتید این یک موضوع جهانی است. من تاکنون در مورد خیلی چیزها صحبت کرده‌ام مثلاً برای مدت طولانی در مورد معماری‌های برای مقیاس بالا صحبت کرده‌ام، در مورد تحلیل‌گری و DevOps صحبت کرده‌ام. اما درست است، همان طور که شما گفتید فرهنگ، استخدام و سبکی که افراد در مهندسی دارند، موضوعاتی هستند که کمتر از حد درباره آن‌ها صحبت شده است و برای همه شرکت‌ها به شدت مهم هستند؛ چه شرکت‌های مهندسی باشند و چه نباشند اما خصوصاً در شرکت‌های مهندسی ما خیلی در مورد این صحبت می‌کنیم که چطور ماشین‌ها را خوشحال نگه داریم اما شاید آن مقدار که باید برای خوشحال نگه داشتن آدم‌ها وقت صرف نمی‌کنیم.بله، همین طور است. آیا اولین فرصتی که برای تأثیرگذاری در فرهنگ و فرآیند استخدام در یک شرکت داشتید را به‌خاطر می‌آورید؟بله، فکر می‌کنم همه در هر زمانی که در موقعیتی باشند که مسئولیت استخدام کسی را داشته باشند، دست کم تأثیر کمی دراین‌باره خواهند داشت. منظورم این است که اگر به ابتدای فعالیت حرفه‌ای‌ام یعنی تقریباً ۲۵ سال قبل برگردم، در آن زمان هم افرادی را استخدام می‌کردیم و تلاش می‌کردیم که افرادی را انتخاب کنیم که مطابقت خوبی با تیم و با فرهنگ و مهارت‌های مورد نیاز تیم داشته باشند. همچنین در استارتاپی که بعد از کار eBay داشتم، فقط دو نفر بودیم بنابراین هر تصمیمی که در مورد استخدام می‌گرفتیم تأثیر زیادی در شکل‌دهی فرهنگ‌مان داشت. اما موردی که فکر می‌کنم که تأثیر با بیشترین مانایی را دارد همین جا در کیکسای است. در کیکسای ۵۵۰ نفر در سانفرانسیسکو شاغل هستند. این اندازه آن‌قدر بزرگ هست که یک مرتبه تعداد زیادی موقعیت مختلف استخدام داشته باشیم و در عین حال آن‌قدر کوچک هست که فرهنگ قوام نیافته و همچنان می‌تواند تأثیر بپذیرد. قبل از آنکه من به این شرکت بپیوندم، البته فرهنگی وجود داشت و یکی از پروژه‌های جانبی که من تلاش می‌کردم انجام دهم این بود که کمک کنم برخی تجربیات خوبی که از گوگل و eBay داشتم را ارائه کنم و برخی‌ تجربیات دیگری که چندان خوب نبودند را بکار نبرم.بسیار خوب. آیا شرایط خاصی را می‌توانید به‌خاطر آورید که می‌خواستید روش استخدام در شرکت‌تان را عوض کنید و کاملاً همراستا با فرهنگ شرکت‌تان نبوده‌اید اما در حرفه‌تان خیلی تازه‌کار بوده‌اید که واقعاً بتوانید تغییر ایجاد کنید؟ مثلاً در ۲۵ سال پیش شرایطی بوده باشد که با خود گفته باشید که می‌خواهم این کار را به شکل بهتری انجام دهم.بله، قطعاً. فکر می‌کنم در هر شرایطی چه مربوط به استخدام باشد و چه مربوط به رویه‌های مهندسی یا هر چیز دیگر باشد، اکثر ما کاری را که انجام می‌دهیم دوست داریم و می‌خواهیم بهترین کار را انجام دهیم و اغلب نظرات جدی در مورد نحوه‌ بهبود عملکرد سازمانی که در آن هستیم داریم. بنابراین نمی‌توانم شرکتی را به‌خاطر بیاورم که در آن حس نمی‌کرده‌ام که می‌توانیم بهتر شویم. همیشه فرصتی برای بهتر انجام دادن هست. بنابراین استدلال سئوال شما کاملاً درست است. اینکه حدی از مقام سازمانی را داشته باشید کمک‌تان می‌کند که تأثیرگذار باشید اما هرگاه در موقعیتی باشید که با کسی مصاحبه می‌کنید، (که امیدوارم این فرض درست باشد که تمام شنوندگان، مهندسانی هستند که با افراد دیگر مصاحبه می‌کنند) این فرصت را دارید که تأثیر بگذارید. اگر کار مدیریتی بکنید، تأثیر گسترده‌تری خواهید داشت اما تأثیری که هنگام مصاحبه با یک فرد کاندید خواهید داشت هم این است که به او نشان می‌دهید که کار کردن در گروه شما و شرکت شما چگونه است، و هم اینکه کاندیداها را از لحاظ مهارت‌ها و تطابق با فرهنگ سازمان، ارزیابی می‌کنید. فکر می‌کنم این یک روش بسیار مستقیم و شخصی است که هر کسی به‌وسیله آن می‌تواند تأثیر بگذارد.بله، قطعاً. هرچند فکر می‌کنم وابسته به شرکتی که در آن هستید و فرهنگ سازمانی که آنجا حاکم است، می‌تواند متفاوت باشد چون من فکر می‌کنم تفاوت‌های مهمی بین کار کردن در آمریکا و در اروپا مثلاً آلمان وجود دارد که در ادامه در مورد آن صحبت خواهیم کرد. آیا فکر می‌کنید که شرکت‌های نرم‌افزاری نسبت به شرکت‌های تولیدی یا مثلاً لوله‌کش‌ها بر روی جنبه‌ها، اهداف یا فعالیت‌های متفاوتی تمرکز دارند یا اینکه فکر می‌کنید استخدام در همه جا از قواعد یکسانی پیروی می‌کند؟این سئوال خوبی است. فکر می‌کنم خیلی چیزها مشترک و خیلی چیزها متفاوت است. چیزهایی که مشترک هستند این است که شما به دنبال یک فرد با انگیزه هستید که با فرهنگ سازمان‌تان همخوانی داشته باشد، دنبال افرادی هستید که بتوانند مهارت‌هایی که دارند را نمایش دهند و همین طور بتوانند با دیگر افراد تیم تعامل و همکاری داشته باشند. فکر می‌کنم این موارد کاملاً همگانی هستند. شما به‌عنوان مثال به لوله‌کش‌ها اشاره کردید. لوله‌کش‌ها اغلب انفرادی کار می‌کنند اما مثلاً در یک کارخانه خودروسازی، چیزها کاملاً سازماندهی شده است، چند ده هزار نفر کار می‌کنند تا یک اتومبیل ساخته شود و مانند یک نرم‌افزاری نیست که چند ده نفر بر روی آن کار می‌کنند. به‌هرحال من فکر می‌کنم که مهارت‌های نرمی (soft skill) وجود دارد که در صنعت‌های مختلف یکسان هستند.اما درست است، در صنعت نرم‌افزار تفاوت‌هایی هم داریم. ما فرصت‌هایی داریم که مهارت‌های افراد را به روشی عینی ارزیابی کنیم که در ادامه به آن خواهیم پرداخت. اما بخش عمده آن این است که نرم‌افزار یک رویه مهندسی نوپا است و حتی برخی می‌گویند که هنوز در حدی که مکانیک، خودرو یا هوافضا، مهندسی هستند، در آن حد مهندسی نیست. به‌عنوان مثال، مانند زمینه‌های دیگر مهندسی نیست که گواهی‌نامه‌های مهندسی شناخته‌شده‌ای در آمریکا یا آلمان یا جاهای دیگر وجود داشته باشد که نشان دهد که شما چندین سال چیزی را تعلیم دیده‌ و در مورد آن تقدیر شده‌اید. هنوز چنین مفهومی در نرم‌افزار وجود ندارد. بنابراین در مورد فرآیند مصاحبه، چیزهای کمتری مربوط به خارج از مصاحبه وجود دارد که بتوانیم به آن‌ها تکیه کنیم و بیشتر کار باید در داخل فرآیند مصاحبه انجام شود. خیلی افراد هستند که تحصیلات دانشگاهی مرتبط و سوابق کاری دارند؛ البته روشن است که این‌ها هم برای ارزیابی مهارت‌های افراد مفید هستند اما یک مکانیزم شناخته شده و مورد احترام همگانی که عینی باشد و بتواند مفاهیم مهندسی را پوشش دهد وجود ندارد.بله، تعریف استانداردی وجود ندارد که مهندسی نرم‌افزار واقعاً چیست.امروزه شرکت‌های نرم‌افزاری، افراد را از طریق شبکه‌های اجتماعی و روش‌های دیگر استخدام می‌کنند اما برای کارخانه‌ها یا مثالی که زدم، در مورد لوله‌کش‌ها، این طور نیست. شما و شرکت‌تان چگونه کاندیداها را می‌یابید؟سئوال خوبی است. این چیزی است که همواره از خود می‌پرسیم زیرا شرکت کیکسای در سانفرانسیسکو واقع شده و امروزه در سال ۲۰۱۴ سانفرانسیسکو تبدیل به یک بازار بزرگ شده است به این معنا که پیدا کردن یک مهندس ماهر خیلی چالشی شده زیرا شرکت‌های زیادی دنبال چنین افرادی می‌گردند. البته تا حدی مزیت محسوب می‌شود که در شرکتی کار کنید که در آنجا بازی بسازید. این دلخواه خیلی‌هاست اما با این وجود رقابت‌های زیادی وجود دارد که البته چیز خوبی است.اما چطور آن‌ها را می‌یابیم؟ اول از همه و بهترین روشی که برای این کار وجود دارد این است که مستقیماً به افرادی که قبلاً با دیگران کار کرده‌اند مراجعه کرده و از آن‌ها بخواهم که به کیکسای بیایند. این روش، از جهات مختلف و با فاصله زیاد، بهترین است. مثلاً از این جهت بهترین است که فردی در کیکسای که او را می‌شناسد، دانش عمیقی در مورد مهارت‌ها، نحوه تعامل کردن او، مطابقت‌های فرهنگی او و مواردی از این دست دارد. اگر چندین سال با کسی کار کرده باشید نسبت به یک مصاحبه چند ساعته، دانش بسیار عمیق‌تری از او خواهید داشت. بنابراین این اولین و بهترین روش است و برای همه شرکت‌ها نیز صادق است.اما لینکدین، هم برای کاندیداهای بالقوه و هم برای شرکت‌هایی که به دنبال کاندیدا می‌گردند، یک نعمت خداداد است. قبل از لینکدین راهی برای پیدا کردن رزومه افراد نبود و بدون درخواست از افراد امکان یافتن سوابق کاری‌شان نبود. فقط همین که می‌توانید کسی را در لینکدین ملاقات کنید و آن‌ها می‌توانند بخش‌هایی از پیش‌زمینه‌های خود را به شما بدهند، فوق‌العاده ارزشمند است. همین طور اینکه می‌توانید به جستجوی افرادی بپردازید که با مجموعه مهارت‌های خاصی در شرکت‌های مشخص دیگری کار می‌کنند نیز فوق‌العاده ارزشمند است. دسته‌ای از جنبه‌هایی که در لینکدین پیشنهاد می‌شوند به‌طور خاص شامل استخدام هم هستند که حتی ارزشمندی بیشتری هم دارند بنابراین لینکدین هم برای کاندیداها و هم برای شرکت‌ها نعمت بزرگی است. اما جنبه منفی‌اش این است که قبلاً وقتی رزومه‌ای را به جایی می‌فرستادید معنی‌اش این بود که در آن زمان دارید دنبال شغل می‌گردید اما در لینکدین دیگر این طور نیست. در لینکدین دیگر این ایده درست نیست که ارسال رزومه به این معناست که از کارتان راضی نیستید و دنبال موقعیت دیگری هستید.به عقیده من آدم‌هایی که معامله کردن با آن‌ها سخت است آن دسته حرفه‌‌ای‌هایی هستند که پروفایل لینکدین ندارند و عموماً این افراد در صنعت‌های غیر نرم‌افزاری هستند زیرا لینکدین هنوز به آن صنایع نفوذ نکرده است. اما سهم بسیار بسیار عمده‌ای از آدم‌ها یعنی ۹۹ درصد افرادی که من به‌صورت حرفه‌ای می‌شناسم اخیراً پروفایل‌های پرجزییاتی در لینکدین دارند و این فوق‌العاده ارزشمند است. به‌ هر حال نکته‌ای که می‌خواستم اشاره کنم این است که داشتن پروفایل لینکدین به تنهایی بیانگر این نیست که به‌دنبال موقعیت شغلی می‌گردم یا خیر. قبلاً این طور بوده که ارسال رزومه به تنهایی مؤید این بوده است که می‌خواهم جای دیگری کار کنم اما اکنون داشتن یک پروفایل لینکدین یک امر پذیرفته شده است و این خوب است زیرا استخدام هم مانند یک بازار است. چه شما پولی تبادل کنید یا نکنید، همین مفهوم کلی که تولیدکنندگان کار و مصرف‌کنندگان کار دور هم گرد می‌آیند، نوعی بازار، است :-). می‌توان این طور قیاس کرد که لینکدین به روشنی نوعی فروش الکترونیکی مهارت‌های بشری است.که جالبه زیرا در آلمان [لینکدین] اصلاً مهم نشده ولی محصول دیگری داریم که این نقش را بازی می‌کند.بله، می‌توانم گفته شما را تصور کنم. هیچ چیز خارق‌العاده‌ای که خاص لینکدین باشد وجود ندارد. لینکدین در آمریکا فرمانروایی می‌کند اما قطعاً ممکن است در کشورهای دیگر جایگزین‌های دیگری باشد.من فکر می‌کنم که لینکدین کمک می‌کند که بِرَند خود را بسازید.دقیقاً. یکی از دوستان و مربیان خوب من که سال‌ها پیش در اوائل تجربه کاری‌ام در شرکت اوراکل با او همکار بودم، سال‌ها پیش به من گفت: رندی، تو باید «برند» شخصی خودت را بسازی! دقیقاً همین لغت را بکار برد. می‌دانید که لغت برند در مورد بازار بکار می‌رود اما من یک مهندس هستم و کار بازار نمی‌کنم. من در مورد این گفته‌اش خیلی جدی فکر کردم و او کاملاً درست می‌گفت. به‌همین خاطر من تشویق می‌کنم که به‌عنوان ملزومات اولیه کار، پروفایل لینکدین (و یا البته معادل آلمانی آن را)‌ داشته باشید. لینکدین در چین هم معادل دارد و خودش در چین بزرگ نشده است. این ملزومات اولیه کار است و پس از آن، به اشتراک گذاشتن کدها و مهارت‌های‌تان در گیت‌هاب، شرکت و صحبت کردن در کنفرانس‌ها و شرکت در گعده‌ها (meetup) و ... هم هست. ویژگی خاص گعده‌ها این است که معمولاً کم هزینه هستند و در مجاورت محل زندگی شما برگزار می‌شوند. همه این‌ها می‌تواند برای راه یافتن به اجتماع و شرکت داشتن در اجتماع کمک کند و همزمان به آرامی برند شخصی خود را می‌سازید.شاید به نظر عجیب برسد اما وقتی من به تجربه شخصی خودم مراجعه می‌کنم هر وقتی که شغلم را عوض کردم به‌خاطر یک رابطه شخصی بوده است؛ همیشه یک معرف، یک دوستِ دوست وجود داشته است و خیلی مواقع به این خاطر نبوده که من در جستجوی کار بوده‌ام بلکه به این خاطر بوده است که دوست من یا دوستِ دوست من به دنبال شخصی با مجموعه مهارت‌های خاصی می‌گشته است. هرچه بتوانید برند شخصی خود و شبکه ارتباطات شخص خود را قوی‌تر کنید، شانس بیشتری برای پیدا کردن کاری دارید که واقعاً دوست دارید آن را انجام دهید.شما در مورد سیستم معرف‌ها صحبت کردید. شما در لینکدین و سیستم‌های مشابه، اطلاعات خیلی زیادی در مورد شخصی که می‌خواهید با او مصاحبه کنید دارید. در این صورت وقتی از قبل این همه اطلاعات در مورد شخص دارید، هدف حقیقی مصاحبه چه خواهد بود؟در حالت ایده‌آل آنچه از لینکدین و گیت‌هاب و مکانیزم‌های مختلف دیگر بدست می‌آورید در مورد مهارت‌های فرد است اما آنچه نمی‌دانید این است که چطور در فرهنگ تیمی و سازمانی شما تطبیق می‌یابد. من فکر می‌کنم این دو به یک اندازه اهمیت دارند. شما نمی‌توانید تطابق‌های فرهنگی را به سادگی از طریق لینکدین بسنجید. بنابراین به نوعی ارتباط برقرار کردن نیاز دارید. ما مصاحبه‌هایی را به‌صورت از راه دور از طریق اسکایپ انجام داده‌ایم که خوب جواب داده است تا بتوانیم جنبه‌های شخصی فرد را بسنجیم، اینکه شخص چطور می‌تواند در تیم و سازمان تطبیق یابد.از طرف دیگر، وقتی جریان داد و ستد و مکالمه بین شما و فرد شکل می‌گیرد، ارزیابی مهارت‌های کدنویسی و تفکر فرد هم خیلی ساده‌تر می‌شود و همین طور خیلی عمیق‌تر می‌شود. این هم جنبه دیگرش است. ما این کار را در کیکسای و جاهای دیگر به خوبی اجرا کرده‌ایم. برای برخی مهارت‌های خاص، ما آزمون‌های کدنویسی داریم که به افراد می‌دهیم و آن‌ها می‌توانند به خانه ببرند، در مورد آن فکر کنند و کارشان را برایمان بیاورند، مثلاً به آن‌ها می‌گوییم که برای ما یک بازی استراتژی بسازند. بنابراین می‌توانید به این فکر کنید که به افراد فرصت‌هایی بدهید که مهارت‌هایشان را نمایش دهند و بعد می‌توانید در جلسه مصاحبه در مورد آن صحبت کنید و از آن‌ها بپرسید که چیزی که ساخته‌اند را چرا ساخته‌اند. این کار فوق‌العاده ارزشمند خواهد بود زیرا در نهایت، ما (چه در کیکسای و چه در گوگل و eBay) به دنبال افراد باانگیزه باهوش هستیم. اینکه فردی بیاید که مهارت‌هایی که ما می‌خواهیم را داشته باشد خیلی خوب است اما تقریباً (تأکید می‌کنم تقریباً) مطلب مهم‌تر این است که آن‌ها قابلیت یادگیری داشته باشند. من ترجیح نمی‌دهم که یک محقق، یک گرافیست یا مهندس هوش مصنوعی در بازی‌سازی استخدام کنم که برای مدت طولانی یکی از این کار‌ها را کرده باشد و به‌خاطر اینکه به دیگر زمینه‌ها علاقه نداشته است یا به‌خاطر کسب مهارت فقط در یک زمینه خاص، دیگر مهارت‌ها را ندارد. در عوض ترجیح می‌دهم که فردی را استخدام کنم که مجموعه مهندسی وسیع‌تری داشته باشد و بتواند در این مجموعه، به بالا پایین و چپ و راست حرکت داشته باشد تا اینکه بخواهم کسی را استخدام کنم که مختص یک فناوری خاص باشد. البته نمی‌خواهم این حس را القاء کنم که ما دنبال هر کارمندی هستیم و برایمان فرقی نمی‌کند و همه برایمان یکسان هستند. من خودم، در برنامه‌نویسی گرافیکی و واسط کاربری افتضاح هستم، بنابراین چنین مطالبه‌ای ندارم که افراد تخصص و علاقه نداشته باشند اما آنچه ما به‌دنبالش هستیم افرادی هستند که گستره بیشتری از این مهارت‌ها و علاقه‌ها را داشته باشند تا اینکه خیلی محدود باشند.بله، زیرا اگر افرادی را داشته باشید که فقط به مهارت‌های خودشان محدود باشند، این محدودیت را خواهید داشت که شما این قابلیت را نخواهید داشت که تصمیم بگیرید از بسته یا زبان دیگری که مطرح شده، استفاده کنید و همه بتوانند از چنین تصمیمی پیروی کنند.بله، دقیقاً. موافقم. یکی از روش‌هایی که افراد به‌طور ضمنی چنین چیزی را نشان می‌دهند این است که خود را مثلاً به‌عنوان مدیر سیستم پایگاه داده اوراکل معرفی می‌کنند یا می‌گویند من یک مهندس ++C هستم یا ... . هیچ اشکالی ندارد که در این زمینه‌ها خبره باشید اما نکته‌ ظریفی که وجود دارد این است که آیا خود را وابسته به یک بسته یا مهارت خاص تعریف می‌کنید یا اینکه اینها فقط چیزهایی است که شما در آن خبره هستید و همچنان به یادگیری چیزهای دیگر هم علاقه دارید.بله، قطعاً. در برخی صحبت‌های شما در اینترنت شنیده‌ام که شما فقط افراد سطح A را استخدام می‌کنید و این استراتژی است که گوگل در ارتباط با استخدام دارد. به‌طور خاص وقتی این استراتژی را داریم که افرادی که دیدگاه بازی داشته باشند و فقط محدود به یک دسته مهارت خاص نباشند، را استخدام کنیم در این صورت استخدام افراد سطح A چه معنی می‌دهد؟ شما کلاً افراد را چطور استخدام می‌کنید؟بسیار خوب. بگذارید توضیح دهم که منظورم از استخدام افراد سطح A چیست. این مطلب خیلی خوب مطالعه و مستند شده است که خصوصاً در صنایع خلاقانه‌ای مانند نرم‌افزار، تفاوت کارایی میان کاراترین و کم‌کاراترین افراد، یک و نیم برابر یا دو برابر نیست بلکه مثلاً ده برابر است یعنی در یک شرکت که به مقدار کافی بزرگ باشد کاراترین مهندس، نسبت به کم‌کاراترین مهندس، حدود ده برابر کارایی بیشتری دارد. از این جهت شما به‌عنوان یک شرکت وقتی چنین فرصتی را دارید بهتر است که این افراد ده برابری را استخدام کنید زیرا اولاً تعداد کمتری از آنها را استخدام می‌کنید و دوماً اگر تعداد کمتری از آن‌ها را استخدام کنید می‌توانید تیم‌های کوچک‌تری داشته باشید و با داشتن تیم‌های کوچک‌تر، سربار تعاملات و هماهنگی‌های کمتری خواهید داشت و تیم می‌تواند کاراتر باشد. همه این جنبه‌ها به ما می‌گویند که خیلی بهتر است یک شرکت، افراد ماهرتر را در عوض افراد کم‌مهارت‌تر استخدام کند؛ من نگفتم افراد باتجربه‌تر زیرا لزوماً رابطه مستقیمی بین انجام کاری برای مدت طولانی و کاراتر بودن نیست.اما شما سئوال خوبی پرسیدید که آیا این موضوع [سطح A بودن یک فرد] یک چیز عینی است یا یک موضوع ذهنی است؟ در این مورد به مانند جام جهانی فکر کنید. بهترین تیم‌های ملی، همگی بازیکنان یکسانی ندارند. بازیکنانی در این تیم‌ها وجود دارند که با مهارت‌های مختلف می‌توانند کارهای زیاد مختلفی انجام دهند اما یک تیم خوب، از ترکیبی از بازیکنان با مهارت‌های مختلف تشکیل یافته است و یک بازیکن خاص که در یک تیم، عالی عمل می‌کند، لزوماً متناسب تیم دیگر نیست. برزیلی‌ها فوتبال را متفاوت با آلمان‌ها و اسپانیایی‌ها بازی می‌کنند. بنابراین بهترین بازیکن بودن برای یک تیم مشخص، خاص همان تیم است.بله، حتی گاهی مربی مجبور می‌شود بازیکنان را تعویض کند زیرا دومین بازیکن خوب، بهترین تطابق را با تیم دارد و نسبت به بازیکنی که از لحاظ انفرادی بهتر است، بیشتر می‌تواند به تیم کمک کند.دقیقاً. در نهایت هدف این است که تیم کارا باشد. تشبیه خوب دیگری که در این مورد می‌توانیم داشته باشیم، ارکستر سمفونی است. شما نوازندگان مختلفی دارید که هر کدام در زمینه خودشان، مهارت دارند اما این به آن معنا نیست که مثلاً بهترین نوازنده ویولن سل، همان بهترین نوازنده‌ای است که می‌تواند در کورتت (گروه ۴ نفره نوازندگان و خوانندگان) شما بنوازد و یا بهترین گیتاریست، مناسب‌ترین فرد برای هر گروه راک ممکن نیست. بنابراین اگر به سئوال‌ اصلی‌مان برگردیم شما به دنبال یافتن افرادی هستید که در زمینه کار شما کاراترین فرد باشد. البته که یک ملزومات پایه‌ای از مهارت‌ها نیاز است اما موارد فرهنگی نیز مهم است.بنابراین به این معناست که اگر یک شرکتی بگوید که فقط بدنبال افراد سطح A یا به اصطلاح ده درصد برتر می‌گردد، این به آن معنا نیست که شرکت دومی هم که می‌خواهد افراد سطح A را استخدام کند، دنبال افراد دقیقاً یکسانی می‌گردد. این وابسته به مطابقت با فرهنگ شرکت و مهارت‌های مورد درخواست دارد و این به آن معنا نیست که ما ۹۰٪ از نیروهای درخشانی که وجود دارند را نادیده می‌گیریم.قطعاً بخشی از آن درست است البته این هم درست نیست که ده درصد برتری که کیکسای تعریف می‌کند، هیچ همپوشانی با ده درصد برتری که گوگل یا eBay یا سَپ تعریف می‌کند ندارد. حتماً مقداری از همپوشانی وجود خواهد داشت. بنابراین روشی که ما می‌توانیم این را بیان کنیم این است که ما به‌دنبال بامهارت‌ترین افرادی هستیم که در عین حال با فرهنگ‌‌ تیم‌‌مان نیز تطابق داشته باشند. این به همان تشبیه فوتبال‌مان بر می‌گردد؛ یک دروازه‌بان یا بازیکن باید سطح خیلی بالایی از مهارت‌ها - نه سطح پایه- را داشته باشد تا بتواند در سطح جام جهانی بازی کند و تطابق داشتن با تیم نیز در مرحله بعد از آن اضافه می‌شود.یکی از نکاتی که شما در صحبت‌هایتان اشاره کرده‌اید این است که افراد سطح C، افراد سطح C را استخدام می‌کنند یا شاید افراد سطح B، افراد سطح C را نسبت به افراد سطح A بیشتر استخدام کنند زیرا مسأله رقابت پیش می‌آید و آنها نمی‌خواهند که فرد با‌مهارت‌تری، بر آن‌ها چیره شود. من این گفته شما را خیلی دوست دارم و فکر می‌کنم شاید استخدام افراد سطح A مربوط به این است که ببینیم چه کسی چه کسی را استخدام کرده است و این چطور بر روی کل تیم تأثیر گذاشته است. آیا این درست است؟بله، کاملاً. شما می‌خواهید که کارایی تیمی که دارید را ماکزیمم کنید و در همان حال می‌خواهید که تیم‌تان به نوعی یک اندام پایدار باشد. بهترین حالتی که می‌توانیم یک فرد سطح A را بدست آوریم این است که هم‌اکنون یک گروه از آن‌ها را داشته باشیم زیرا اولاً برای کاندیداها خیلی جذاب می‌شود و آن‌ها با خود می‌گویند این آدم‌ها خیلی باحال هستند و من می‌خواهم که با آن‌ها کار کنم. از طرف دیگر، افراد سطح A، هم می‌خواهند که با بهترین‌ها کار کنند، آن‌ها به مهارت‌های خودشان اعتماد دارند و می‌خواهند با افراد عالی دیگر همکار شوند زیرا می‌توانند از آن‌ها چیز یاد بگیرند. مهمترین چیز در مورد سطح A بودن، همین انگیزه یادگیری است، اینکه همواره می‌خواهید رشد کنید و به همین خاطر بوده که به این سطح رسیده‌اید. بنابراین افراد سطح A تمایل به استخدام افراد سطح A دارند اما همان طوری که شما گفتید افراد سطح B به استخدام افراد سطح C گرایش دارند زیرا خودآگاه یا ناخودآگاه، به‌علت نوعی عدم خودباوری یا ترس، نمی‌خواهند افراد سطح A را استخدام کنند زیرا در مورد موقعیت خود نگران هستند، حتی بدتر از آن این است که فردی که در سطح مساوی باشد هم بالقوه تهدید به حساب می‌آید و متأسفانه سازمان‌های بزرگ سنتی اغلب این مشکل را دارند و در طول زمان سطح افرادی که استخدام می‌شوند به تنزل گرایش دارد و این باعث بی‌انگیزه شدن اندک افراد باقیمانده سطح A می‌شود و وقتی آن‌ها هم بروند دیگر خیلی سخت می‌شود که ورق را برگردانیم.بله، قطعاً. وقتی به صحبت‌های شما را در اینترنت نگاه می‌کردم، به نظر می‌رسد که شما روش استخدامی که گوگل دارد را تحسین می‌کنید. آیا ممکن است به ما بگویید این روش نسبت به روش معمول استخدام چه تفاوتی دارد و چرا آن را به روش‌های دیگر ترجیح می‌دهید؟بله، ابتدا بگذارید هدف آن را بگویم. افراد می‌توانند خودشان در اینترنت جستجو کنند، من چیزی نمی‌گویم که سرّی باشد و جنبه داخلی گوگل را داشته باشد، این موارد به خوبی در دسترس عموم قرار گرفته است. بنابراین بگذارید با هدف گوگل آغاز کنیم. هدف گوگل این است که پیرو بحثی که الان داشتیم افراد سطح A را استخدام کند؛ هدفش این است که «فقط» افراد سطح A را استخدام کند. اگر فرآیند استخدام را به مانند یک خط لوله در نظر بگیریم، آن‌ها می‌خواهند در انتهای خط لوله فقط افراد سطح A باشند که جذب گوگل می‌شوند. گوگل می‌خواهد ردی اشتباه (false negative) داشته باشد اما هیچ‌گاه قبولی اشتباه (false positive) نداشته باشد. ردی اشتباه به این معنی است که به منِ رندی بگویند متأسفیم گوگل جای مناسبی برای شما نیست اما اشتباه کرده باشند. آن‌ها این اشتباه کردن را پذیرفته‌اند و می‌دانند که شاید رندی باید می‌آمده است. اما آن‌ها هیچ‌گاه نمی‌خواهند قبولی اشتباه داشته باشند که رندی را استخدام کنند اما رندی مناسب گوگل نباشد. بنابراین همه چیزها در فرآیند استخدام برای این هدف تدارک دیده شده است.اگر از دیدگاه کاندیداها نگاه کنیم، آن‌ها با مصاحبه‌های فنی کاملاً عمیق و پرجزییاتی مواجه می‌شوند. من، خودم قبل از مصاحبه گوگل، هفته‌ها کتاب‌های طراحی الگوریتم را مطالعه می‌کردم که ارزشش را داشت زیرا مصاحبه‌ها خیلی عمیق و پرچالش بودند. این روش به دو علت خوب است، نخست آنکه یک سازوکار صافی کردن خوب است و دیگر اینکه بیانگر میزان جدی بودن گوگل در ارتباط با مهندسی است. بنابراین داشتن یک مصاحبه سخت، از این نظر صافی کردن میزان قدرت کاندیداها چیز خوبی است اما مطلب دیگری که کمتر از آن تقدیر شده است این است که به کاندیداها این پیام را می‌رساند که ما در ارتباط با این موقعیت شغلی جدی هستیم، اینجا جای خوبی برای کار کردن است و به‌همین خاطر است که ما تا این میزان برای آن تلاش می‌کنیم و مصاحبه تا این حد سخت است. آدم‌ها کارهای پرچالش را دوست دارند به‌همین خاطر است که ما مثلاً بازی کردن را دوست داریم. بنابراین این موضوع دو جنبه دارد و من فکر می‌کنم که از جنبه دوم به‌درستی تقدیر نشده است.بنابراین مصاحبه بسیار سخت است و همان طور که در خیلی از شرکت‌ها متعارف شده، چندین دوره مصاحبه برگزار می‌شود. اما گوگل در طی زمان دریافته که چطور این کار را انجام دهد. چند مورد هست که نسبت به مصاحبه‌های عادی در جاهای دیگر متفاوت است. اول اینکه برای تصمیم‌گیری در مورد استخدام افراد، یک موقعیت شغلی با عنوان «مدیر استخدام» نداریم بلکه این تصمیم بر اساس ارزیابی عینی همان مصاحبه‌ها رخ می‌دهد. همه فیدبک‌هایی که مصاحبه‌کنندگان از مصاحبه‌ها می‌دهند، به کمیته استخدام می‌رود. این کمیته از هیچ کدام از آن مصاحبه‌کنندگان یا هیچ مدیر استخدامی تشکیل نشده است. البته [در گوگل] کمیته‌های استخدام زیادی وجود دارد اما بیایید از لحاظ مفهومی فرض کنیم که فقط یک کمیته وجود دارد، در آن صورت آن کمیته، جریانی که همه کاندیداها طی کرده‌اند را می‌بینند، اعضاء کمیته همگی مهندس‌های ارشد گوگل هستند که مدت طولانی در آنجا از بهترین‌ها بوده‌اند و می‌دانند کار کردن در گوگل به چه شکلی است و فرهنگ گوگل چیست، بنابراین هرکدام از آن‌ها به روشی شخصی به‌دنبال فردی هستند که بهترین مطابقت برای گوگل را داشته باشد و آن‌ها هستند که این تصمیم را می‌گیرند که آیا به رندی پیشنهاد همکاری بدهند یا خیر. بعد از آن، اینکه حالا این شخص در کدام بخش گوگل قرار بگیرد، مطلب مجزایی است. بعد از آن است که مصاحبه با مدیر استخدام و گروه خاص آن، انجام می‌شود زیرا این مصاحبه‌های بعدی کمتر در مورد ارزیابی مهارت‌های فرد است و بیشتر در مورد تطبیق با فرهنگ داخل تیم است. من این تمایز را دوست دارم. از برخی جنبه‌ها، این روش در گوگل خوب جواب می‌دهد زیرا جریان عظیمی از کاندیداها وجود دارد و اینکه صافی‌های زیادی در جلوی راهشان وجود دارد، مشکلی ندارد زیرا در ابتدای خط لوله به تعداد کافی ورودی دارید. طی تجربه اندکی که من داشته‌ام نتیجه نهایی این است که افرادی که از انتهای دیگر خارج می‌شوند شدیداً بامهارت و باانگیزه هستند و کاملاً از لحاظ فرهنگی مطابقت دارند و به نظر من این فرآیند نسبت به فرآیندهای دیگر نرخ موفقیت‌ بیشتری داشته است زیرا فرآیندی سخت و عینی است و همان طور که گفتم جدی بودن و اینکه اینجا جای واقعاً خوبی برای کار کردن است را به کاندیداها نمایش می‌دهد.من می‌خواهم دو جنبه از این نوع روش استخدام را توضیح دهم، البته من می‌دانم که فقط گوگل نیست که به این روش عمل می‌کند و شرکت‌های دیگر هم از آن‌ها آموخته‌اند. اول اینکه گاهی یا اغلب به نظر می‌رسد که گوگل تنها به این خاطر که افراد دفعه اول است که مراجعه کرده‌اند آنها را رد می‌کند. دوم اینکه به نظر می‌رسد آزمون‌ها تنها حول ساختمان داده و طراحی الگوریتم است. آیا این مقداری کم‌دامنه نیست؟ آیا فکر نمی‌کنید افراد ارزشمند دیگر و یا سهم عمده‌ای از آن‌ها، کنار گذاشته می‌شوند؟بله، سئوال‌های خوبی است. مورد اول به مسأله «ردی اشتباه» بر می‌گردد. بگذارید دوباره این را توضیح دهم که هدف فرآیند استخدام این است که اطمینان حاصل شود که تنها افراد سطح A استخدام می‌شوند، تنها کاندیداهایی که از لحاظ مهارتی و فرهنگی تطابق دارند، پذیرش می‌شوند. رد کردن آدم‌ها هیچ مزیتی ندارد اما این فقط به این خاطر است که گوگل خیلی شفاف و آشکارا می‌گوید که اشتباه می‌کند. ما گوگلی‌ها می‌دانیم که در این فرآیند اشتباه می‌کنیم و افرادی را رد می‌کنیم که واقعاً باید استخدام می‌کردیم و این مطلب کاملاً شناخته شده است. بنابراین کمیته‌ استخدامی که به آن اشاره کردم، به‌عنوان بخشی از ارزیابی کاندیداها، می‌توانند بگویند که استخدام می‌‌کنیم، می‌توانند بگویند که استخدام نمی‌کنیم و هم می‌توانند بگویند که از آن‌ها می‌خواهیم که مجدداً تقاضا کنند. من شنیده‌ام که در برخی از این کمیته‌ها به‌عنوان مثال چنین صحبت‌های در می‌گیرد که: «فلانی در مصاحبه‌ها خوب بوده است اما موارد اندکی را اشتباه کرده بنابراین الان نمی‌تواند استخدام شود اما خوش‌آتیه است و حالا که می‌داند فرآیند استخدام به چه ترتیبی است بهتر است از او بخواهیم که ۶ ماه دیگر، دوباره تقاضا کند» و بعد این امید هست که او دوباره تقاضا کند و مجدداً در فرآیند استخدام قرار گیرد. من می‌خواهم روشن کنم که همه افرادی که در این فرآیند قرار می‌گیرند تشخیص می‌دهند که این فرآیند، بی‌عیب نیست و ما افرادی که واقعاً باید اینجا باشند را رد می‌کنیم. این رد کردن گوگل به معنای این نیست که دیگر هیچ‌گاه با گوگل تماس نگیرید و افرادی که رد شده‌اند چنین احساسی نمی‌کنند. آن‌ها اگر همچنان خواهان کار کردن در آنجا هستند باید دوباره تقاضا کنند و بار دوم ممکن است موفق شوند. الان افرادی در گوگل هستند که درباره نحوه استخدام در گوگل، در وبلاگ‌شان نوشته‌اند و می‌توانید در مورد آن‌ها جستجو کنید. مثلاً استیو یگ یک مثال خوب از آنها است. او خودش دفعه اول، موفق به استخدام نشده است. او خیلی شفاف در این مورد نوشته است. او یک دفعه مصاحبه داده و رد شده و متوجه شده که خیلی سخت است و شروع کرده به مطالعه بیشتر. مطلب خوبی در وبلاگش دارد که می‌توانید خودتان بخوانید. من خودم قبل از آنکه [درگوگل] مصاحبه شوم کل توضیحاتی که در مورد تجربیاتش داده بود را خوانده بودم.بخش دوم سئوال شما این بود که آیا فرآیند گوگل تنها بخش خاصی از کاندیداهای بالقوه را انتخاب می‌کند و بخش دیگری که واقعاً باید آنجا باشند را رها می‌کند؟ شما به‌طور خاص این مثال را زدید که ما بر اساس دانش ساختمان داده‌ها و طراحی الگوریتم که مربوط به دو سه سال اول دانشگاه‌شان است (البته اگر کامپیوتر خوانده باشند)، ارزیابی می‌کنیم. دوباره در اینجا نیز من با این مطلب شروع می‌کنم که افراد متوجه هستند که این فرآیند ممکن است اشتباه ‌کند. اگر دوباره به تشبیه فوتبال‌ برگردم، در آنجا همه باید بتوانند توپ را به چرخش درآورند و پاس‌های دقیق بدهند. در اینجا نیز مهارت‌های ساختمان‌ داده‌ها و طراحی الگوریتم، چیزی است که گوگل به‌عنوان ملزومات پایه‌ای که هرکسی باید داشته باشد، وضع کرده است. اما نکته مثبتش این است که اگر در این زمینه‌ها احساس فرسودگی می‌کنید، می‌توانید آن‌ها را مطالعه کنید. قرار نیست موشک هوا کنید. من خودم برای مدت طولانی مطالعه می‌کردم بعد تقاضای استخدام کردم. من کتاب مرجع الگوریتم‌ها را همان طور که توصیه شده بود از ابتدا تا انتها خواندم و بادقت روی مطالب آن فکر می‌کردم؛ همین طور تعدادی از آزمون‌های برنامه‌نویسی را از خود می‌گرفتم و این‌ها واقعاً کمک کرد.یک مطلبی که به‌صورت ضمنی در سئوال شما وجود داشت این است که واضح است که وقتی به‌عنوان کارمند گوگل در راهروها قدم می‌زنید قرار نیست کسی از شما بپرسد که پیچیدگی زمانی (time complexity) یا پیچیدگی فضایی (space complexity) فلان الگوریتم چقدر است. قرار نیست چنین اتفاقی بیافتد اما این‌ها ملزومات پایه‌ای هستند که دست‌کم قابل ارزیابی به‌صورت عینی هستند. این یک جنبه دیگری از این مطلب است؛ منظورم این است که شما می‌توانید بفهمید که آیا مثلاً رندی کاربرد مناسب جداول درهم‌سازی (hash table) یا لیست‌های پیوندی یا درخت‌های قرمزسیاه و ... را می‌داند یا نمی‌داند و این موضوعات کمتر جنبه شخصی و ذهنی دارند. من نمی‌خواهم این احساس را پیدا کنید که این‌ها تنها مواردی است که شما بر اساس آن ارزیابی می‌شوید اما این‌ها ملزومات پایه هستند.برای اینکه اطمینان یابیم که ما فقط در مورد گوگل صحبت نکرده‌ایم، می‌خواهم از شما بپرسم که اگر بخواهید این رویه‌ها را در فرآیند استخدام خود در کیکسای بکار ببرید، آیا تغییراتی در آن اعمال می‌کنید و روش دیگری انتخاب می‌کنید که نسبت به فرآیند گوگل برای کیکسای مطابقت بهتری داشته باشد؟سئوال خوبی است. قطعاً ما تمامی فرآیند استخدام گوگل را به خدمت نگرفته‌ایم. ما پارسال شروع کردیم که چیزهای دیگری به فرآیند اضافه کنیم. همان طور که پیش از این اشاره کردم، ما همیشه، در موضوعات خاصی، آزمون‌های برنامه‌نویسی برای انجام در منزل داریم، ما شروع کردیم که این آزمون‌ها را بیشتر کنیم زیرا فهمیده‌ایم که به چند دلیل عموماً باارزش هستند. اول اینکه، یک روش عینی برای فرصت دادن به افراد برای نمایش مهارت‌هایشان است. از طرف دیگر این روش خوبی برای برقراری گفتگو است. مثلاً به فرد کاندیدا می‌گویید که در کدهای او متوجه چیزی شده‌اید و می‌خواهید در مورد آن و مصالحه‌هایی که وجود داشته صحبت کنید. به این ترتیب می‌توانید گفتگوهای مهندسی بیشتری نسبت به قبل برقرار کنید. متوجه منظورم می‌شوید؟قطعاً. اگر فقط همین علت را هم داشت باز هم خیلی خوب بود.جنبه دیگر آن این است که درباره ادامه فرآیند، صریح باشیم. ما یک کمیته استخدام مجزا نداریم چون هنوز به اندازه‌ای نرسیده‌ایم که چنین چیزی شکل بدهیم اما سخت‌گیری‌های بیشتری در ادامه‌ فرآیند قرار داده‌ایم که کمک کرده است.آیا هم‌اکنون بخشی از زمان خود یا تیم‌تان را به استخدام کردن می‌پردازید؟ما یک شرکت ۵۰۰ نفره هستیم و ۶ نفر داریم که تمام‌وقت به ثبت و ضبط امور استخدام می‌پردازند. این فعالیتی است که در کل شرکت تلاش فراوانی برای آن می‌شود. من و تیم من به‌طور خاص، حدود ۱۰ تا ۱۵ درصد و گاهی ۲۰ درصد زمان‌مان را به این کار می‌پردازیم. ما زمان و زحمت زیادی برای ارزیابی کاندیداها و اطمینان از اینکه مطابقت خوبی دارند، می‌کنیم. به‌علاوه همانطور که قبلاً در این مصاحبه اشاره کردم، همه ما بر روی گسترش دادن شبکه ارتباطی‌مان برای پیدا کردن افراد کار می‌کنیم زیرا همان طور گه قبلاً گفتم بهترین روشی که می‌توانید بفهمید آیا فردی مطابقت خوبی دارد این است که او را از قبل بشناسید. بگذارید در اینجا یک جوک بگویم: روش استانداردی که در فرآیند استخدام وجود دارد مانند این است که با فردی یک ساعت صحبت کنید و بعد با هم ازدواج کنید. این خیلی احمقانه است اما اگر کسی باشد که چندین سال با او کار کرده باشید و به خوبی او را بشناسید و او هم شما را به‌خوبی بشناسد، این می‌تواند مؤثر باشد. فکر می‌کنم این تشبیه، درست باشد. ما هم در مورد علاقه افرادی که به کیکسای می‌آیند و هم در مورد موفقیت افرادی که این‌جا هستند، بیشترین موفقیت را درباره افرادی داشته‌ایم که توسط افراد دیگری معرفی شده‌اند و پیش از آن، برای مدت طولانی با هم کار کرده‌اند و جایگزین دیگری برای این امر نیست. مستقل از اینکه چه تعداد آزمون داشته باشیم، چه مقدار عینی باشیم، چقدر دقیق و سریع صحبت کنیم، ... هیچ روشی که بتواند جای ۳ سال کار کردن با کسی را بگیرد، وجود ندارد.اما سرانجام به این مربوط می‌شود که چقدر می‌توانید زمان صرف کنید که خیلی نمی‌توانید.دقیقاً.می‌خواهم سئوالی از شما بپرسم که خصوصاً برای من که آلمانی هستم و همین طور برای همه مخاطبین ما که آسیایی یا اروپایی هستند و در آمریکار نیستند، اهمیت دارد. آیا فکر نمی‌کنید که این روشی که توضیح داده شد با فرهنگ‌های ملت‌های دیگر غیرآمریکایی در تضاد باشد؟ به‌عنوان مثال من به‌عنوان یک فرد آلمانی، این کار را نخواهم کرد که بعد از یک بار که برای استخدام در شرکت شما اقدام کردم، ۶ ماه به شدت کار کنم و بعد دوباره تقاضا بدهم. آیا فکر می‌کنید که این تصور اشتباه است و جنبه‌های عمومی برای استخدام وجود دارد که در همه کشورها می‌تواند بکار گرفته شود؟ یا اینکه فکر می‌کنید همه این تکنیک‌ها باید برای افراد کشورهای مختلف، دوباره تنظیم شوند؟سئوال خوبی است. تجربیات استخدام من منحصر به آمریکا و بالاخص دره سیلیکون است. بنابراین نسبت به این ایده، هیچ مخالفتی ندارم که به‌خدمت گرفتن همه این رویه‌ها حتی در سراسر آمریکا هم مناسب نیست چه برسد به آسیا و اروپا. در واقع اگر در سراسر دنیا، اختلافی نباشد مایه تعجب است. بخش دیگری در سئوال شما، به‌صورت ضمنی وجود داشت که آیا چیزهای عمومی هم وجود دارد یا خیر؟ من فکر می‌کنم قطعاً وجود دارد. اینکه به‌دنبال آدم‌هایی با تطابق‌های مهارتی و فرهنگی هستیم، دنبال آدم‌های باانگیزه هستیم که بتوانند خوب ارتباط و تعامل برقرار کنند، این‌ها به گمان من جهانی هستند. اما جزییات اینکه فرآیند کار چگونه باشد، اگر قرار نباشد که برای کشورهای مختلف مثلاً ژاپن، چین، آلمان و ... متفاوت باشد، جای تعجب است. من البته در شرکتی کار می‌کنم که جهانی است و کمک می‌کنم که استخدام‌های جهانی خوبی داشته باشیم اما همان طور که گفتم اگر تفاوت‌های فرهنگی وجود نداشته باشد جای تعجب دارد و در عین حال اگر فرآیند ایده‌آل برای پیدا کردن فردی در ژاپن یا چین یا آلمان برای ملحق شدن به شرکت شما، با فرآیند ایده‌آل آن در آمریکا، به‌طور کامل متفاوت باشد آن هم جای تعجب دارد. حتماً همپوشانی‌هایی وجود دارد اما همپوشانی کامل نیست.بله، من در این مورد با شما موافقم. یکی از جنبه‌هایی از صحبت‌های شما که من واقعاً دوست دارم این است که شما در این مورد زیاد صحبت می‌کنید که همواره باید در مورد استراتژی‌ها تجدیدنظر کرد و این ایده را ترویج می‌کنید. آیا این به روش استخدام شما هم مربوط می‌شود؟قطعاً. من فکر می‌کنم ما به‌عنوان افراد یا سازمان‌ها همواره باید به این فکر کنیم که چطور می‌توانیم بهتر عمل کنیم زیرا همه ما چه منظور از ما، آدم‌ها باشد چه سازمان‌ها باشد، در سفر بهبود دادن خودمان هستیم. صادقانه بگویم که دست‌کم لازمه‌اش این است که در این مورد که چه مصالحه‌هایی (trade-off) می‌کنید و چه اهدافی دارید با خود روراست باشید و جبهه نگیرید. فکر می‌کنم سازمان‌ها همواره باید به‌دنبال بهبود خود باشند و این مربوط به همه چیز می‌شود. به‌طور خاص در مورد فرآیند استخدام، اگر به مثال گوگل برگردم، در آنجا گوگل داده‌های مربوط به فرآیند استخدامی که طی ۱۵ سال داشته‌اند را جمع‌آوری می‌کنند و به‌طور دائم آن را تصحیح می‌کنند. آنچه من توضیح می‌دهم مربوط به تجربیاتی است که در مورد فرآیند استخدام سال ۲۰۱۳ در گوگل داشتم اما این فرآیند در طی زمان تکامل می‌یابد و همچنان نیز در حال تکامل است. من فکر می‌کنم این باید در همه شرکت‌ها درست باشد. شرکت‌ها اهداف کلی خود و اهداف شرکت خود در یک سازمان خاص را تغییر می‌دهند بنابراین قطعاً باید چیزهایی که در استخدام دنبال آن هستید و همین طور شاید خود فرآیند استخدام را نیز تغییر دهید. اینکه فکر کنیم که فرآیند استخدامی که هم‌اکنون در یک شرکت داریم، کامل و بی‌عیب است ابلهانه است.منطقی به نظر می‌رسد. فکر می‌کنم خصوصاً در مورد استخدام برخی مواقع هست که به این تصور می‌رسید که بسیارخوب، الان روشش را یافته‌اید، در سراسر جهان این‌گونه است اما خوب است که از شما می‌شنویم نباید این‌طور باشد. اما اگر می‌دانید به ما بگویید که چطور می‌توان در این مورد، میزان موفقیت را اندازه‌گیری کرد؟ آیا می‌دانید که گوگل چطور این کار را انجام می‌دهد؟ یا شما چطور این کار را می‌کنید؟قطعاً. ما این کار را می‌کنیم. مانند همه شرکت‌ها ما نیز افراد را به‌‌شکل منظم ارزیابی می‌کنیم. این یک فرآیند معمول است که از عملکرد افراد بازخورد بگیریم و ببینیم چطور می‌توانیم بهبود یابیم. همین یک شاخص خوب است که ببینیم آیا فردی مطابقت خوبی داشته یا خیر. اینکه آیا افراد همچنان باقی مانده‌اند، معیار خوب دیگری است. از طرفی فرآیند استخدام به مانند یک قیف است. بنابراین می‌توانید در طی زمان، مراحل مختلف آن قیف را اندازه بگیرید. این کمک می‌کند که ببینید آیا تغییراتی که در فرآیند داده‌اید کم و بیش مؤثر بوده است یا خیر. ببینید که چند درصد از افراد مرحله خاصی از قیف را طی کرده‌اند و ببینید که بهتر یا بدتر شده است. اندازه‌گیری این تغییرات می‌تواند یک شاخص باشد. گوگل همین کار را می‌کند. مانند همه شرکت‌ها آن‌ها به‌صورت منظم تک‌تک کارمندان را ارزیابی می‌کنند. این یک شاخص خوب است و همین طور باقی ماندن افراد و تحلیل قیف از فرآیند هم شاخص‌های دیگر است.ما برنامه‌ریزی کرده بودیم که در مورد فرهنگ شرکت‌ها، رقابت‌ها و چیزهای مشابه آن خیلی بیشتر صحبت کنیم. امیدوارم بتوانیم قراری برای نیمه دوم برنامه‌‌مان بگذاریم.قطعاً. خیلی دوست دارم این کار را بکنیم.فقط یک سئوال کلی. آیا شما در مورد استخدام صحبت می‌کنید اما در حال حاضر کارتان کلاً چیز دیگری است؟ الان که در آلمان صحبت می‌کنید اگر در مورد استخدام صحبت نکنید چه‌کار می‌کنید؟طنزش این است که خودم واقعاً استخدام شده‌ام. من مدیر ارشد فنی در کیکسای هستم. ما بازی‌های متنوع زیادی می‌سازیم. مسئولیت من این است که همه این مهندسی‌های مشترک شده که برای طی کردن مراحل یک بازی بکار می‌رود را اداره کنم. کار روزانه من این است که این سازمان را اداره کنم و رهبری فنی و سازمانی آن را انجام دهم. تا چند ساعت دیگر به سانفرانسیسکو برمی‌گردم و به دفترم می‌روم و کار روزانه‌ام را پی می‌گیرم.الان در کیکسای استخدام دارید؟ نمی‌خواهید تبلیغ کنید؟بله، قطعاً. ممنونم. کیکسای همواره استخدام دارد و الان هم به اندازه همیشه استخدام می‌کند. ما حدود ۵۵۰ کارمند در جاهای مختلف دنیا داریم که حدود ۴۵۰ نفر از آن‌ها در دفاتر اصلی سانفرانسیسکو مشغول هستند. همین طور دفاتری در جاهای دیگر داریم. یک دفتر در بریتیش کلمیبیا در کانادا داریم، دفتری در بریزبن در استرالیا داریم که یکی از بازی‌های‌مان آنجا ساخته می‌شود، دفتر دیگری در پورتلند داریم که امور ترابری را آنجا انجام می‌دهیم، همین طور یک دفتر کوچک در سیاتل داریم. ما بازی‌های استراتژی بلادرنگ می‌سازیم بنابراین برای طراحی واسط کاربری، گرافیک و شبیه‌سازی سایت بازی که خیلی مهم است به دنبال افراد با تخصص front-end می‌گردیم. همین طور به دنبال مهندس‌های قوی برای سرویس‌ها و تولید سمت سرور بازی‌هایمان هم هستیم. همین طور به دنبال افرادی هستیم که تحلیل‌ کنند و زیرساخت‌های تحلیل‌ها را بسازند و دنبال افرادی برای تضمین کیفیت هستیم. من به شدت توصیه می‌کنم که اگر کسی علاقه‌مند است به بخش مشاغل وب‌سایت شرکت کیکسای بیاید و همه این مواردی که در حال حاضر به‌دنبالش هستیم را ببیند.من فقط می‌توانم شنوندگان‌مان را تشویق کنم که ویدئو‌هایی که در توضیحات این مصاحبه گذاشته‌ایم را مشاهده کنند و به صحبت‌های شما در کنفرانس‌ها بیایند و چیزهای زیادی از آن بیاموزند. خیلی ممنون که در مصاحبه شرکت کردید. همان طور که گفتیم، بخش دومی از این مصاحبه را هم امسال خواهیم داشت. اما الان از شما متشکرم و برایتان آرزوی روز خوبی دارم.خیلی ممنون که با ما بودید. خیلی خوش گذشت.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Fri, 17 Jun 2022 14:15:43 +0430</pubDate>
            </item>
                    <item>
                <title>ریزسرویس‌ها</title>
                <link>https://virgool.io/se-radio/%D8%B1%DB%8C%D8%B2%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%87%D8%A7-zcybsyy4b8h1</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۲۱۳ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت، یوهانس تونز با جیمز لوییس، معمار نرم‌افزار و مدیر شعبه انگلیس ThoughtWorks درباره ریزسرویس‌ها (microservice) صحبت می‌کند. جیمز، عضو هیأت مشاوره تکنولوژی در ThoughtWorks است که هر ۳ ماه یک‌بار، ملاقات دارند و رادار تکنولوژی ThoughtWorks را تولید می‌کنند. (رادار تکنولوژی، نام سندی است که حدوداً هر ۶ ماه یک‌بار منتشر می‌شود و در آن تغییراتی که در گرایش‌های مربوط به تکنیک‌ها، تکنولوژی‌ها، زبان‌ها و ابزارهای توسعه نرم‌افزار رخ داده به شکل گرافیکی و توضیحات موجز مطرح می‌شود- مترجم). علاقه جیمز، تولید نرم‌افزار از طریق سرویس‌های کوچک همکار است. جیمز، در دهه ۹۰ اخترفیزیک خوانده است اما از برنامه‌نویسی به زبان فرترن خسته شد! او بعد از ۱۵ سال کارهای مدیریت پایگاه داده و بعدها طراحی و معماری نرم‌افزار، اعتقاد دارد که نوشتن نرم‌افزار، ساده‌ترین بخش مسأله است و بیشتر کار، مربوط به درست فکر کردن افراد است. در این مصاحبه یوهانز و جیمز درباره محبوبیت اخیر ریزسرویس‌ها، سبک‌های معماری، استقرار، اندازه، تصمیم‌های فنی و قراردادهای مبتنی بر مشتری (consumer-driven contracts)، صحبت می‌کنند. آن‌ها همچنین ریزسرویس‌ها را با معماری‌ سرویس‌گرا (service-oriented) مقایسه می‌کنند و بحث را با صحبت در مورد چهره‌های شاخص در اجتماع ریزسرویس‌ و  اینکه بر دوش بزرگان سواریم به پایان می‌رسانند. جیمز، به برنامه خوش آمدی!خیلی ممنون!آیا چیزی هست که بخواهی به بیوگرافی‌ات اضافه کنی؟فکر نکنم. فکر کنم خوب پوشش دادید. من حدود ۸ سال و نیم است که این کار را انجام می‌دهم. من تغییرات زیادی در صنعت نرم‌افزار را دیده‌ام و فکر می‌کنم تغییرات خیلی خیلی سریع است و فکر می‌کنم آنچه امروز می‌خواهیم در مورد آن صحبت کنیم، یکی از آن آخرین تغییرها باشد.بیا در مورد موضوع عمیق شویم. ما می‌خواهیم در مورد ریزسرویس‌ها (microservice) صحبت کنیم. ممکن است با این شروع کنید که ریزسرویس چیست؟بله، البته. ریزسرویس به اعتقاد من، یک برنامه کوچک است که می‌تواند مستقلاً مستقر (deploy) شود، مستقلاً مقیاس بپذیرد، مستقلاً تست شود و یک مسئولیت منفرد دارد. این مسئولیت منفرد، چند وجه دارد. یکی از این نظر که یک علت منفرد برای تغییرکردن داشته باشد و هم یک علت منفرد برای جایگزین شدن داشته باشد؛ این ضروری است. اما وجوه دیگر مسئولیت منفرد این است که فقط یک کار را انجام دهد و به سادگی برای کسانی که آن را توسعه می‌دهند قابل فهم باشد.چنین چیز منفردی، چه می‌تواند باشد؟سئوال خوبی است. یک مثال از چیز منفرد می‌تواند یک مسئولیت منفرد در ارتباط با نیازمندی‌های عملکردی یا غیرعملکردی یا نیازمندی‌های فراعملکردی (cross-functional) باشد. یک مثال می‌تواند یک پردازشگر صفی باشد؛ چیزی که یک پیغام را از صف می‌خواند، بر روی آن یک تکه پردازش کوچک مرتبط با منطق کسب‌وکار (business logic) انجام می‌دهد و آن را منتقل می‌کند. می‌تواند یک کار غیرعملکردی یا تقاطعی باشد و یا می‌تواند چیزی باشد که مسئولیتش این باشد که در مورد منبعی (resource) خدمت بدهد و نمایشی از یک منبع باشد. مثلاً (نمایشی از) کاربر، مقاله، ریسک بیمه، ... . چیزی که خیلی خیلی مشخص و کوچک باشد و به تنهایی کار منفردی را انجام دهد.من این احساس را دارم که ریزسرویس‌ها، اخیراً خیلی محبوب شده‌اند. شما در مورد آن صحبت کرده‌اید، دیگران در مورد آن صحبت کرده‌اند و ... . چرا این‌طور شده است؟سئوال خوبی است که چرا ریزسرویس‌ها، به ناگهان محبوب شده‌اند. حدود ۴ سال پیش، یک کارگاه بود که افراد مختلفی از اجتماع‌‌های مختلف صنعت نرم‌افزار شرکت داشتند، به‌عنوان مثال برخی افراد از اجتماع طراحی مبتنی بر حوزه (domain-driven design)، برخی از اجتماع RESTful، برخی از اجتماع تبادلات پیغام (messaging) و ... . من در این کارگاه شرکت کردم. در آنجا برایم مشخص شد که سئوال‌هایی درباره اندازه برنامه‌ها هستند که زیاد تکرار می‌شوند. به‌عنوان مثال اینکه فلان برنامه ما طی ۲ سال و نیم یا ۵ سال یا ۱۰ سال آن‌چنان بزرگ شده است که دیگر نمی‌توانیم آن را نگهداری کنیم؛ انجام هر تغییر عملکردی در آن سخت شده است یا اینکه ما می‌خواهیم بتوانیم این برنامه را بر روی فضای ابری (cloud) مستقر کنیم و به‌صورت نرم‌افزار به‌عنوان خدمت (software as a service) عرضه کنیم، اما در حال حاضر ممکن نیست.در نتیجه آن، این ایده مطرح می‌شد که برنامه‌ها به مؤلفه‌های کوچک همکار خرد شوند که در پروسس‌های خود اجرا شوند و با همدیگر کار کنند و بتوانند جداگانه نگهداری شده و جداگانه مقیاس بپذیرند. بنابراین مجموعه‌ای از اجتماع‌هایی که بیشتر تجربی بودند شکل گرفت. تعدادی از آنها در لندن بودند و برپایه برخی افراد شکل گرفتند. مثلاً فکر می‌کنم خیلی‌ها با بروس استنلی کار کرده باشند (ممکن است اسم به اشتباه تشخیص داده شده باشد - مترجم) و یا دن نورث که در مورد معماری‌های با مؤلفه‌های قابل‌جایگزینی صحبت می‌کند و روی ایده جایگزین‌پذیری، تأکید دارد. فرد جورج هم چند سالی است که در مورد ریزسرویس‌ها صحبت می‌کند. این‌طور دیده می‌شود که بیشتر در لندن، روی آن کار می‌شود. در همین حین، Netflix را دارید که در ساحل غربی آمریکا، در مورد آنچه در موردش صحبت می‌کنیم یعنی معماری‌های سرویس‌گرای ریزدانه، شراکت دارد. آنها هم از همین اصطلاح ریزسرویس استفاده می‌کنند. تعدادی از این اجتماع‌های مختلف بوده است که در طی زمان رشد کرده‌اند. بنابراین ارائه این رهیافت برای تولید نرم‌افزار، دوام داشته است. اگر به شرکت‌هایی با ابعاد Netflix نگاه کنید، چنین رهیافتی تقریباً ضرورت داشت. همان طور که آدریان کاکرافت می‌گوید، علت این‌ که سیستم‌ها را این‌گونه می‌سازند این است که می‌خواهند بتوانند تا جایی که ممکن است سریع باشند و تغییرات را سریع اعمال کنند.به سئوال شما برگردیم که چرا این‌قدر محبوب است. من فکر می‌کنم سازمان‌های زیادی هستند که در ۵ سال گذشته، به حد مرگ رسیده‌اند. آنها فهمیده‌اند که برای اینکه بتوانند مقیاس‌پذیر باشند و بتوانند در تحویل محصول عملیاتی، کاراتر باشند و بتوانند مزایای چیزهایی از قبیل تحویل مستمر (continuous delivery) را داشته باشند به برخی رهیافت‌ها نیاز دارند که به آن‌ها این اجازه را بدهد که در بُعدهای مختلف به‌صورت مستقل، بزرگ شوند. بنابراین فکر می‌کنم زمانش رسیده بود که ایده‌هایی مانند ریزسرویس‌ها توفیق یابند زیرا شرکت‌های زیادی با مشکل یکسانی روبرو شده بودند.شما چیز جالبی گفتید که افراد در این موارد، برنامه‌های بزرگ یکپارچه‌ای (monolithic) داشته‌اند که آن‌ها را به ریزسرویس‌هایی خرد کردند. آیا شکل معمول بکارگیری ریزسرویس‌ها همین است؟سئوال خوبی است و چیزی است که در واقع با آن درگیر هستم. اگر به بطن سئوال توجه کنیم در واقع این است که آیا با ریزسرویس‌ها آغاز می‌کنید یا اینکه آن‌ها را بعداً می‌سازید؟ به‌صورت تجربی، غالب سازمان‌ها با یک چیز بزرگ شروع کردند و در طول زمان آن چیز بزرگ را شکستند. اکثر سازمان‌ها چیزی که من به آنها پیاده‌سازی‌ به سبک ریزسرویس‌ها می‌گویم را بعداً ساختند. مثلاً Netflix [این‌طور است]، مثال دیرینه آن، احتمالاً Amazon است. آن‌ها با یک پایگاه داده بزرگ شروع کردند و بعد به سمت معماری سرویس‌گرا کشیده شدند. Netflix هم موقعیت کاملاً یکسانی داشت و با یک سیستم با ساختار کاملاً بزرگ یکپارچه آغاز کرد و با حرکت به سمت این نوع معماری سرویس‌گرای ریزدانه بود که خرد شد.آیا مثالی دارید که بتوانید کمی بیشتر صحبت کنید و روشن‌تر کنید که این خرد کردن و رسیدن به این معماری ریزسرویس‌ها چطور رخ می‌دهد؟قطعاً. من مشاور خوبی هستم. ۳ سال و نیم پیش من مشتریانی از صنعت بیمه داشتم که درگیر کار با بانک‌ها شدم. آنها این شرایط را داشتند که یک برنامه خیلی بزرگ با سبک چند لایه‌ای مرسوم را نوشته بودند که در آن یک پایگاه داده بزرگ با کلی منطق کاری داشتند، محیط دات‌نت بود و یک سرویس دسترسی به داده‌ها داشتند که بر روی آن، یک برنامه بزرگ دیگری داشتند که کلی منطق کاری در آن نوشته شده بود. مشکلی که داشتند این بود که در این برنامه بزرگ که بر روی لایه سرویس نوشته شده بود، محصولات مختلفی را توسعه داده بودند. آن‌ها انواع بیمه‌ها را می‌فروختند. هر کدام از آنها چرخه تغییرات خودش را داشت. برخی از آنها بالغ‌تر و برخی نابالغ‌تر بودند و همچنان که سازمان رشد می‌کرد باید جداگانه بر روی این محصولات مختلف، سرمایه‌گذاری می‌کردند. متأسفانه از آنجایی که یک برنامه خیلی بزرگ داشتند، همه چیز به‌هم گره خورده بود، اگر می‌خواستند تغییراتی بر روی محصولات بیمه‌های درمانی داشته باشند، باید برای [اتمام] چرخه تغییرات مربوط به محصولات بیمه‌های خودرو صبر می‌کردند و یا اگر می‌خواستند مقیاس محصولات بیمه‌های خودرو را بزرگ کنند  -زیرا عموماً بیمه‌های خودرو مثلاً در مقایسه با بیمه‌های عمر ارزش خیلی بیشتری دارند- مقیاس دیگر محصولات هم باید در اندازه بیمه‌های خودرو بزرگ می‌شدند. آن‌ها انعطاف زیادی نداشتند و همچنین گرفتار وضعیتی شده بودند که برای اینکه تیم‌های توسعه‌دهنده‌ای که روی این برنامه کار می‌کردند بتوانند بدون ایجاد مزاحمت برای یکدیگر کار کنند، استراتژی‌های بسیار پیچیده و عجیب و غریبی برای انشعاب و ادغام (branch &amp; merge) را به کار گرفته بودند زیرا هرگاه تغییری می‌دادید بر روی نواحی مختلفی تأثیر می‌گذاشت. آن‌ها در شرایط سختی قرار داشتند و طی ۳ سال گذشته در جهت خرد کردن این برنامه به محصولات حرکت کردند. این یک مثال از نحوه‌ای است که ممکن است خرد کنید.یعنی آنها با جدا کردن یکی از بخش‌ها آغاز کردند؟ طوری که آن بخش همچنان با برنامه یکپارچه مراوده داشته باشد؟در این مورد خیر، این کار را نکردند. به‌جای آن محصولات جدید را جداگانه خارج از سایت تولید کردند. در واقع به سمت بازسازی آن (refactor) نرفتند بلکه مثلاً بخش بیمه درمانی را به‌صورت یک ریزسرویس مجزا، توسعه دادند. در واقع داخلش یک پیاده‌سازیِ SQL ،OR و REST در محیط دات نت داشت که از الگوی مجزاسازی مسئولیت‌های فرمان از پرس‌ و جو (command and query responsibility segregation) استفاده می‌کرد.مختصراً می‌گویید که این (الگوی مجزاسازی مسئولیت‌های فرمان از پرس و جو) چه معنی می‌دهد؟مختصراً می‌گویم باشه :-) در آن مورد، ایده مربوط به جدا کردن خواندن از نوشتن بود. پیاده‌سازی‌های دسترسی به داده‌ها و ذخیره داده‌ها به‌طور مجزا از هم از طریق پرس‌وجوها و فرامین انجام می‌شود. وقتی فرامینی اجرا می‌کردید، رخدادهایی تولید می‌شدند که مدل مربوط به خواندن را پر می‌کردند و بعد برنامه‌تان از آن مدل می‌خواند. در جایی می‌نوشتید و از جای دیگری می‌خواندید و مؤلفه‌هایی که این کارها را می‌کردند به‌صورت مجزا توسعه داده شدند و به‌صورت سرویس‌های مجزا به‌عنوان ریزسرویس‌ها اجرا می‌شدند. من در گروهی بودم که اسم افراد را به خاطر نمی‌آورم اما یک ارائه خوب، در مورد نحوه‌‌ای که به این رهیافت رسیدند از یکی از آن معمارها در کنفرانس QCon مربوط به مارچ ۲۰۱۴ لندن وجود دارد. آن‌ها برنامه را با تفکیک به صفحات خرد کردند. آن‌ها زیرسرویسی داشتند که مسئول بخش‌هایی از یک سایت منفرد بود.بیایید کمی در مورد این صحبت کنیم که از لحاظ فنی چطوری ریزسرویس‌ها را می‌سازید. مثلاً اگر بخواهم ریزسرویسی برای اعتبارسنجی کاربر، بنویسم از چه زبانی استفاده می‌کنم؟ بر طبق چه استانداردهایی می‌نویسم؟یکی از راهنماها و اصول درباره آن این است که مورد به مورد، [بسته به خودش] کار را تنظیم کنید. به‌جای اینکه یک زبان خاص را انتخاب کنید یا یک ذخیره‌‌گاه داده خاص برای همه بسته محصولات‌تان داشته باشید، این انعطاف را دارید که بر اساس اطلاعات و ابزارها تصمیماتی آگاهانه بگیرید. یک انتخاب‌ خاص که [فقط همان] صحیح باشد وجود ندارد.مثلاً در مورد سرویس کاربران که شما صحبت کردید می‌توانید آن را به سادگی در سی‌شارپ یا جاوا و یا هر نوع زبان مبتنی بر مدل دیگری بسازید. اینجا من خطر دفاع کردن در مقابل این همه افرادی که این روزها عاشق جاوااسکریپت هستند را می‌پذیرم :-) من شخصاً طرفدار آن نیستم، اگر می‌خواهید بدانید می‌توانید علتش را از مارتین فاولر بپرسید! اما تقریباً با هر زبانی می‌شود این کار را کرد. مسأله مهم این است که به‌جای اینکه به‌دنبال استفاده از بسته‌های سنگین اضافی باشید، بسته را سبک نگاه دارید. این مطلب شامل این می‌شود که به‌جای اینکه [سرویس‌ها را] بر روی محفظه‌های برنامه (application container) مثلاً Tomcat و دیگر محفظه‌ها مستقر کنید به این فکر کنید که آیا می‌توانید از ابزارهای سبک‌تر مثلاً Embedded Tomcat و Embedded Jetty استفاده کنید. این در مورد جاوا بود. دات نت هم به تنهایی مکان جالبی است زیرا هر آنچه به‌طور سنتی در فضای دات‌نت انجام داده‌ایم بر روی IIS مستقر می‌شود. همه برنامه‌هایی که از محیط‌های مختلف می‌آیند این‌طور هستند. اما حتی در دات‌نت هم، این جنبش وجود دارد که آموخته‌های اجتماع‌های لینوکس و جاوا را به‌کار بگیرند و از سیستم‌های تعبیه شده استفاده کنند. بنابراین در فضای دات‌نت هم راه‌های جایگزینی وجود دارد که در کنار برنامه‌هایتان از ابزارهای سبک‌تر استفاده کنید.اما وقتی که به لایه ارتباطات نگاه کنیم، همه چیز به فرم HTTP و REST است ...من خودم اقرار دارم که طرفدار سبک معماری REST هستم. فکر می‌کنم به این طریق به خیلی از مشکلاتی که طی چندین دهه اخیر در زمینه یکپارچه‌سازی (integration) شناسایی کرده‌ایم، چیره شدیم.به‌عنوان مثال؟به‌عنوان مثال، نسخه‌دهی‌هایی که در ارتباط با مجموعه نتایج خروجی باید داشته باشیم آسان‌تر قابل انجام خواهد بود. البته باید گفت که در ریزسرویس‌ها چنین چیزی نداریم که سرویس‌ها حتماً باید از نوع RESTful باشند و همواره باید از REST استفاده کنید. آنچه در حالت عادی به افراد می‌گویم این است که باید برای کار ابزار درستش را انتخاب کنید. اگر ابزار درست کار شما این است که تبادل پیغام را از طریق یک گذرگاه داشته باشید چراکه مقدار زیادی نیازمندی‌های فراعملکردی (cross-functional) حول آن دارید، همین کار را باید انجام دهید. من و مارتین این‌طور می‌گوییم که در عوض اینکه بر روی یک گذرگاه سرویس معظم (enterprise service bus) تمرکز کنید که سرویس‌ها خارج از گذرگاه آویخته شده باشند به‌جای آن بر روی ‌نقطه‌های انتهایی هوشمند و لوله‌های خِنگ (smart endpoints and dumb pipes) تمرکز کنید. این روش بیشتر به این صورت است که این‌ ریزسرویس‌ها، منطق کار‌ها (business logic) را در خود دارند و به‌وسیله پروتکل اصلی برنامه با هم صحبت یا تعامل می‌کنند اما در خود ریزسرویس‌ها این‌طور نیست.فکر می‌کنم این نقطه‌های انتهایی هوشمند و لوله‌های خِنگ، به مدل Unix ارجاع داشته باشد.ممکن است همین طور باشد. فکر می‌کنم به این دلیل این نام را انتخاب کردیم که این عنوان در مقابل مدل گذرگاه سرویس معظم اختیار می‌شود. آن طور که من به خاطر دارم، همواره در ThoughtWorks بی‌اعتمادی زیادی نسبت به یکپارچه‌سازی [به این نوع سبک گذرگاه سرویس‌ معظم] رواج داشته است؛ این چیزها معمولاً وعده می‌دهند که همه‌ مشکلات شما را حل می‌کنند. به شخصه، پیاده‌سازی خوبی از گروهی از سرویس‌ها یا معماری ندیده‌ام که همه چیز حول یک گذرگاه سرویس مرکزی معظم آویخته شده باشند. من ندیده‌ام که این‌جور چیزها موفق شده باشد. به عقیده من، این‌جور مدل مرکزی‌سازی، خوب نیست. اینکه منطق‌های خود را در یک جا و بالقوه در یک گذرگاه سرویس معظمی قرار ‌دهید که همه چیزها از مسیریابی و انتقال داده‌ها و همه این‌جور کارها را -که برای مراوده بین برنامه‌ها نیاز است- انجام دهد. این روش‌ها مشکل شما را حل نمی‌کند و روش درستی نیست. چند سال پیش در کنفرانس QCon، یک ارائه خوب از جیم وبر و مارتین فاولر با این عنوان بود که «آیا گذرگاه من در اینجا بزرگ به نظر می‌رسد؟» در آنجا جیم در مورد ایده داشتن یک گذرگاه پیچ ‌در پیچ شگفت‌آور صحبت می‌کند. به عقیده او، این گذرگاه‌های معظم فقط کمک می‌کنند که نمودارهای زیبایی داشته باشیم چراکه وقتی به نمودارهای معماری‌‌های معظم‌تان نگاه می‌کنید، متوجه یک سری خطوط متقاطع زشت می‌شوید و تمایل دارید که یک جعبه در وسط قرار دهید تا به ناگاه همه آن خطوط حذف شود. به‌عنوان یک معمار، این را دوست دارید. اما در واقع همه آن خطوط هنوز وجود دارند، فقط داخل آن جعبه قرار گرفته‌اند؛ جعبه پیچ در پیچ شده است.اگر مسیریابی توسط یک گذرگاه سرویس معظم انجام نمی‌شود، پس چه کسی آن را انجام می‌دهد؟ آیا لازم است خودم مسیریابی کنم؟بله، قطعاً لازمست نحوه ارتباط برقرار کردن بین برنامه‌ها را بدانید. و اگر سرویس‌های بیشتری بسازید مسائل مربوط به یکپارچه کردن (integration) بیشتری خواهید داشت. اگر در گذشته با دو سه تا سیستم خارجی، مسائل یکپارچه‌سازی کمتری احتمال داشتند، الان با یک سیستم گسترش‌یافته، مسائل بیشتری در این ارتباط رخ خواهد داد و باید در مورد نحوه ارتباط برقرار کردن بین برنامه‌ها بیشتر بدانید. با این حال روش‌های مختلفی برای این کار وجود دارد. چیزهایی از قبیل تأمین منابع پیشرفته (advanced sourcing) یا برنامه‌های رخدادگرا. مثلاً اگر از چیزهایی از قبیل HTTP و ارائه نتایج (در پکت‌های HTTP) استفاده کنید، به شما اجازه می‌دهد که ناهمبسته (decouple) شوید و به‌وضوح این‌طور نیست که همواره ارتباطاتِ از نوع نقطه به نقطه ببینید.آیا شبیه این نیست که پیچیدگی و نحوه با هم کارکردن‌ها را از یک برنامه یکپارچه به لایه شبکه آورده‌ایم؟جواب مختصرش این است که بله، و در واقع وقتی با افراد در این مورد صحبت می‌کنم یکی از نظراتی که دریافت می‌کنم همین است. دوباره از مارتین فاولر نقل می‌کنم که: «آیا با این کار داریم پیچیدگی‌های تصادفی -پیچیدگی تصادفی، به همان معنایی که فرد بروکس تعریف کرده- را از داخل معماری و از کدهای پیوند‌دهنده (glue code) که کامپوننت‌ها و ماژول‌های داخل برنامه هستند به زیرساخت‌ها منتقل می‌کنیم؟»احتمالاً الان زمان خوبی برای [این انتقال] است زیرا الان روش‌های خیلی بیشتری برای مدیریت این نوع از پیچیدگی‌ها را بدست آورده‌ایم. اگر در برنامه‌نویسی زیرساخت‌ها نظر کنید، خودکارسازی زیرساخت‌ها و حرکت به سمت ابرها (cloud) و ... را داشته‌ایم که امروزه در همه‌جا حاضرند. بنابراین برای این کارها و اینکه بفهمیم چه تعداد برنامه‌ داریم و چطور با همدیگر صحبت می‌کنند ابزارهای بهتری به‌دست آورده‌ایم.یکی از چیزهایی که از گوش کردن به یکی از صحبت‌هایتان متوجه شدم این است که ریزسرویس‌ها باید بدون محفظه (container) و به‌صورت مستقل قابل استقرار باشند. این به چه معناست؟ خصوصاً در ارتباط با خودکارسازی زیرساخت‌ها چه معنی می‌دهد؟بله، در گذشته من این را گفته‌ام. اغلب این چیزها مفصل‌تر از آن است که بتوانم ظرف یک صحبت ۵ دقیقه‌ای توضیح دهم. من این‌طور فکر می‌کنم که چیزهایی که نیاز دارید مستقلاً مستقر شوند را باید بتوانید مستقلاً مستقر کنید. به دلایل مختلفی [ممکن است این را نیاز داشته باشید]. مثلاً آیا نیاز دارید که آنها را به دلایل میزان دسترسی یا توان عملیاتی یا تأخیر، به‌صورت مستقل مقیاس‌دهی کنید؟ اگر چنین نیازمندی وجود دارد باید بتوانید آن‌ها را مستقلاً مستقر کنید. اگرچه من سازمان‌هایی را می‌شناسم که گروه‌هایی از این چیزها را با هم مستقر می‌کنند بنابراین شاید ۳ یا ۴ چیز باشند که واقعاً نیاز دارید که چرخه تغییرات آن‌ها را مشترک کنید.مانند سرویس کاربران یا اعتبارسنجی ...بله، بالقوه اینها می‌تواند باشد. در مورد مثال بیمه که من صحبت کردم، یک سرویس حقوق دسترسی وجود داشت که به‌عنوان بخشی از ریلیز آن محصول عرضه می‌شد. از جنبه تأثیرات این‌ها بر روی تیم پشتیبانی و مسائلی از قبیل تولید زیرساخت‌ها، باید بتوانیم نرم‌افزارها را بهتر توسعه دهیم. مثلاً ایده‌ای تحویل مستمر (continuous delivery) را داریم که جز هامبل و دیوید فارلی در کتابشان توضیح داده‌اند و در مورد این است که چطور خط لوله‌ها را کنار هم بسازیم و چگونه کل این مسیر انتقال نرم‌افزار از کار توسعه تا محیط عملیاتی را انجام دهیم. همچنین در خیلی موارد شاهد یک تغییر نگرش هستیم که به‌جای میانگین زمان رسیدن به خرابی (mean time to failure) به میانگین زمان ترمیم یافتن (mean time to recovery) توجه می‌شود.منظور شما از میانگین زمان ترمیم یافتن چیست؟یک مثال خیلی جالب از آن، روشی است که Netflix، از قطع‌کننده مدار (circuit breaker) در محصولاتش استفاده می‌کند. مدتی است که الگوی قطع‌کننده مدار، جایگاه پیدا کرده است. این الگو ابتدا توسط مایکل نایگارد اختراع و ترویج شد. او این الگو را در کتاب خودش، کتاب «منتشرش کن!» بیان کرد. این کتاب خارق‌العاده و یکی از بهترین کتاب‌ها در زمینه عملیات (operation) است. آنچه قطع‌کننده مدار در نرم‌افزار انجام می‌دهد این است که هنگام صحبت با سیستم‌های خارجی سطحی از ایمنی را فراهم می‌آورد. من در تجربه شغلی‌ام، قطع‌کننده جریان را در حالتی پیاده‌سازی کرده‌ام که سیستم‌های پایین‌دستی کُند شوند و یا از دسترس بروند. همه می‌دانیم که بین کُند شدن و اصلاً نبودن، تفاوت وجود دارد. این تکه از نرم‌افزار که قطع‌کننده مدار نام دارد می‌تواند در این حالت‌ها عمل کرده و مدار را باز کند و سیستم‌های پایین‌دست از آن پس، غیرقابل دسترس خواهند بود.بنا به نوع پیاده‌سازی، می‌توان انواع ایمنی‌های مختلفی داشت مثلاً یک راهنما می‌تواند حجم حوض نخ‌ها (thread pool) باشد (اشاره به نوعی از پیاده‌سازی این الگو که در آن، هر فراخوانی راه دور در یک نخ (thread) که از حوض نخ‌ها گرفته می‌شود، انجام می‌شود و اگر تعداد نخ‌های مشغول از سقف مشخصی بالاتر رود، قطع‌کننده مدار عمل کرده و تا زمان رفع مشکل، اصطلاحاً مدار را باز کرده و خودش فراخوانی‌ها را با پاسخ پیش‌فرض یا پاسخ خطا جواب می‌دهد - مترجم).اگر درست متوجه شده باشم مثلاً یک پیاده‌سازی از قطع‌کننده جریان مانند gmail است که وقتی قطع باشم، بعد از ۵ ثانیه تلاش می‌کند، بعد به ۱۰ ثانیه افزایش می‌یابد، بعد به ۲۰ ثانیه افزایش می‌یابد و ... .بله، دقیقاً. این یک مثال عالی است. بعد از آن وقتی در محیط عملیاتی کارهایی از قبیل مانیتور کردن و گزارش‌گیری بر روی این موارد را انجام می‌دهید، می‌توانید ببینید که در هر لحظه از زمان دقیقاً چه اتفاقی برای سیستم‌تان افتاده است. البته اگر مثلاً ۱۰ سرویس داشته باشید، این مسئله خیلی مهم‌تر خواهد بود، چون اگر سرعت پاسخ‌دهی کاهش یابد، پیدا کردن منشأ آن دشوار خواهد بود. کارهایی از قبیل بکارگیری الگوی قطع‌کننده مدار و سپس گزارش دادن بر روی آن به ما این اجازه را می‌دهد که به محض وقوع مشکلات توجه‌مان بر روی آن‌ها جلب شود و در سریعترین زمان ممکن آن‌ها را برطرف کنیم. این فکر آغاز شده که [کاهش دادن] میانگین زمان ترمیم یافتن از طریق راه‌اندازی مجدد سرویس‌ها یا با توازن برقرار کردن بین ظرف‌ها یا ایجاد ظرف‌های جدید یا هر روش ممکن دیگری، اهمیت خیلی بیشتری دارد. فکر می‌کنم احتمالاً محبوب‌ترین پیاده‌سازی که در مورد آن وجود دارد، Hystrix نام دارد که آن هم از Netflix است. Netflix بیش از ۶۰۰ سرویس مستقل عملیاتی دارد. وقتی این منظره را نگاه می‌کنید عملکردها پیچیده می‌شود و نیاز به چیزی دارید که در شناسایی مشکلات کمک‌تان کند و کار را برای افرادی که روی این سیستم‌ها کار می‌کنند راحت‌تر کند.شاید بهتر باشد کمی بحث را عوض کنیم. بر اساس چیزی که شما گفتید؛ در زمانی که چند صد سرویس داریم، [هرکدام از] این سرویس‌ها چقدر بزرگ هستند؟ ریزسرویس‌ها چقدر بزرگ هستند؟من از محدوده چند صد خط کد تا چند هزار خط کد را دیده‌ام.اما قطعاً یک میلیون نیست!قطعاً یک میلیون نیست. راهنمایی که در این مورد وجود دارد و خود من هم به آن فکر می‌کنم این است که آیا [یک ریزسرویس] یک کار و تنها یک کار را انجام می‌دهد؟ سخت است که تصور کنیم که چیزی در حد چند میلیون خط کد یک کار و فقط یک کار انجام دهد! مگر آنکه کارش فقط این باشد که یک میلیون خط کد باشد که هرکدام خودشان را پرینت کنند، در آن صورت ممکن است :-) بنابراین در ارتباط با اندازه آن‌ها، باید قابل فهم بوده و تنها یک دلیل برای تغییر آن‌ها وجود داشته باشد و بیش از چند هزار خط کد نباشند. با در نظر داشتن این مسأله تعداد آن‌ها اهمیت می‌یابد. احتمالاً اهمیت بیشتری دارد که به این فکر کنید که چه تعداد از آن‌ها را به‌صورت عملیاتی می‌توانید پشتیبانی کنید تا اینکه به این فکر کنید که آن‌ها واقعاً چقدر کوچک هستند. زیرا اگر پشتیبانی عملیاتی شما کاملاً نابالغ باشد بهتر است که تعداد کمتری از آنها که اندازه‌های بزرگتری دارند، داشته باشید؛ منظور بالغ بودن از این لحاظ است که یک دکمه داشته باشید که کاملاً خودکار سیستم را مستقر عملیاتی کند، اینکه تیم‌های عملیاتی داشته باشید، دانش و مهارت‌های لازم برای کار با مشتری و چیزهایی از این قبیل را داشته باشید. از این نظر، بهتر است که بر روی تعداد سرویس‌ها تمرکز کنید تا بر روی اندازه هرکدام از آن‌ها.شما خیلی در مورد مسئولیت‌های منفرد (Single Responsibility) صحبت کرده‌اید و به طراحی مبتنی بر حوزه (Domain Driven Design) اشاره کرده‌اید. آیا ریزسرویس‌ها، نوعی طراحی مبتنی بر حوزه در لایه سرویس‌ها هستند؟اگر به صحبت‌هایی که از من در اینترنت هست گوش کنید، می‌بینید که من همواره کلامم را به این ختم می‌کنم که ما بر روی دوش بزرگان ایستاده‌ایم. (مَثَلی است که خصوصاً پس از آنکه اسحاق نیوتن در یکی از نامه‌هایش به کار برد مرسوم شد و به این معناست که ایده‌های جدید مبتنی بر دانش‌ و ایده‌های قبلی که گذشتگان مطرح کرده‌اند، شکل می‌گیرد- مترجم). به نظر من ریزسرویس‌ها، گردآوری از چندین مجموعه رویه‌های برتر از چندین اجتماع مختلف است. از این میان، چیزهای خوبی از اجتماع طراحی مبتنی بر حوزه هم گردآوری شده است مانند طراحی استراتژیک (strategic design)، حیطه‌های مرزبندی شده (bounded context)، زیرحوزه‌ها (sub-domain) و اینکه چطور یک حوزه بزرگ را به زیرحوزه‌ها تفکیک کنید و ... . همین طور مزیت‌هایی از رویه‌های برتر مرتبط با کارهای عملیاتی و خودکارسازی آن‌ها آورده شده است؛ این موارد از اجتماع‌ DevOps و برنامه‌نویسی زیرساخت‌ها، آورده شده است. همین طور مواردی از اجتماع ابری (cloud) و اجتماع‌های یکپارچه‌سازی، گردآوری شده است؛ از اجتماع افرادی‌ که با پیغام‌ها و سرویس‌های RESTful کار می‌کنند، آن‌هایی که خیلی سخت کار می‌کنند تا افراد آگاه شوند که می‌توانند مسائل یکپارچه‌سازی را با همین ابزارهای رایگان موجود در وب، انجام دهند و نیازی به هزینه و سرمایه‌گذاری بر روی آن ندارند. همه این ایده‌های مختلف، در یکجا جمع شده است.از اجتماع طراحی مبتنی بر مدل (domain driven design) هم ایده‌هایی گرفته شده است. من گفتم که ریزسرویس‌ها به‌صورت مجزا تولید می‌شوند اما اگر بخواهم کمی از گفته‌ام عقب نشینی کنم باید بگویم به‌عقیده من روشی که بتوانید یک معماری مؤثر داشته باشید این است که آن معماری مبتنی بر منطق منطق کسب‌وکار (business logic) باشد و این باید یک کار بالا به پایین باشد. [به این ترتیب که] شما متوجه می‌شوید که کسب‌وکار چیست، که دورنمای کسب‌وکار چیست، که فرآیندهای مرتبط با کسب‌وکار چیست و [آنگاه] مقصود محصول نرم‌افزاری را نشأت‌گرفته از آن‌ها را می‌یابید؛ و به‌عقیده من فهم اینکه زمینه کسب‌وکار و مدل‌های کسب‌وکار چیست همان قلب طراحی مبتنی بر مدل است.یکی از همکارانم در کلراید، نظر خیلی فنی خوبی دارد. ایده‌اش این است که معماری کسب‌وکار باید همریخت (isomorphism) باشد. به این صورت که اگر به طراحی‌های موجود در معماری‌تان نگاه کنید و از طرف دیگر به مفاهیم کسب‌وکارتان نگاه کنید باید خیلی شبیه به هم باشند. باید بتوانید به کسب‌وکارتان نگاه کنید و معماری‌تان را ببینید و به معماری‌تان نگاه کنید و مفاهیم کسب‌وکارتان را ببینید. چه یک متخصص فن‌آوری باشید و چه فردی باشید که در کسب‌وکاری مشغول است، در هر دو حالت، باید متوجه شوید که چه کاری دارد انجام می‌شود.یک نسخه تشدیدشده از این ایده وجود دارد که چالشی‌تر و بحث‌برانگیزتر است و آن در این ارتباط است که اصلاً نباید ایده‌ای داشته باشیم و همه چیز باید در کسب‌وکار گفته شود که من نمی‌خواهم به‌سراغش بروم که ممکن است بحثش یک ساعت به درازا بکشد.به‌ خاطر دارم که شما در مورد چیزی مانند همسایه یک ریزسرویس صحبت کردید. کنجکاوم بدانم آیا این راهی برای گروه کردن آن‌هاست؟همسایه؟!شما چیزی شبیه به این گفتید که اگر می‌خواهید ریزسرویس‌ها را با هم گروه کنید باید آنها را حول کسب‌وکارها یا حول نیازمندی‌های غیرعملکردی با هم گروه کنید و این را همسایه ریزسرویس نامیدید.آهان، شاید یک لغت جدید ابداع کرده باشم! بله، همین طور فکر می‌کنم. ما به‌صورت داخلی خیلی در این مورد صحبت کرده‌ایم. این هم اصطلاحی است که برپایه ایده‌های همکارانم درست کرده‌ام یعنی همان طور که گفتم ما بر روی دوش بزرگان ایستاده‌ایم. این ایده به این صورت است که وقتی سیستم‌تان را طراحی می‌کنید به‌جای آنکه شبیه طراحی یک ساختمان بر اساس یک طرح اولیه باشد بیشتر مانند طراحی یک شهر است. بیشتر در ارتباط با ناحیه‌های یک شهر است. در یک شهر، نواحی مختلف صنعتی، مسکونی، تجاری و ... وجود دارند. [در سیستم نرم‌افزاری] اتصال بین این نواحی، بر اساس پروتکل‌های حوزه برنامه انجام می‌شود. این‌ها [حُکمِ] امکانات زیرساخت را دارند یعنی همه [نواحی] از امکانات زیرساخت خطوط آب استفاده می‌کنند، همگی از امکانات برق و چراغ برق‌ استفاده می‌کنند و ... . بنابراین رمز کار این است که چطور ناحیه‌بندی کنیم و نقشه نواحی چطور تهیه شود. من برای این کار روش‌های سبک وزن ‌تر را می‌پسندم. به این ترتیب که ابتدا فرآیندهای کسب‌وکار را بشناسید و سپس از تکنیک‌های سبک استفاده کنید مثلاً اینکه از تخته وایت‌برد یا کارت‌های ایندکس و ترکیب این ابزارها استفاده کنید. اما بله، فهم اینکه این گروه‌ها کدام هستند بسیار اهمیت دارد و باید قبل از هر کار دیگری انجام شود.در اینجا، همپوشانی گسترده‌ای با فضای جامعه معماری نرم‌افزار وجود دارد. آن‌ها برای مدت طولانی، کارهای گسترده‌ خوبی در این زمینه کرده‌اند. بنابراین می‌توانید همه آن تعلیمات را بکار گیرید مثلاً با استفاده از ایده‌های طراحی مبتنی بر حوزه، امور را به زیردامنه‌ها و زمینه‌های مرزبندی شده بخش بندی کنید و بعداً آنها را به برنامه‌های مجزا تفکیک کنید.به خاطر می‌آورم که یکی از همکارانم می‌گفت که ما به این دلیل در مورد ریزسرویس‌ها صحبت می‌کنیم زیرا اصطلاح معماری سرویس‌گرا (service oriented architecture) آسیب دیده است. آیا می‌توانید تفاوتش با معماری سرویس‌گرا را بیان کنید و توضیح دهید که چه چیزی به آن آسیب رسانده که ما امروزه از ریز‌سرویس‌ها صحبت می‌کنیم؟ابتدا می‌خواهم بین کلیت جامعه معماری سرویس‌گرا با پیاده ‌سازی‌هایی که در سازمان‌های مختلف دیده‌ام، تفاوت قائل شوم زیرا فکر می‌کنم تفاوت آشکاری وجود دارد. اگر به عنوان مثال به مانیفست معماری سرویس‌گرا (SOA) نگاه کنید، در واقع، کاملاً روشن و ملموس بیان شده است. اما بر طبق تجربه من و تجربه‌های همکارانم و تجربه‌ای که در کل صنعت داریم اگر ایده SOA را با پیاده‌سازی‌هایی که از آن در واقعیت بیرونی شده است مقایسه کنید، تفاوت‌های آشکاری وجود دارد. واقعیت بیرونی این است که برنامه‌های ۱۰ میلیون دلاری داریم که مثلاً دو سال و نیم است اجرا می‌شود و ارزشی تولید نکرده است. واقعیت این است که بر روی بخش‌هایی از کد که وظیفه حل مسائل یکپارچه‌سازی (integration) را دارند میلیون‌ها دلار خرج می‌شود و این هزینه‌کردها هیچ‌گاه به‌ بار نمی‌نشیند. فکر می‌کنم اهمیت دارد که بین آن چیزی که مورد حمایت جامعه [معماری سرویس‌گرا] است با آنچه در واقعیت وجود دارد تفاوت قائل شویم.فکر می‌کنم ایده ریزسرویس‌ها، واقعاً در مورد آن واقعیت‌هاست؛ به نظر من جای شگفتی ندارد که [ریزسرویس] یک رهیافت پایین به بالا برای ساختن سیستم‌ها است. خیلی از افرادی که در این کار شرکت کرده‌اند، به شدت در داخل تیم و با توسعه‌دهنده‌ها مشغول بوده‌اند و همچنان هستند. به این ترتیب، هر روزه مشکلات واقعی مثلاً هزینه زمان مورد نیاز برای انجام تغییرات و مشکلات مقیاس‌پذیری را مشاهده می‌کرده‌اند.در چنین شرایطی، ما به‌دنبال رهیافتی می‌‌گشته‌ایم که برخی از این مشکلات را حل کند. این‌طور فکر نکنید که این تصادفی بوده است که خیلی از افراد مستقل از [خواستگاه‌های مختلف مثلاً] معماری‌ تکاملی، طراحی مبتنی بر مدل، XP و جنبش‌ agile و ... به شدت درگیر آن شده‌اند. زیرا آنچه در ریزسرویس‌ها واقعاً در مورد آن صحبت می‌کنیم مدلی‌ است که بیشتر یک رهیافت افزایشی (incremental) و نوبه‌ای (iterative) برای ساختن معماری‌های سرویس‌گرا است.حتی اگر این‌ها را هم در نظر نگیریم، اگر به صحبت‌هایی که چند سال قبل می‌شد برگردید می‌بینید که در مورد معماری سرویس‌گرای واقعی گفته می‌شد که به‌عنوان رهیافتی برای ساختن سرویس‌ها و تولید ارزش به‌صورت افزایشی است در مقابل اینکه بخواهید دورنمای یکپارچه شده از سرویس‌ها را از پیش طراحی کنید و بخواهید ۸ ماه به طراحی مستندات بگذرانید و پیاده‌سازی‌ها ۵ سال طول بکشد و واقعاً هیچ نتیجه‌ای ندهد.به عقیده من، سبک ریزسرویس‌ها برای ساختن برنامه‌ها، مرتبط با همان معماری سرویس‌گرا است زیرا روش سرویس‌گرا برای ساختن سیستم‌ها، یک روش کاملاً معقولی است. به عقیده من تفاوت اصلی آن‌ها در جزییات نحوه پیاده‌سازی است؛ مثلاً اینکه مدل حاکمیت (governance) غیرمتمرکز دارید.یا مثلاً اینکه [در ریزسرویس‌ها] یک گذرگاه سرویس معظم نداریم!بله، این‌ها مربوط به انتخاب فناوری‌ها است که راه حل‌های سبک‌تر نسبت به سنگین‌تر، ارجحیت داده می‌شود. اما به‌غیر از آن در مورد چیزهایی از قبیل مدیریت نیز این‌گونه است که شما هم از جنبه فنی و هم از جنبه انسانی، سازوکارهای سبک‌تر را می‌پسندید؛ به‌جای اینکه تمایل داشته باشید تعداد زیادی استانداردهای سخت وضع کنید، استانداردها را به‌صورت داخلی در طی زمان و بر اساس کاربردها و تجربه‌های واقعی طراحی می‌کنید و یا به‌جای اینکه یک رهیافت بالا به پایین داشته باشید، به‌جای آن در داخل همان سطوح [خودشان] به آن‌ها فکر می‌کنید و در سطوح پایین تولید انجام می‌شود.یکی از چیزهایی دیگری که من شنیده‌ام این است که برخلاف SOA در معماری ریزسرویس، سرویس‌ها، واسط کاربر گرافیکی (GUI) دارند. آیا این درست است؟خیر. فکر نمی‌کنم این‌طور باشد. فکر نمی‌کنم چیزی وجود داشته باشد که التزام کند که باید GUI داشته باشید. البته فکر می‌کنم در واقع کاملاً مفید است که حتی فقط برای بررسی نحوه کارکرد برنامه هم که شده، GUI داشته باشیم.برای مانیتور کردن ...بله، اما در مورد GUI هایی که مشتری‌ها با آن‌ها روبرو می‌شود، خیر چنین چیزی نداریم که باید GUI داشته باشید.بیایید کمی در مورد تیم صحبت کنیم. فکر می‌کنم شما قانون کانوِی (conway&#x27;s law) را بدانید. ممکن است کمی در مورد آن صحبت کنید و بگویید در معماری ریزسرویس‌ها چه معنی می‌دهد؟این مثال دیگری است که یک تجربه و یا چیزی که برای مدت طولانی، مشخص شده است، در کاربرد دیگری، ظاهر می‌شود و پلی بین این اجزاء برقرار می‌شود. فکر می‌‌کنم در سال ۱۹۶۸ بوده است که ملوین کانوِی، -او اهل ساحل غربی آمریکا است- یک مقاله در مورد تجربیاتش در مورد فکر می‌کنم تئوری ارتباطات (communication theory) می‌نویسد. آنچه او در مقاله‌اش توضیح می‌دهد این است که ساختار راه‌های ارتباطی در نرم‌افزاری که یک سازمان می‌سازد کاملاً یا به شدت با ساختار راه‌های ارتباطاتی که آن سازمان در داخل خودش دارد منطبق است به این ترتیب که اگر شما مثلاً یک تیم پایگاه داده داشته باشید و یک تیم میان‌افزارها (middleware) داشته باشید و یک تیم واسط کاربری (UI) داشته باشید، در نهایت سیستمی هم تولید خواهید کرد که یک پایگاه داده، نوعی میان‌افزار و یک UI خواهد داشت. این را می‌توانم با گفته دن نورث خیلی خوب توضیح دهم. او به من گفت که اگر از ۹ نفر بخواهید که کامپایلر بنویسند، در نهایت به یک کامپایلر می‌رسید که در ۹ مرحله‌ کامپایل می‌کند! :-)جالب است که آن مقاله، ابتدا به‌وسیله مجله مرور کسب‌وکار هاروارد (Harvard business review) رد می‌شود. سپس بعد از گذشت مدتی سازمان‌های دیگری به‌عنوان مثال مایکروسافت به‌صورت داخلی این تحقیقات را تکرار کردند. در انتها HBR خودش هم تحقیقات را تکرار کرد و فهمیدند که به نظر می‌رسد این مورد در نرم‌افزار رخ می‌دهد. بنابراین قانون کانوِی اعتبار یافت.جالب این است که ما در مباحثه‌های خودمان متوجه شدیم که این پیامد فقط به‌خاطر نحوه ساختاردهی تیم یا طراحی سیستم‌تان نیست بلکه پیامدی از نحوه اجبار کردن مرزهای بین این تیم‌هاست. بنابراین در واقع می‌توانید با ساختار تیم‌تان مرزهایی در نرم‌افزارتان تحمیل کنید که باعث مرزهایی در معماری سیستم‌تان می‌شود.برای روشن شدن مطلبی که می‌گویید می‌پرسم: آیا یک ریزسرویس باید به‌صورت تمام وقت دقیقاً توسط یک تیم توسعه داده شود؟خوشحالم که شفاف‌سازی می‌کنید. خیر، من دقیقاً این را نمی‌گویم. من توصیه نمی‌کنم که باید یک تناظر یک به یک بین ریزسرویس‌ها و تیم‌ها باشد. چنانچه ۳ ریزسرویس داشته باشیم که در یک حیطه مرزبندی شده (bounded context) قرار گیرند، ممکن است این ۳ ریزسرویس به یک تیم تخصیص یابند. من علاقه دارم که محدوده [فعالیت‌های] یک تیم مجموعه‌ای از قابلیت‌های پایدار کسب‌وکار باشد که در یک زمینه قرار می‌گیرند. این [ساختار] در یک سازمان می‌تواند کاملاً پایدار باشد زیرا در این صورت کسب‌وکار و معماری، مفاهیمی همریخت خواهند بود. ما باید ببینیم که کسب‌وکار به چه شکلی کار می‌کند و به همان شکل به نرم‌افزار ساختار دهیم تا مانند هم بشوند. اگر بر این اساس تیم‌ها را ساختار دهید، ممکن است تیم‌های مربوط به نیازمندی‌های فراعملکردی (cross-functional) وجود داشته باشد که مانند مدل کسب‌وکار باشد.این یک حوزه خیلی جالب است که فکر می‌کنم در حال حاضر افراد خیلی برای کاوش آن علاقه‌مندند. یکی از مثال‌های خوب آن در مورد یکی از مشتری‌هایم است که از من درخواست مشاوره معماری کرده بودند. بخش بزرگی از سیستم‌ آنها در هند استقرار داشت و بخشی از نرم‌افزارشان در لندن بود. اگر به نحوه تعاملات بین نرم‌افزار لندن و نرم‌افزار هندی نگاه می‌کردید، می‌دیدید که نسبت به دیگر ارتباط‌های‌ بین سیستم‌هایشان، احتمالاً بیشترین ناهمبستگی (decouple) را داشتند و بیشتر بر اساس رد و بدل کردن پیغام بود. این یک مثال خوب بود از اینکه وقتی تیم‌ها در قاره‌های مجزایی قرار دارند، این سبک [سیستم‌های تا حد ممکن ناهمبسته] تنها روشی است که می‌توانیم به طراحی سیستم فکر کنیم.بنابراین چنانچه می‌خواهید ماژول‌ها یا سرویس‌های خود را ناهمبسته کنید، تیم‌هایتان را ناهمبسته کنید.بله. مثلاً در قاره‌های مجزا :-) یا مانند یک مشتری دیگر که در آمریکا داشتم که یک تیم ۶ نفره بودند که بر روی یک نرم‌افزار واحد کار می‌کردند اما هر کدام از آنها در یک جای اداره می‌نشستند و مکعبی کار می‌کردند. (هر کدام در یک وجه مکعب قرار داشتند) و برای ۶ ماه تمام کار می‌کردند و بعد از آن دور هم جمع می‌شدند و من فکر می‌کنم که در این مورد کار درستی نبود. به آن‌ها گفتم مطمئن نیستم با ۶ ماه از هم دور کار کردن و بعد دور هم جمع شدن هیچ‌گاه محصولی حاصل شود.بله، باید بتوانید ببینید که سیستم‌تان به‌صورت یک مجموعه واحد، کار می‌کند. این من را به سئوال بعدی رهنمون می‌کند که چطور ریزسرویس‌ها را تست می‌کنید. ما می‌دانیم که چطور تست واحد (unit test) بکنیم، می‌دانیم که چطور در داخل سطح یک سرویس منفرد، تست یکپارچگی (integration) بکنیم اما وقتی یک برنامه متشکل از تعدادی ریزسرویس دارید باید بتوانید مطمئن شوید که آنها در کنار همدیگر نیز کار می‌کنند. چطور آن را تست می‌کنید؟ آیا برپا کردن تست خیلی دشوار نخواهد بود؟بله، احتمالاً این یکی از جنبه‌های دشوار کار است. وقتی سیستمی می‌سازیم همواره مصالحه‌هایی (trade-off) می‌کنیم. وقتی روی اموری از قبیل مقیاس‌پذیری و قابلیت نگهداری در طی زمان تمرکز می‌کنیم، یکی از مصالحه‌هایی هم که باید داشته باشیم این است که تست کردن دشوارتر می‌شود.اغلب سیستم‌هایی که من دیده‌ام در نهایت به این سرانجام رسیده‌اند که بر روی ریزسرویس‌ها یک سیستم مبتنی بر رخداد (event driven) برقرار شده است که خودش دوباره لایه پیچیدگی جدیدی می‌افزاید زیرا به‌غیر از آنکه باید نگران تست کردن چیزهای زیادی به‌صورت مجزا باشید باید نگران ناهمگام بودن (asynchronicity) هم باشید. با این وجود، مزیت‌های زیادی هم خواهید داشت زیرا می‌توانید چیزهای کوچک را به‌صورت مجزا تست کنید که براساس مجموعه‌ای از مشخصات‌ آیا آنچه قرار است انجام دهند، را انجام می‌دهند یا خیر. مشکل جایی رخ می‌دهد که می‌خواهید چندین سیستم گره خورده به هم را تست کنید. مشکل جاییست که می‌خواهید فرآیندهای کسب‌وکار را از خلال چندین ریزسرویس تست کنید.یک مثال آن، می‌تواند در یک سیستم بانکی باشد که مشتری داشته باشم که یک حساب بانکی دارد و یک فرآیند کسب‌وکار دارم که می‌گوید وقتی یک مشتری ساخته می‌شود باید یک حساب مشتری برایش ساخته شود و می‌خواهم بتوانم برای آن تعدادی ایمیل یا کارت بانکی یا چیزهای دیگری مرتبط با کسب‌وکار را ارسال کنم. با رهیافت ریزسرویس‌ها، در اینجا چندین قابلیت‌ کسب‌وکار وجود دارد. شما قابلیت مشتری (کلیت مشتری) را دارید. ممکن است قابلیت تراکنش و حساب (account) را داشته باشید و چیزهای دیگر. شما فرآیندهای کسب‌وکاری دارید که از خلال این مرزها عبور می‌کنند. چطور می‌خواهید تست‌هایتان را حول این چیزها قرار دهید؟ راه‌های مختلفی برای این کار وجود دارد. یک مثالش این است که نوعی تستِ در سطح محصول داشته باشیم. اینکه یک جریان گذرکننده از این چیزها داشته باشم که در سطح محصول باشد که بتوانم به‌صورت خودکار اجرایش کنم و محیطی داشته باشم که بتوانم این چیزها را بر روی آن مستقر کنم و آنها را تست کنم.همچنین راه‌ها و سازمان‌های پیشرفته‌تری هم وجود دارند. سازمان‌هایی هستند که واقعاً روش‌های جدیدی برای تولید نرم‌افزار اختراع می‌کنند. من فکر می‌کنم Netflix و شرکت‌های مانند آن، از این دسته هستند. آن‌ها در واقع دارند به سمت مدل‌های جالب جدیدی حرکت می‌کنند. در واقع چیزهایی از قبیل تست کردن کارایی (performance) قبل از راه انداختن سیستم، مربوط به گذشته هستند. امروزه تست را بر روی محصول عملیاتی انجام می‌دهید. در واقع تست به‌وسیله تعداد اندکی از کاربرانمان بر روی محصول عملیاتی انجام می‌شود. البته واضح است که این کار بعد از تست اصلی عملکردی توسط تیم توسعه‌دهنده انجام می‌شود.البته به این امید که با یک سازوکار مانیتور کردن خوب هم پشتیبانی می‌شود.بله، با مانیتور کردن‌های اضافی و لاگ‌گذاری‌های متراکم و چیزهای دیگری که باید قرار دهید، پشتیبانی می‌شود.قبلاً گفتم که جنبشی در ارتباط با [تمرکز روی] میانگین زمان ترمیم یافتن وجود دارد و یا ایده مانیتور کردن معنایی (semantic monitoring) محصول را داریم و اینکه طی کردن مراحل از توسعه به استقرار و عملیاتی شدن محصول به‌طور خودکار انجام شود. مثلاً [در زمینه مانیتور کردن معنایی] مانیتور کردن مسیری که کاربر هنگام بازدید از یک وب‌سایت طی می‌کند و چیزهایی از این قبیل مطرح است که این‌ گونه مباحث در سازمان‌های بزرگ در حال پیشرفت است.حالا شما می‌توانید از من در مورد سازوکار نسخه‌ دادن (versioning) سئوال کنید. شاید باید در مورد آن هم صحبت کنیم.بسیار خوب. پس در مورد نسخه‌ها صحبت کنید :-)من فکر می‌کنم کاملاً مرتبط با تست کردن است. زیرا چیزهای زیادی دریافت می‌کنید که با همدیگر صحبت می‌کنند. واضح است که مطمئن شدن از اینکه [این اجزاء] می‌توانند همچنان با همدیگر صحبت کنند از مثلاً [تست کردن] یک فراخوانی متد سخت‌تر است. همین‌طور بازسازی (refactor) این چیزها نیز سخت‌تر است و اموری از قبیل سازوکار نسخه‌دهی، نسبت به آنچه در گذشته بوده، مشکل بزرگتری خواهد بود. چطور می‌خواهید قراردادی که بر اساس آن، با کلاینت‌هایتان صحبت می‌کنید را نسخه‌دهی کنید؟ برای این منظور، افراد روش‌های مختلفی استفاده می‌کنند. در برخی مواقع افراد از ایده قراردادهای مبتنی بر مصرف‌کننده (consumer driven contract) استفاده می‌کنند.قرارداد مبتنی بر مصرف‌کننده چیست؟این ایده، نقطه‌ مقابل یک ایده‌ قدیمی است. اگر یک سیستم پایین‌دست داشته باشم که قرار است با آن یکپارچه ‌شوم می‌خواهم مطمئن شوم که اگر تست‌هایم را در قبال آن سرویس از راه دور اجرا کنم، همچنان مبتنی بر قراردادهایی است که داشته‌ایم وگرنه نخواهم توانست با آن تعامل کنم. بنابراین دوست دارم که به‌طور خودکار هر تغییری که در قرارداد ایجاد شده را بفهمم تا بتوانم در سمت خودم نیز تغییرات را اعمال کنم.ایده قرارداد برآمده از مصرف‌کننده این است که به نوعی جهت فلش را عوض کنیم. یعنی به‌جای اینکه من به‌عنوان کلاینت یک سرویس زیردست، تست‌ها را اجرا کنم، همچنان تست را من می‌نویسم اما آن را به سرویس می‌دهم تا خودش مالکش باشد و بعنوان بخشی از ساختن (build) خودش آن را اجرا کند.یعنی به آن‌ها این امکان را می‌دهید که تست‌های شما را در قبال سیستم خودشان و در خط لوله‌ای که خودشان دارند اجرا کنند.دقیقاً همین است. به آن‌ها یک سری بیان مشخصاتی که قابل اجرا باشد را می‌دهید و (به آن‌ها می‌گویید) که به‌عنوان کلاینت انتظار دارید چطور با شما رفتار شود. از طرف دیگر افرادی که کدها را توسعه و نگهداری می‌کنند، این مشخصات را گرفته و همان‌ طور که شما گفتید به‌عنوان بخشی از فرآیند ساختن (build) خودشان اجرا می‌کنند. بنابراین قرارداد این می‌شود که این قراردادها در سیستم‌های بالادست شکسته نشود. این ایده، خیلی عالی است و افرادی این ایده‌ها را گرفته و کمی جلوتر هم رفته‌اند؛ فکر می‌کنم یک پیاده‌سازی Ruby به نام Pact از آن وجود دارد و یک پیاده‌سازی دیگری هم با نام Pacto وجود دارد. به خاطر نمی‌آورم این نام مخفف چیست اما یکی از این پیاده‌سازی‌ها در استرالیا و دیگری در برزیل انجام شده است.روش دیگری که درباره مدیریت نسخه‌ها وجود دارد و بر اساس ایده مضحکی شکل گرفته این است که با شکل‌ دادن تردد (traffic shaping) این کار را انجام دهیم. این کار لزوماً در مورد API ها عمومی انجام نمی‌شود بلکه در داخل ساختاری که برای ریزسرویس‌ها دارید هم کاربرد دارد که من مثالش را در همان Netflix یا شرکت‌های دیگری که با آن‌ها کار کرده‌ام، دیده‌ام.وقتی با ریزسرویس‌ها تعامل دارید چنانچه بخواهید تغییراتی دهید که درون‌تیمی باشد واقعاً نیازی نیست که چندان نگران نسخه‌ها باشید زیرا این تغییراتی که تنها بر روی قراردادهای درون‌تیمی تأثیر دارند خیلی سریع انجام می‌شود. کافیست به همکارم بگویم که من می‌خواهم این تغییر را بدهم. خوبه؟ و او می‌گوید بله، و به همین سرعت تغییر انجام می‌شود اما وقتی به قراردادهای با تیم‌های دیگر می‌کشد، باید سطحی از پایداری را فراهم کنید. در اینجا شرکت‌هایی مانند Netflix همان‌طور که گفتم به‌جای استفاده از سازوکارهای خاص نسخه‌دهی از نوعی شکل‌دادن تردد استفاده می‌کنند و یا اینکه این روش را در ترکیب با یک سازوکار خاص نسخه‌دهی استفاده می‌کنند. در این مدل، شما نسخه‌ای از سرویس‌ را دارید که به‌صورت عملیاتی در حال اجرا است و بعد شما نسخه بعدی را هم عملیاتی می‌کنید، یعنی دو نسخه متفاوت از یک سرویس را خواهید داشت که هر دو عملیاتی شده‌اند اما در واقع نسخه جدید، زنده نیست و هیچ ترددی به آن نمی‌شود. بعد از آنکه تست‌ها را انجام دادید و تست‌های سطح محصول را انجام دادید و مطمئن شدید که صاحب محصول (product owner) از آنچه رخ داده، خرسند است و ...و شاید از برخی مشتریان قدیمی هم بخواهید که از آن استفاده کنند...دقیقاً. بعد از انجام این کارها شروع می‌کنید که تردد به آن را شکل دهید و افراد را به سمت آن سوق دهید و یا این‌طور خواهد بود که تیم‌های بالادستی خودشان انتخاب می‌کنند که چه زمانی جابجا کنند. و البته با توجه به این‌که ما به سمت عصری پیش می‌رویم که در آن پردازش ابری در همه‌ جا حاضر است، این ایده که بتوانید نسخه‌های مختلف چیزی را همزمان اجرا کنید، ساده‌تر فهمیده و اجرا می‌شود چون دیگر با محدودیت‌های مراکز داده‌ها روبرو نمی‌شویم، فقط ممکن است بوسیله محدودیت‌های مراکز داده‌ Amazon و ... به مشکل بخوریم :-)بسیار خوب، در پایان آیا سئوالی هست که بخواهید از شما بپرسم یا چیزی هست که بخواهید در حالت کلی در مورد ریزسرویس‌ها بگویید؟بله، نظر من این است که ما بر دوش بزرگان ایستاده‌ایم. [ریزسرویس‌‌ها] پدیده کاملاً جدیدی نیست. قطعاً این‌طور نیست و فکر نمی‌کنم هیچ کس دیگری چنین ادعایی داشته باشد که همه این ایده‌ها جدید است بلکه بر روی تعدادی زیادی از ایده‌های موجود ساخته شده است و آن‌ها را طوری کنار هم قرار داده است که قدرت آن‌ها چند برابر شود. قرار دادن این چیزها کنار یکدیگر به‌عنوان یک راه جامع که شامل ایده‌های توسعه تَرکه‌ای (lean)  باشد، شامل ایده‌های دنیای سرویس‌گرا باشد، شامل ایده‌هایی از دنیای DevOps باشد، ... همه این چیزها کنار همدیگر، نسخه قدرتمندی می‌‌سازد که می‌توانید سیستم‌های امروزی را برپایه آن تولید کنید.افراد زیادی [در این کار] مشارکت داشته‌اند، پیش از این در مورد دن نورث صحبت کردم که در ارتباط با ایده‌ معماری‌های مؤلفه‌های جایگزین‌پذیر خیلی مشارکت داشته است و یا فرد جورج و یا ادریان کاکرافت که در Netflix صحبت‌های گسترده‌ای در این زمینه کرده است یا مؤسسه‌های بزرگی در استرالیا هستند، یکی از همکارانم به اسم اوان بوچر آنجا همکاری می‌کند. در مقایسه، در انگلستان، می‌توانید کارهای خیلی جذابی [در ارتباط با این موضوع] داشته باشید و از کاری به کار دیگر بروید. فکر می‌کنم اکنون که پردازش ابری در همه‌جا حاضر است، دوران شگفت‌انگیزی برای توسعه‌ نرم‌افزار باشد و فکر می‌کنم این چیزی است که معادلات دنیای امروز را عوض می‌کند و ما خیلی مختصر در مورد آن صحبت کردیم.خوب است. شنوندگان ما کجا می‌توانند چیزهای بیشتری در این زمینه پیدا کنند؟ شنیده‌ام که در نوشتن یک کتاب مشارکت دارید.بله. اولینش همان مقاله‌ ریزسرویس‌ها است که با مارتین فاولر نوشته‌ام که در سایت مارتین فاولر قرار دارد. در بلاگم -که البته خیلی به‌ندرت بر روی آن پست می‌گذارم- مباحث و آشنایی‌هایی با موضوع وجود دارد. از این بابت عذر می‌خواهم که خیلی از مطالب بلاگم در مورد اخترفیزیک است :-) همان‌طوری که گفتید کتابی هم هست که در حال حاضر در نوشتن آن مشارکت دارم. در همین حال، یکی از همکارانم یعنی سم نیومن که [در زمینه ریزسرویس‌ها] مشارکت فراوانی داشته است، کتابی با عنوان ساختن ریزسرویس‌ها نوشته است. به‌غیر از این‌ها فکر می‌کنم بلاگ Netflix، یک منبع خارق‌العاده است. احتمالاً چیزهای بیشتری هم هست :-)کجا می‌توان بیشتر از شما شنید. آیا در توییتر هستید؟بله، در توییتر با عنوان boicy@ هستم. همچنین می‌توانید به من ایمیل بزنید. آدرسش در زیر مقاله سایت فاولر هست. ما خیلی دوست داریم که با افراد تعامل داشته باشیم. اگر علاقه‌مند شدید لطفاً در ارتباط باشید. من تمام تلاشم را می‌کنم که به همه نامه‌هایی که دریافت می‌کنم پاسخ دهم.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Fri, 10 Jun 2022 18:15:19 +0430</pubDate>
            </item>
                    <item>
                <title>مشاور نرم‌افزار بودن</title>
                <link>https://virgool.io/se-radio/%D9%85%D8%B4%D8%A7%D9%88%D8%B1-%D8%A8%D9%88%D8%AF%D9%86-ehb9oxcbynv5</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۱۶۸ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت، مایکل و مارکوس در ارتباط با مشاور (و یا مربی) بودن در صنعت نرم‌افزار صحبت می‌کنند. آن‌ها دراین‌باره صحبت می‌کنند که چطور می‌‌شود یک مشاور خوب شد و همین‌طور درباره برخی جنبه‌های مثبت و منفی این حرفه بحث می‌کنند. ما تصمیم نگرفته‌ایم که چه کسی سئوال کند و چه کسی مطالب را ارائه کند. می‌خواهیم به یک روش برنامه‌ریزی نشده و منعطف این کار را بکنیم! وقتی می‌خواهیم در مورد مشاوره و مربی‌گری صحبت کنیم فکر می‌کنم ابتدا باید آن‌ها را تعریف کنیم. شما می‌خواهید امتحان کنید؟بله، صادقانه بگویم که من یک تعریف واقعاً روشنی از تفاوت بین مشاوره و مربی‌گری ندارم. شاید بیشتر به این خاطر باشد که من در کارم، همواره به عنوان مربی عمل کرده‌ام اما در قرارداد ممکن است مشتری بیشتر به مشاوره علاقه نشان دهد.وقتی به عنوان مربی عمل می‌کنید، چه‌کار می‌کنید؟ شاید به این روش، برداشتی از آن پیدا کنیم.در پروژه‌هایی که من شرکت داشته‌ام، کمک می‌کرده‌ام که تیم چیزی را یاد بگیرد و کاری که احتمالاً قبلاً انجام نداده را انجام دهد. به‌عنوان مثال، اینکه اسکرام را به عنوان یک فرآیند چابک (Agile Process) به‌کارگیرند. کمکشان می‌کردم که اسکرام را اعمال کنند. من واقعاً اسکرام را برای آن‌ها انجام نمی‌دادم بلکه کمک‌شان می‌کردم که این کار را بکنند. شاید تفاوت همین باشد. شما به‌عنوان مشاور همواره کاری را برای مشتری انجام می‌دهید و چیزی را برایش آماده می‌کنید. چیزی را پیاده‌سازی می‌کنید یا نرم‌افزاری را می‌دهید یا مسئله‌ای را برای‌شان حل می‌کنید اما به عنوان مربی بیشتر کمک‌شان می‌کنید که خودشان کارها را انجام دهند.این قطعاً همان روشی است که من برای مجزا ساختن این دو استفاده می‌کنم. من اگر پروژه‌ای داشته باشم که برای یک هفته یا یک ماه طول بکشد، عموماً آن را مربی‌گری می‌نامم زیرا همان کاری را که گفتی انجام می‌دهم. در واقع کمک‌شان می‌کنم که کار کنند اما مشاوره را معمولاً برای موردی به‌کار می‌برم که برای دو یا سه روز به سراغ تیم می‌روم و به‌وسیله آموزش کمک‌شان می‌کنم که در جهت خاصی هماهنگ شوند مثلاً تلاش می‌کنیم که اولین مرحله تولید یک DSL برای یک تنظیم‌کننده یخچال را بیابیم. برای من این‌طور است که چیزهای کوتاه‌مدت که اساساً فقط شامل صحبت کردن و شاید تولید یک پروتوتایپ باشند را مشاوره می‌نامم و وقتی کاری را برای مدت طولانی‌تری انجام می‌دهم و مانند یک عضو واقعی تیم هستم و کار واقعی را انجام می‌دهم یا اینکه برای مدت طولانی کمک‌شان می‌کنم، آن را مربی‌گری می‌نامم اما روشن است که تعریف واقعاً روشنی نیست.بله، خصوصاً در کارهای روزمره.بله، منظورم این است که فکر می‌کنم مهم باشد که این موضوع مربی‌گری و مشاوره‌‌ای که داریم در موردش صحبت می‌‌‌کنیم را از رفتار سنتی آدم‌های کاسب‌کار متمایز کنیم که بیشتر با خودجلوه‌گری همراه است! :-)بله، چون این چیزها برای ما مهم نیست و این کارها را خیلی دوست نداریم! :-)وقتی ما در مورد مشاوره صحبت می‌کنیم واقعاً منظورمان کار عملی نرم‌افزار است نه امور تجاری.بله، من هم همین طور.فکر می‌کنم یکی از اهداف اصلی مشاوره و مربی‌گری، انتقال دانش است. می‌خواهید به تیمی کمک کنید که چیزی را فرا بگیرد یا در انجام آن خوب شود. درست است؟بله، فکر می‌کنم بین مشاوره و مربی‌گری با یک قرارداد ساده اجاره افراد (Body Leasing) -که به‌علت نبود مثلاً نیروی کافی برای توسعه کد بسته می‌شود- تفاوت زیادی وجود دارد.بسیار خوب. آنچه می‌خواهیم انجام دهیم این است که کمی توضیح دهیم که به‌عنوان مربی یا مشاور چه می‌کنیم. بعد از آن می‌توانیم کمی نظرمان را در این مورد توضیح دهیم که چه صلاحیت‌های ضروری برای افرادی که می‌خواهند این شغل را داشته باشند، وجود دارد. این خطر را دارد که این‌طور به نظر برسد که می‌خواهیم به شما بگوییم چقدر وارد هستیم اما منظورمان این نیست. راستش ما اخیراً نامه‌ای دریافت کردیم که ارسال‌کننده به ما یادآوری کرده بود که با وجود این خطر، باید این قسمت را اجرا کنیم. به‌خاطر همین، دور هم جمع شدیم و اجرایش کردیم زیرا بعضی افراد واقعاً دوست دارند در مورد این موضوع بشنوند.بسیار خوب، لطفاً در مورد یکی دو نمونه پروژه‌ [که درگیرش بوده‌اید] و کارهای روزمره‌اش بگویید.یکی از نمونه پروژه‌ها برای من این بوده است که با تیمی همراه شده‌ام که می‌خواستند روش‌های چابک مثلاً اسکرام را به خدمت بگیرند. آنها واقعاً می‌خواستند این حس را پیدا کنند که برای آنها به‌کارگیری اسکرام یعنی چه؟ آنها من را دعوت کردند و ما دوسه روز در مورد اینکه اسکرام چیست و چطور تعریف می‌شود و خصوصاً اینکه انجام اسکرام برای آنها چه معنی می‌دهد صحبت کردیم یعنی در مورد این ترجمه دانش تئوری به زندگی عملی روزمره. ما حسی پیدا کردیم که اسکرام به چه معنی است و چطور می‌توانند آن را آغاز کنند و چطور می‌توانند آن را ادامه دهند. این کار عموماً بیشتر با یک روش کارگاه مانند انجام می‌شود. کنار هم و بدون میز می‌نشینیم و از تخته‌های الصاقی (Pin board) یا وَرَقی (Flip chart) استفاده می‌کنیم. به‌صورت تعاملی مسائل را با گروه بحث می‌کنیم.شما گفتید «گروه». آنها چه نوع افرادی هستند؟فکر می‌کنم خیلی متنوع باشد: توسعه‌دهنده‌ها، مدیر پروژه‌ها، گاهی حتی مدیران محض (Pure Manager). فکر می‌کنم دامنه‌اش به همه نقش‌هایی که در شرکت‌ها برای توسعه نرم‌افزار می‌شناسید، بکشد. مشتری‌های من عموماً شرکت‌های بزرگ بوده‌اند و داخل خود ساختارهای سلسله‌مراتبی داشته‌اند و از من کمک خواسته‌اند. در این نوع شغل‌های دوروزه کارگاهی یک دستور جلسه ثابت یا ۲۰۰ صفحه اسلاید آماده نمی‌کنید که همه وقت را برایشان صحبت کنید بلکه کم و بیش به‌صورت تعاملی به افراد توضیح می‌دهید که معنای چیزی چیست و چه سئوال‌هایی در موردش هست. من دوست دارم با فهرستی از سئوال‌ها آغاز کنم. مشتریان، سئوال‌های بیشتری هم می‌افزایند. در ابتدای کارگاه، به آنها می‌گوییم که سئوال‌هایتان چیست و مهم‌ترین چیزها و بزرگترین سئوال‌هایی که در ذهنتان دارید چیست. ما سئوال‌ها را اولویت‌بندی و فهرست می‌کنیم و گام به گام به سراغ همه آنها می‌رویم. در حین پاسخ دادن به این سئوال‌ها، مقداری اصطلاحات و دانش تئوری را مطرح می‌کنم. [مثلاً می‌گویم که] الان باید در مورد نحوه گذشته‌کاوی (Retrospective) صحبت کنم یا الان باید در مورد چگونگی برنامه‌ریزی‌ یک دوره (Sprint) صحبت کنم اما این تکه بحث‌های تئوری بیشتر این‌طور هستند که به هنگام لزوم ارائه می‌شوند. فکر می‌کنم این شغل‌های کوچک دو سه روزه، مرسوم باشند.من دو نوع تجربه مشاوره کاملاً متفاوت داشته‌ام. یکی مشاوره دادن در ارتباط با یک ابزار مشخص است مثلاً مدل کردن با Eclipse یا XText و چیزهای شبیه به آن. در این حالت کارگاه بیشتر با قالب آموزشی انجام می‌شود. مشتریان به من می‌گویند که می‌خواهند فلان نوع زبان را بسازند و می‌دانند که برای آن کار XText خوب است؛ بعد ما با همدیگر ساختن آن را شروع می‌کنیم و کمک‌شان می‌کنم که زبان را بسازند و ابزار را به آن‌ها آموزش می‌دهم.نوع دیگر شغل که برای من جذابیت خیلی بیشتری دارد، در حالتی است که مشتری می‌گوید: ما در مورد این مبحث زبان‌های مختص حوزه (Domain Specific Language) و توسعه برآمده از مدل (Model Driven) شنیده‌ایم و فکر می‌کنیم چیزهای خوبی باشد و می‌خواهیم ببینیم که آیا می‌توانیم در محیط خودمان آنها را بکار ببریم؟ در اینجا دو حالت وجود دارد، یک حالت این است که می‌گویند که ما یک مورد خاص در ذهن داریم مثلاً اخیراً برای یک شرکت کار کردم که یخچال می‌ساختند و در مورد تعریف یک DSL برای توضیح ترمودینامیک و الگوریتم‌های خنک‌سازی یخچال‌هایشان فکر می‌کردند. کاری که کردیم این بود که تلاش کردیم، اولین نسخه این زبان را بسازیم. قبل از هرچیز باید مسئله را می‌فهمیدم بنابراین سئوالات زیادی پرسیدم و سعی کردم بفهمم که توضیح دادن چگونگی خنک کردن یخچال، یعنی چه؟ من باید می‌فهمیدم که چه چیزی را می‌خواهند توضیح دهند. بعد از آن، نشستیم و تلاش کردیم با یک نوت‌بوک، کار نوشتن پروتوتایپ یک زبان را آغاز کنیم. اگر فرض کنیم که خودم قانع شوم که DSL راه خوبی (برای مسأله آن‌ها) است، آنگاه من باید آن‌ها را قانع کنم که این کار جواب می‌دهد و زحمتی که برای ساختن زبان متحمل می‌شوند، قابل قبول است.یک حالت دیگر هم این است که مثلاً گاهی مواقع مشتریان نام من را در کنفرانس‌ها می‌بینند و می‌گویند حال که شما به اینجا آمده‌اید یک ارائه یک ساعته یا یک ساعت و نیمه در مورد DSL برای تیم یا همه توسعه‌دهنده‌ها در شرکت بگذارید. این‌ها شرایط متداول مشاوره‌های من بوده است.فکر می‌کنم برای من، یک حالت دیگر این بوده است که به‌صورت کلاسیک آن‌ها را برای چند ماه به‌صورت ۲ یا ۳ روز در هفته مربی‌گری می‌کرده‌ام تا اسکرام یا روش‌های چابک دیگر را در کارهای روزمره‌شان به‌خدمت بگیرند و کمک‌شان می‌کرده‌ام که در این راه موفق باشند.یعنی شما هر هفته برای یکی دو روز بر می‌گشتید؟بله، در ابتدا کار را سنگین‌تر مثلاً با ۳ یا ۴ روز در هفته آغاز می‌کردیم و بعد از چند هفته آن را به ۲ یا ۱ روز در هفته یا ۱ روز در ماه، کاهش می‌دادیم.بله، این کاری است که من هم انجام داده‌ام و این همان چیزی است که من به آن مربی‌گری می‌گویم. من دقیقاً همین کار را می‌کنم با این تفاوت که من اغلب با فرآیند‌های توسعه نرم‌افزار سروکار ندارم بلکه در عوض، بیشتر در مورد فناوری‌ها و کارهای مشخص سروکار دارم. من هم به همین روش کار می‌کنم. با کار سنگین‌تر آغاز می‌کنم و بعد زمان آن را کاهش می‌دهم.گاهی از من هم برای [مشاوره دادن] برخی فناوری‌ها درخواست می‌شود. من دو وجه دارم. یکی از علاقه‌مندی‌هایم در مورد فرآیند‌ها و سبک‌های چابک است و بخش دیگر قلبم برای فناوری‌های جالب مثلاً فناوری‌های مربوط به جاوااسکریپت و OSGi می‌تپد. خیلی مفرح است که با تیم‌هایی همراه شوید که مثلاً دارند OSGi را به خدمت می‌گیرند و برخی چالش‌های فنی که دارند را متوجه شوید مثلاً برخی مسائل مربوط به بارگذاری کلاس‌ها و این چیزها! به نظر من این‌ها مسائل خیلی جذابی هستند و خیلی مفرح است که با آن‌ها بر روی این مسائل کار کنید تا چیزها بکار بیافتند خصوصاً اگر در مدت زمان کوتاهی مثلاً یکی دو روز باشد. آن‌ها امیدوارند در چنین مدتی اینگونه مسائل‌شان حل شود. همواره خیلی جذاب و مفرح است که سیستم‌های مختلف و افراد مختلف را ملاقات می‌کنید.فکر می‌کنم تا پایان مصاحبه باید برگردیم و بازهم در مورد آن بخش‌هایی از شغل مشاوره که دوست داریم و آنچه دوست نداریم صحبت کنیم اما دیدن سیستم‌های مختلف و تیم‌های مختلفی که با سیستم‌های مختلف کار می‌کنند قطعاً یک امتیاز بزرگ است.برای یک مشاور خوب بودن چه چیزی مهم است؟ شما گفتید که این تفکیک بین امور مربوط به فرآیند‌ها و برخی فناوری‌های خاص از قبیل OSGi -که شما را بیشتر با آن می‌شناسند- را دوست دارید. به نظر شما برای یک مشاور خوب بودن چه پیش‌شرطی مهم است؟به نظر من یکی از مهمترین پیش‌شرط‌ها این است که دوست داشته باشید به صحبت‌های افراد گوش دهید.جالب شد چون فکر می‌کردم که مشاور همه‌اش صحبت می‌کند!من هم دوست دارم که صحبت کنم! اما فکر می‌کنم خیلی مهم باشد که به صحبت‌های افراد گوش دهیم تا مشکلات‌شان را بفهمیم و به سیستم‌ آن‌ها، به مشکلاتشان و به تیم‌شان کاملاً احترام بگذاریم. گاهی مشاورانی را می‌بینم که وقتی می‌آیند [گویی] رئیس بزرگ هستند و همه چیز را می‌دانند و خیلی به مشتریان اهمیت نمی‌دهند، می‌گویند معماری شما کاملاً اشتباه است و باید به این روش یا آن روش عمل کنید. این روش کار من نیست و چیزی نیست که به آن علاقه داشته باشم.این یک چالش جالب است. مگر نه؟ اگر به عنوان مثال، مورد OSGi را درنظر بگیریم، افراد می‌دانند که شما OSGi را کاملاً می‌شناسید. آنها ممکن است شما را استخدام کنند تا در ارتباط با مشکلات OSGi کمکشان کنید. شما باید در برخی جنبه‌ها بهتر از آن‌ها بدانید در غیر این صورت استخدامتان نمی‌کردند. از طرف دیگر، شما نمی‌توانید آنجا بروید و بگویید شما همه نادان هستید و همه کارهایتان اشتباه است و بیایید که به روش دیگری آن را انجام دهیم در عوض می‌خواهید که تیم، شما را کاملاً دوست داشته باشد.چه من اهمیت بدهم چه ندهم، این [روش کار] درست نیست!بنابراین رمزش این است که دانشتان را در مورد فناوری یا هر چیز دیگری عرضه کنید اما مجبورشان نکنید.من مجبورشان نمی‌کنم و فکر می‌کنم وقتی داخل یک تیم به عنوان مربی یا مشاور عمل می‌کنید، حتماً به این خاطر شما را استخدام کرده‌اند که در مورد یک فناوری خاص یا روش توسعه، دانش کافی ندارند و در مورد بخش‌هایی از کاری که انجام می‌دهند نیاز به کمک دارند اما نادان نیستند. من تیم‌ها و افراد بسیار بسیار خوبی را دیده‌ام که خوب کار می‌کرد‌‌ه‌اند. فکر می‌کنم یک مزیت این کار مشاوره این است که این دو طرف را کنار هم می‌گذاریم، شاید من کمی در مورد OSGi بیشتر از آن‌ها بدانم اما آن‌ها در مورد حوزه کارشان، سیستم‌ها، ساختارها و شرایط جانبی‌شان خیلی بیشتر از من می‌دانند؛ در مورد همه چیزهایی که هر روزه باید با آن‌ها درگیر شوند و من از آنها بی‌اطلاعم. فکر می‌کنم این دو دانش را باید به هم پیوند دهید تا کاری انجام شود و مسئله‌ای حل شود.شاید داریم سعی می‌کنیم چیز یکسانی را به روش‌های مختلفی بیان کنیم. برای من این‌طور است که اگر یک عقیده اختصاصی در مورد چیزی داشته باشم، آن‌ها را متوجهش می‌کنم و به آنها می‌گویم که دارند اشتباه عمل می‌کنند با این حال می‌دانم که مرزها کجاست. تلاش نمی‌کنم که یک عقل کُل باشم. در یک حوزه خاص، کمکشان می‌کنم و احتمالاً [در آن حوزه] چیزهای بیشتری می‌دانم اما در مورد دیگر چیزها کنار می‌ایستم. اگر چیزی از من بخواهند که نمی‌دانم، باید بگویم که نمی‌دانم، ایده‌ای ندارم.من فکر می‌کنم اینکه بگویید عقیده من این‌جور یا آن‌جور است کاملاً مقبول است اما وقتی این فقط به عنوان عقیده من باشد. ممکن است حقیقت یا حقیقت در سراسر جهان مطابق با آن باشد و ممکن هم هست که عقیده من فقط برآمده از تجربه‌های گذشته‌‌ام باشد که با آنچه آن‌ها انجام می‌دهند متفاوت باشد.بنابراین فکر می‌کنم کار برای من بیشتر شبیه به اشتراک گذاشتن تجربیاتم بوده است و اینکه تلاش کنم تا تجربیاتم را با شرایط آنها تطبیق دهم و یاد بگیریم که از آن تجربیات چه چیزی می‌توانیم بیاموزیم تا مسئله‌ای را حل کنیم یا چیزی را بهتر کنیم.چیز دیگری که من در کار خودم متوجه شدم این بود که گاهی واقعاً انرژی لازم برای فهم عمیق مسأله واقعی مشتری را صرف نکرده‌ام. گاهی به جایی می‌روید و با افراد، نیم‌ساعت صحبت می‌کنید و بعد می‌خواهید مشکل آن‌ها را در یکی از جعبه‌هایی که برای چیزهای مختلف ساخته‌اید بگذارید و می‌خواهید حل کردن مسأله‌شان را آغاز کنید اما مسائل را واقعاً نفهمیده‌اید، در این هنگام شروع بکار می‌کنید و کمکشان می‌کنید که پروتوتایپ یا هر چیز دیگری را بسازند اما مدتی بعد می‌فهمید که خیلی خوشبین بوده‌اید و قضیه پیچیده‌تر از این حرف‌ها است. مسائل عمیق‌ترند و آن‌قدر آسان نیستند. بنابراین همان طور که شما گفتید واقعاً مهم است که وقت بگذاریم و به افراد گوش دهیم و تلاش کنیم که ورودی‌ها را بفهمیم.بله، در یکی از پروژه‌هایی که وارد شدم، برای مدت نسبتاً طولانی با تیم کار می‌کردم و همراه با تیم، توسعه می‌دادم، در بحث‌های معماری و طراحی شرکت می‌‌کردم و حتی در کارهای برنامه‌نویسی روزانه شرکت می‌کردم، گاهی آنها از من می‌پرسیدند که آیا یک ایده طراحی برای فلان مسأله داری؟ و من اغلب می‌گفتم باید ۳ بار بپرسی تا جواب واقعاً خوبی بگیری! زیرا اولین جواب من بیشتر شبیه این است که: بله، این مثل فلان چیز می‌ماند و راه‌حلش A است. بعد از ۲ ساعت آنها برمی‌گردند و می‌گویند ما به یک مشکلاتی خورده‌ایم. می‌آیی یک نگاهی بکنی؟ و من می‌فهمم بله، راه حل A اشتباه بوده است، ساده‌انگارانه بوده است یا کاملاً افتضاح بوده است. [می‌گویم] بیایید راه حل B را امتحان کنیم. من یک ایده برای B دارم و بعد از ۳ ساعت دوباره به من می‌گویند: خیلی مناسب نیست، می‌توانی یک نگاهی بکنی؟ و بعد با همدیگر راه‌حل C را پیدا می‌کنیم. بنابراین این شرایط به اشتراک گذاشتن تجربیات و بحث با آن‌ها، از جنس بهتر دانستن چیزی یا کمتر و زیادتر دانستن چیزی نیست بلکه بیشتر شبیه به داشتن تجربیات مختلف از افراد مختلف است تا ببینیم که چه چیزی می‌توانیم از آن‌ها بیاموزیم و چه راه‌حلی می‌توانیم پیدا کنیم.برخی می‌گویند که مشاور نباید دانش افرونه‌ای فراهم کند بلکه فقط باید کمک کند که چیزهایی که تیم هم‌اکنون می‌داند برایشان توضیح داده شود و چیزها را کنار هم قرار دهد و دستیابی به یک تیم خلاق و مولد را تسهیل بخشد. دراین‌باره من می‌گویم نوع مشاوره‌هایی که من می‌کرده‌ام این‌طور نبوده است. من نمی‌گویم که این اشتباه است یا اتفاق نمی‌افتد اما نوع مشاوره‌ای که من می‌دهم نیست. من برای حوزه‌های کاملاً معینی از تخصص‌ها استخدام می‌شوم و نقش من کسی نیست که بخواهد تیم را یکپارچه کند اما فکر می‌کنم این‌طور افراد هم وجود داشته باشند.بله، در ارتباط با مشاوره‌هایی که در ارتباط با فرآیند توسعه داشته‌ام، نوع کارم بیشتر به همین شکل بوده است زیرا اینکه «من» فرآیندی را انجام دهم یا آن را و آن را تجربه کنم معنی نمی‌دهد. تیم است که آن را تجربه می‌کند و باید آن را بپذیرد، تغییرش دهد و یاد بگیرد که چطور با آن فرآیند برخورد کند. آن‌ها باید آزمایشات خودشان از بکارگیری آن فرآیند را داشته باشند. این‌ها شرایطی است که من به تیم کمک می‌کنم که دریابد چه چیزی درست و چه چیزی غلط است و من از قبل نمی‌دانم که چه چیزی درست یا غلط است.یکی از چیزهایی که من فکر می‌کنم برای یک مشاور خوب بودن مهم است و به درآمد روزانه‌تان مرتبط می‌شود این است که باید یک پروفایل روشن داشته باشید. من همواره به این روش کار می‌کنم. من در حوزه‌های خاصی کار می‌کنم و در همان حوزه‌ها [مقاله و کتاب] منتشر می‌کنم و در کنفرانس‌ها سخنرانی می‌کنم. بنابراین افراد فرض می‌کنند که من در آن حوزه‌ها، تجربه دارم و این چیزی است که می‌توانم بفروشم و در آن زمینه کار کنم. من نمی‌توانم تصوری از مشاوره دادن کسی داشته باشم که در زمینه خاصی تمرکز نکند. آیا چنین افرادی وجود دارند؟ در آن صورت شاید همان روش اجاره افراد (Body Leasing) باشد، اینکه به پروژه‌ای بروید و فقط کار کنید.شاید همان اجاره افراد باشد، نمی‌دانم. من اغلب تلاش می‌کنم که موضوعاتی که به آن‌ها علاقه دارم را دنبال کنم. مثلاً همان OSGi که برایم جالب است زیرا من واقعاً این نوع از پیمانه‌ای بودن (Modularity) را دوست دارم. البته نمی‌گویم که هر شب خواب OSGi را می‌بینم! من چیزها را یاد می‌گیرم و خوشحال می‌شوم که آن‌ها را به اشتراک بگذارم. به عنوان مثال به دیگران کمک کنم که چیزهای OSGi را راه بیاندازند اما البته اگر بخواهم برای ۲۰ موضوع مختلف مشاوره بدهم، نمی‌توانم به همه آن‌ها علاقه داشته باشم و در همه موضوعات خوب باشم. واقعاً دوست دارم در چیزی خوب باشم و به دیگران آن را توضیح دهم و کمکشان کنم.شرایطی را دوست ندارم که مشتری برای یک متخصص Hibernate درخواست کرده است و رئیستان شما را برای او می‌فرستد زیرا در پروفایل شما خوانده که ۲۰ سال پیش در یکی از پروژه‌هایتان Hibernate را برای یک هفته استفاده کرده‌اید اما الان چون متخصص آن را ندارید شما به سراغ مشتری می‌روید و باید به ایشان مشاوره بدهید و تمام چیزی که می‌توانید انجام دهید این است که شب قبل آن تلاش کنید چه راه حلی وجود دارد که به قدر یک گام خیلی خیلی جزیی از مشتری جلو باشید. این چیزی است که من دوست ندارم و در همه سال‌های گذشته از این مسئله اجتناب کرده‌ام که بخواهم در زمینه‌ای مشاوره بدهم که واقعاً در آن خبره نیستم و چیزی نمی‌دانم.شخصاً باید خودم به چیزی که به مشتری می‌گویم مطمئن باشم. باید اطمینان داشته باشم که آنچه در موردش صحبت می‌کنم را می‌دانم و در مورد آنچه پیشنهاد می‌کنم مطمئن باشم. نه به این معنا که به‌طور کامل چیزی باشد که آنها نیاز دارند که این خود سئوال دیگری است اما باید مطمئن باشم که چیزها مطابق با قواعدی هستند که کار می‌کند و قبلاً آن‌ها را انجام داده‌ام. من موافقم که برای یک مشاور خوب بودن باید در زمینه خاصی که درباره‌اش مشاوره می‌دهم، کاملاً حرفه‌ای باشم. این واقعاً حیاتی است.بله، همین طور فکر می‌کنم باید صادق باشید. اگر سئوالی پرسیدند که چون قبلاً آن را انجام نداده‌اید برایش پاسخی ندارید یا شاید ایده‌ای برایش ندارید، در چنین شرایطی من همواره می‌گویم که ایده‌ای ندارم و با تیمی که قبلاً چنین شرایطی داشته باشد برخورد نکرده‌ام؛ می‌توانم تصور کنم که راه‌های A، B یا C ممکن است جواب بدهد، باید امتحانش کنیم ولی من واقعاً جواب را نمی‌دانم. فکر می‌کنم این مطلب در یک فرآیند مشاوره سالم، مطلب مهم است.درست است، زیرا مشتری‌ها خیلی سریع این را می‌فهمند که دارید در مورد چیزهایی صحبت می‌کنید که واقعاً آن‌ها را نمی‌شناسید. این را حس می‌کنند. حس می‌کنند که نامطمئن شده‌اید و فقط دارید حرف می‌زنید.بله، عموماً آن‌ها در این شرایط که می‌گویید واقعاً ایده‌ای ندارید، عصبانی نمی‌شوند. البته شاید اگر قرار باشد برای سه روز پشت سرهم این را بگویید که واقعاً ایده‌ای ندارم که مشکل شما چیست و متوجه نشده‌ام که چه چیزی می‌تواند کمک‌تان کند، در این صورت باید قبلاً اشتباهی رخ داده باشد.این نکته خوبی بود. شما چگونه مشتری‌های خود را پیدا می‌کنید؟ یا اینکه مشتری‌ها چطور شما را پیدا می‌کنند؟ منظورم این است که چطور مطمئن می‌شوید که آنچه الان در موردش صحبت کردید اتفاق نیافتد؟ چگونه به هم پیوند می‌خورید؟عموماً دوست دارم که قبلاً با آن‌ها صحبت کرده باشم. منظورم پیش‌فروش نیست. آن چیز دیگری است. دوست دارم که قبلاً با آن‌ها صحبت کنم و بفهمم که مسئله و شرایط چیست؟ انتظارات چیست؟ چه انتظاری از من دارند؟ به آن‌ها می‌گویم که آیا فکر می‌کنم می‌توانم به آن‌ها کمک کنم یا نه. خیلی زیاد پیش می‌آید که به آن مشتری‌های بالقوه می‌گویم من در این حوزه‌ها تجربه دارم و می‌توانم کمکتان کنم اما در مورد آن بخشی که اشاره کردید، متخصص نیستم، داستان زندگی‌ام را می‌گویم و به ایشان می‌گویم که ولی الان برای دانش خوب بهتر است از کس دیگری کمک بخواهید. این خیلی بهتر است که آنجا بنشینید و نقش متخصص چیزی را بازی کنید که واقعاً نیستید.من هم همین کار را می‌کنم. همواره سعی می‌کنم از قبل با آن‌ها صحبت کنم. خیلی موارد، فقط لازمست ۵ دقیقه صرف کنید و به خوبی می‌فهمید چه چیزی از شما می‌خواهند. گاهی کمی پیچیده‌تر است. اخیراً برای یک مشتری کار می‌کردم که بعد از جلسه مشاوره معلوم شد آنها اصلاً هیچ مشاوره‌ای نمی‌خواسته‌اند بلکه می‌خواستند من بنویسم که آنچه آن‌ها انجام داده‌اند درست بوده است! قضیه کاملاً سیاسی بود و این واقعاً ناگوار بود. من از ادامه کار با آن‌ها کناره‌گیری کردم زیرا این مضحک بود. اما در حالت کلی، از قبل صحبت کردن با آن‌ها ایده خوبی است. گاهی به آنها می‌گویم که من این چیزها را نمی‌دانم، بگذارید یکی از همکارانم را بیاورم یا می‌گویم به شما پیشنهاد می‌کنم که از فلان فرد درخواست کنید. یک بار یک شرکت من را برای کار معمول DSL در زمینه جاوا و Spring استخدام کرد. من یک روز آنجا مشغول بودم تا فهمیدم که آنها DSL نمی‌خواهند فقط می‌خواهند از Spring استفاده کنند. به آن‌ها گفتم چرا با ابرهارد ولف تماس نمی‌گیرید؟ او را استخدام کنید.بله، برای من و هم برای شرکتی که در آن کار می‌کنم یعنی شرکت IT Agile همین طور است. فقط شما نیستید که می‌توانید بگویید که شما نباید از من درخواست کنید و از کس دیگری درخواست کنید بلکه شرکت شما هم فکر می‌کنم همین رویه را باید پیروی کند. این که بگوید ما بر روی فلان چیز و بهمان چیز تمرکز داریم. مثلاً اگر شما دوست دارید که در مورد تیم‌های چابک توزیع شده جهانی مشاوره شوید از فلان شخص (اسمی در مصاحبه گفته شد که متوجه آن نشدم - مترجم) درخواست کنید.شما چطور در مورد قیمت تصمیم می‌گیرید؟ منظورم این است که شاید معنی ندهد که بگوییم در اینجا و در حال حاضر باید X دلار در روز بپردازید زیرا این وابسته به کشور و صنعتی است که در آن مشغول هستید. شما چطور قیمت را تعیین می‌کنید؟به آنها می‌گویم از مدیرم بپرسید! :-)من مستقل بودم، هنوز هم مستقل هستم اما این روزها ...پس شما نمی‌توانید از مدیرتان بپرسید؟ :-)من هم می‌خواهم که از مدیرم بپرسند که همان شماره تلفن است فقط اسمش فرق می‌کند! :-) روشی که عموماً استفاده می‌کنم این است که می‌گویم اگر روزانه فلان مبلغ را بگیرم خوبه و اگر متوجه شوم شرکتی که من را خواسته یک بانک است و کلی پول دارد، ۲۰۰-۳۰۰ یورو به آن مبلغ اضافه می‌کنم و اگر یک شرکت کوچک باشد که بگویند ما نمی‌توانیم این مقدار را بپردازیم، اگر یک مسئله جالب باشد یا فقط ۵ کیلومتر با جایی که زندگی می‌کنم فاصله داشته باشد یا چیزی باشد که بتوانم خودم یادگیری داشته باشم، مبلغ را کاهش می‌دهم. اما فکر می‌کنم برای مشاور، مهم است که وقتی برای یک پروژه مشتری می‌رود، عدد مشخصی را در ذهن داشته باشد زیرا آن‌ها می‌خواهند بدانند شما چقدر می‌خواهید.من فکر می‌کنم به اینکه چند ساعت در پروژه شرکت می‌کنید هم بستگی دارد. آیا می‌خواهند فقط برای چند روز شما را داشته باشند یا چند سال؟بله، درست است. به چیزهای زیادی وابسته است. یکی از آن‌ها البته این است که شما در مورد آن موضوع خاص چقدر معروف هستید. اگر برای چیزی معروف هستید و آن‌ها دقیقاً برای همان موضوع شما را استخدام می‌کنند روشن است که می‌توانید مبلغ بیشتری درخواست کنید. به عنوان مثال من در سال ۲۰۰۴ با BMW همکاری کردم. در آن زمان من تجربه‌هایی در مورد توسعه برآمده از مدل داشتم اما مطلقاً هیچ تجربه‌ای در مورد نرم‌افزارهای تعبیه‌شده (Embedded Software) نداشتم. آن‌ها از من پرسیدند که آیا می‌خواهم با ایشان کار کنم. من گفتم: بله، من می‌توانم در مورد توسعه برآمده از مدل کمکتان کنم اما هیچ تجربه‌ای در مورد سیستم‌های تعبیه شده ندارم، من با نرخ کمتر از آنچه به‌طور معمول می‌گیرم موافقت نمی‌کنم اما در حین این پروژه شما چیزهای زیادی در مورد سیستم‌های تعبیه‌شده یاد می‌گیرم. بنابراین در نهایت با نرخی کار کردم که عموماً با آن نرخ کار نمی‌کردم اما خیلی خوب بود، آنجا برای من یک سال طول کشید و واقعاً خیلی یاد گرفتم و معامله خوبی بود. چیزهای شبیه به این هم اتفاق می‌افتد.کمی در مورد توانایی‌ها یا مهارت‌هایی که برای یک مشاور خوب بودن نیاز دارید صحبت کنیم. از دیدگاه فنی باید واقعاً موضوعی را که در موردش مشاوره می‌دهید را بشناسید. فکر می‌کنم این مسأله روشن است. و طبق تجربه‌های من ایده خوبی است که این را آشکار کنید مثلاً با مقالات، صحبت در کنفرانس‌ها و ... تا همه کسانی که مشتریان بالقوه شما هستند شما را به این موضوعات بشناسند زیرا این باعث می‌شود که مشتری‌های بالقوه راحت‌تر پیدا شوند.بله، این پیدا کردن مشتریان را آسان‌تر می‌کند زیرا ممکن است شما را در کنفرانس‌ها ببینند و مثلاً به شما ایمیل بزنند. بنابراین واقعاً نیاز زیادی به بازاریابی و فروش و این چیزها نخواهید داشت.بله، من واقعاً هیچ‌گاه چنین کارهایی نکرده‌ام. من به عنوان مشاور، هیچ‌گاه هیچ نوع کار مربوط به فروشی انجام نداده‌ام. در ۹۰٪ کارهایی که کرده‌ام مشتری‌ها به سمت من آمده‌اند.شاید این خاص شما باشد! :-)مطمئن نیستم. اینطور فکر نمی‌کنم. اگر به دیگرانی که پروفایل روشنی دارند مثلاً پیتر هسباخ، ماتیاس برن یا فرانک بوشمان نگاه کنید، من فکر نمی‌کنم که آنها مشتری‌ها را صدا کنند که آیا می‌توانیم برایتان کار کنیم. فکر نمی‌کنم این‌طور جواب بدهد.بله، ولی شاید دقیقاً همان افراد این‌طور باشند، افراد معروفی که زیاد در کنفرانس‌ها شرکت می‌کنند، اینها الان به ذهن شما رسیدند. شما در مورد افراد دیگر فکر نکردید مثلاً کسانی که چند باری در کنفرانس‌ها شرکت کرد‌ه‌اند ...آنچه من می‌گویم این است که من در مورد روش دیگر مشتری پیدا کردن نمی‌توانم صحبت کنم زیرا هیچ‌گاه انجامش نداده‌ام. شاید شما بتوانید. شاید شرکت شما، شرکت IT Agile بتواند. من نمی‌دانم.ما هم در شرکت IT Agile بازاریابی‌های زیادی با کارهایی از قبیل صحبت در کنفرانس‌ها و نوشتن کتاب کرده‌ایم. ما چیزهای زیادی از این‌جور محصولات تبلیغاتی مثلاً روزنامه دیواری و ... را داشته‌ایم.شما کافی‌ماکس داشتید!ما کافی‌ماکس داشتیم، خودکار داشتیم، ... فکر می‌کنم چیزی که در مورد این محصولات تبلیغاتی مهم است این است که رابطه روشنی با شرکت و پروفایل شما داشته باشد. همه شرکت‌ها خودکارهای تبلیغاتی دارند. این مهم نیست که شما خودکار و پَد تبلیغاتی داشته باشید. این‌ها رابطه‌ای با شرکت و پروفایل‌ شما نمی‌سازند. خیلی جذاب‌تر است که محصولات تبلیغاتی داشته باشید که افراد آن را مستقیماً به محیط و کارهای شما نسبت دهند. ما در IT Agile این‌طور فکر می‌کنیم. این فقط من نیستم، من همه آن قطعات و کالاهای تبلیغاتی IT Agile را اختراع نکرده‌ام. بیشترشان را آنا هوک، اختراع کرده است. فکر می‌کنم خلق این چیزهای کوچک کار فوق‌العاده‌ای بوده است، شما می‌توانید آنها را به مهندسی نرم‌افزار و در انتها به IT Agile منتسب کنید.بله، ما در مورد مهارت‌های یک مشاور صحبت کردیم. فکر می‌کنم یکی از این توانایی‌ها که شما قبلاً به آن اشاره کردید گوش دادن است و فقط گوش دادن هم نیست، باید متوجه شوید و نوع مشکلاتی که تیم دارد را بفهمید و همین طور باید تا حدودی تحرکات تیم را متوجه شوید، اینکه دو سه نفر کلیدی در تیم چه کسانی هستند که اگر دانش را به آنها منتقل کنید آن‌ها می‌توانند آن را بیشتر گسترش دهند. بنابراین فکر می‌کنم آشنا شدن با افراد و مسائل‌شان و تلاش برای فهمیدن اینکه تیم چطور کار می‌کند، مطلب مهم دیگر است.بله، کلاً مهارت‌های ارتباطی. فهمیدن، گوش دادن و توانایی توضیح دادن شفاف چیزها به افراد، توضیح دادن مفاهیم، توضیح دادن ایده‌ها. واقعاً این‌طور نیست که اگر ایده فوق‌العاده‌ای در ذهن داشته باشید لزوماً می‌توانید آن را منتقل کنید.این هم جالب است که [داشتن این مهارت‌ها] با صحبت کردن در کنفرانس‌ها و نوشتن مقاله، مشابهت دارد زیرا آن‌ها هم مربوط به انتقال دانش‌ هستند. اگر یک مشاور، ارائه‌ها و نوشته‌های خوبی داشته باشد، نشانه خوبی است که اگر او را استخدام کنید، می‌تواند دانش و ایده‌هایش را به تیم شما منتقل کند. درست است؟بله، دقیقاً. ما الان در مورد پروفایل شفاف صحبت کردیم. مثلاً شاید افراد شما را به این بشناسند که در DSL ها خوب هستید، فکر کنم بهتر است که این‌ها هر نیمسال یک‌بار، تغییر نکنند، مثلاً امسال متخصص طراحی باشید، سال بعد متخصص فرآیندهای چابک باشید، بعد متخصص OSGi، بعد Scala، بعد متخصص Clojure، بعد متخصص Tomcat، بعد متخصص Spring و بعد ... . برای من این موضوع جالب است که در حالی که تنها در دو جنبه فرآیندهای چابک و OSGi فعال هستم، حتی در این شرایط که واقعاً به هر دو جنبه علاقه دارم، گاهی افراد گیج می‌شوند و از من می‌پرسند که: واقعاً؟! شما در زمینه فرآیندهای چابک هم کار می‌کنید؟ جالبه!این خیلی ساده‌تر است که برای یک مدت طولانی بر روی یک موضوع خاص تمرکز کنیم و بین موضوعات مختلف جابجا نشویم.وقتی مشتری‌ها تلاش می‌کنند چیزی را برای من توضیح دهند، یکی از چیزهایی که به‌صورت منظم انجام می‌دهم این است که گوش می‌دهم و تلاش می‌کنم بفهمم. بعد آنچه گفته‌اند را دوباره با زبان و کلمات خودم بیان می‌کنم، یا شاید با دیاگرام و روی تخته تلاش می‌کنم چیزها را توضیح دهم. شاید بتوانم این تکنیک را توصیه کنم اینکه فقط تلاش نکنید منفعلانه گوش دهید بلکه تلاش کنید آن را درک کنید و با آن دانش، با گسترش دادن یا مثال ساختن از آن، کاری انجام دهید.بله، من فکر می‌کنم این یک تکنیک شناخته‌شده در روانشناسی هم هست، تکنیک گوش دادن فعال.بنابراین بیایید به نقاط مثبت و منفی این شغل نگاهی بیاندازیم. بیا با جنبه‌های منفی آغاز کنیم که نمی‌توان از دستش خلاص شد. فکر می‌کنم یک مورد منفی ناامیدکننده خیلی خیلی بزرگ وجود دارد که ...سفر کردن؟بله، سفر کردن آزار می‌دهد!من می‌توانم بگویم حتی اگر کارت عضویت از هر کدام از خطوط هوایی جهان را داشته باشید، وضعیت تنها کمی بهتر می‌شود زیرا می‌توانید در یک اتاق ساکت بنشینید و غذا داشته باشید و ... اما با این وجود آزار می‌دهد!اگر می‌خواهید مشاور شوید باید بتوانید سفر کنید و هرچه مسن‌تر شوید کم‌انگیزه‌تر می‌شوید. می‌توان پیش‌بینی کرد که داریم ریسک می‌کنیم.بله، خصوصاً اگر خانواده و فرزندانی دارید.ولی مشکل اینجاست که پروژه‌های جذاب معمولاً در آن جاهایی نیست که شما زندگی می‌کنید مگر آنکه در سیاتل یا سانفرانسیسکو باشید. اما اگر یک آدم معمولی در یک شهر معمولی از یک کشور معمولی هستید، همواره باید بین پروژه‌های جذاب و پروژه‌های خانگی انتخاب کنید. الان من حدود ۱۰ سال است که به عنوان مشاور کار می‌کنم و فقط ۲ هفته پیش بود که توانستم برای یک مشتری کار کنم که بتوانم شب‌ها پیش پدر و مادرم باشم. معمولاً مشتری‌ها در جای دیگری هستند و باید در هتل اقامت کنید و همه دردسرهای سفر را خواهید داشت.حتی اگر مشتری خوبی باشد و هتل خوبی باشد، کمک می‌کند که فقط کمی مسائل بهتر و ساده‌تر و خانوادگی‌تر شود اما فقط کمی.وقتی جوان بودم (یعنی وقتی بچه بودم :-))، من یک سال تمام نزد مشتری کار می‌کردم. روشی که جبرانش می‌کردم این بود که در طول تابستان برای ۲-۳ ماه، تعطیل می‌کردم بنابراین چیزی داشتم که منتظرش باشم. با این حال در رابطه‌هایم دچار مشکل می‌شدم. بنابراین، این دردآور است، ممکن است ارزشش را داشته باشد، من هنوز به‌عنوان مشاور کار می‌کنم اما به دلایل مشخصی، دیگر به آن مقدار سفر نمی‌کنم. اما شما باید به این مسئله آگاه باشید.مورد منفی دیگر؟ چیزی سراغ دارید؟فکر می‌کنم یک مورد منفی دیگر این است که نمی‌توانید برای مدت طولانی با یک تیم باشید و همکارانی پیدا کنید. ما عموماً در IT Agile جلساتی داریم، ما داخل شرکت به هم همکار می‌گوییم اما مانند این نیست که داخل یک تیم توسعه محصول باشید. هنگام توسعه محصول، افراد را هر روزه می‌بینید و با آن‌ها آشنا می‌شوید و یک خانواده کاری دارید. اما در اینجا آن حس را ندارید مگر آنکه برای جایی به مدت خیلی طولانی کار کنید. من برای کاری به مدت ۶ سال مشغول بودم البته نیمه‌وقت بود اما مربوط به یک پروژه بود، در انتها همان حس را داشتم که گویی بخشی از خانواده‌ام هستند اما این استثنا است.یک ریسک دیگر در این ارتباط وجود دارد که اگر با تیمی واقعاً کار نکنید، برایتان سخت می‌شود که یاد بگیرید. من می‌خواهم دوباره در مورد مثال یخچال‌سازی صحبت کنم. من از آن شرکت تا حدی آموختم که چطور یخچال می‌سازند اما نکته اینجاست که من مشاور یخچال‌‌سازی نیستم و نهایتاً برایم اهمیتی ندارد. اگر شما همیشه خبره‌ترین فرد در یک موضوع خاص باشید، احتمال این‌که در آن موضوع از دیگران چیزی یاد بگیرید خیلی کم است؛ قطعاً چیزهای دیگری را یاد می‌گیرید اما آن‌ها خیلی مرتبط با پیشرفت حرفه‌ای شما نیستند. بنابراین فکر می‌کنم این یک مشکل است به‌همین خاطر خیلی از مشاورها به کنفرانس‌های زیادی می‌روند و یک شبکه بزرگ دارند و با افراد زیادی صحبت می‌کنند، حتی اگر با هم در یک شرکت نباشند و مانند یک خانواده بزرگ نباشند اما همچنان یک شبکه بزرگ از دوستان و دیگر همکاران تشکیل می‌دهند تا این را تا حدی جبران کنند.بله، من واقعاً دوست دارم که به کنفرانس‌های زیادی بروم و با این افراد و حضار دیگر صحبت کنم. تلاش می‌کنم که از کنفرانس‌ها برای یاد گرفتن از دیگران استفاده کنم. نه اینکه به سخنرانی‌هایشان گوش دهم بلکه با آن‌ها صحبت می‌کنم و به حرف‌هایشان گوش می‌دهم.بله، موافقم. و در نهایت، ریسک دیگر این است که به یک سخنران تبدیل شوید، به کسی که فقط سخن می‌گوید. اینکه تعدادی اسلاید آماده داشته باشید و می‌دانید که چه بگویید اما هیچ‌گاه واقعاً عمل نمی‌کنید فقط سخن می‌گویید. از یک طرف این ریسک وجود دارد و نباید به این طریق رفتار کنید اما به‌عنوان یک مشاور، گاهی این حس را دارید که تا حدی اجتناب‌ناپذیر است. من همواره وقتی پروژه‌ها در یک جهت صحیح قرار می‌گیرند، آن‌ها را ترک می‌کنم و تا آخر کار، وقتی مشکلات بزرگ واقعی پیدا می‌شوند نمی‌ایستم. شما می‌دانید که چگونه است! ابتدای کار، همه چیز راحت است. گاهی وقت‌ها حس می‌کنم که ترجیح می‌دهم در جایی کار کنم که واقعاً چیزی را بسازیم نه اینکه فقط در مورد ساختن چیزها صحبت کنیم.بله، قطعاً. من پروژه‌هایی که واقعاً در آن چیز مشخصی را انجام می‌دهیم را بیشتر دوست دارم، اهمیت ندارد که از جنبه فنی جذاب باشد یا از جنبه فرآیند توسعه. اما جذاب است که برای مدت طولانی در کنار تیم باشید تا ببینید در طول زمان، چه رخ می‌دهد و شما با مشاوره‌تان چه مشکلاتی را بعد از یک یا دو سال ایجاد کرده‌اید! فکر می‌کنم بعد از این مدت زمان، اگر با تیم همراه شوید، سودمند است زیرا در مورد تجربیاتی که به اشتراک گذاشته‌اید، فرا می‌گیرید. در غیر این صورت در انتها به شرایطی خواهید رسید که دانشتان تنها از صحبت کردن با دیگران حاصل می‌شود و تجربه‌هایتان در طول زمان کمتر و کمتر می‌شود و دانشتان را تنها از برخی پروژه‌های مشاوره تولید خواهید کرد که هیچ‌گاه واقعاً آنها را تا آخر انجام نداده‌اید.بیا در مورد جنبه‌های مثبت مشاور بودن صحبت کنیم.فکر می‌کنم مطلب واضح این است که خیلی افراد جالب را ملاقات می‌کنید. تعداد زیادی تیم‌های خوب را می‌بینید. می‌توانید فناوری‌های مختلف، پروژه‌های مختلف، سیستم‌های مختلف و حوزه‌های مختلف را ببینید که جذاب است. هیچ‌گاه واقعاً کسل‌کننده نمی‌شود.خوبه! :-)شما تجربه دیگری دارید؟ :-)موافقم که همیشه محیط‌ها متفاوتند به‌عنوان مثال اخیراً برای یک شرکت کار کردم که ماشین‌های لیتوگرافی می‌ساخت که بخشی از تولید تراشه بود و با حدود یک ساعت و نیم آموزش برای آشنایی در مورد چگونگی کار کردن این ماشین‌ها آغاز کردند که به‌شدت جذاب بود. همین یادگرفتن در مورد سیستم‌ها و محیط‌های مختلف و کارهای جالب مختلفی که افراد می‌کنند، یک جنبه بسیار بسیار عالی این شغل است. اینکه هیچگاه کسل نمی‌شوید را من صد در صد مخالفم زیرا نمی‌دانم تا به‌حال چه تعداد DSL های XText در سطح Hello World ساخته‌ام. احتمالاً دیگر بهتر از این نمی‌شوم! این کسل‌کننده است! به‌همین خاطر است که همیشه تلاش می‌کنم تا مطمئن شوم که  مشتریانم، دست‌کم، حوزه خاصی که می‌خواهند برایش زبان بسازیم را به من پیشنهاد دهند زیرا واقعاً دوست ندارم که Hello World استاندارد خودم را بسازم زیرا خیلی کسل‌کننده است. در حالت کلی، موافقم که [آنچه گفتید] مزیت بزرگ این شغل است.فکر می‌کنم این هم مزیت است که در ساختارهای مرسوم شرکت‌ها، قرار نمی‌گیرید.منظورتان سیاست‌ها [یِ سازمانی] است؟سیاست‌ها، سلسله‌مراتب‌ها، رئیس‌تان، مقامتان و ... . این‌ها واقعاً در کارهای روزمره‌تان در سایت مشتری، مطرح نیست. گاهی آن نحوه کار کردن در شرکت‌های بزرگ و سلسله‌مراتب بزرگ، آزاردهنده است!یا نحوه کار نکردن!یا شاید نحوه کار نکردن! گاهی خوب‌ است که می‌گویید بسیار خوب، کار تمام شد و به شرکت کوچک مشاوره‌ای‌تان برمی‌گردید و یا به‌سراغ تیم دیگری می‌روید و زندگی می‌تواند شکل دیگری پیدا کند.نکته مثبت دیگر می‌تواند این باشد -دقت کنید که آن را بسنجید- که می‌توانید به‌صورت مستقل کار کنید. اگر می‌خواهید که سفر کنید و می‌خواهید کل سال را کار کنید، می‌توانید این مقدار پول را بدون ریسک خاصی کسب کنید، این‌طور نیست که ده‌ها هزار یورو برای چیزی سرمایه‌گذاری کنید. مانند استارتاپ‌ها نیست البته استارتاپ چیز دیگری است، با یک استارتاپ موفق، می‌توانید خیلی بیشتر از یک مشاور درآمد داشته باشید اما احتمالاً اگر در یک شرکت عادی کار کنید، نمی‌توانید به این مقدار درآمد داشته باشید. من این‌طور فکر می‌کنم البته هیچ‌گاه آن کار را نکرده‌ام. البته لازمه‌اش این است که کل سال‌تان را یعنی ۲۰۰ روز در سال را کار کنید و آن را به تکه‌های کوچک مشاوره‌های مجزا‌ بشکنید زیرا اگر برای یک پروژه یکسان برای مدت طولانی کار کنید، حقوق روزانه‌تان واقعاً پایین می‌آید. بنابراین اگر می‌خواهید که مسافرت کنید و مشتری‌های زیاد متفاوتی داشته باشید، می‌توانید مقدار درآمد زیادی داشته باشید. این یک جنبه جذاب این شغل است.بله، خصوصاً برای کسانی که برای خودشان کار می‌کنند و مشاور مستقل هستند.بله، اگر حقوقتان به مقدار پولی که خودتان درمی‌آورید، بستگی داشته باشد. واضح است که در مورد افرادی که برای خودشان کار می‌کنند و مستقل هستند و همین طور چنانچه در شرکت‌های مشاوره‌ای سنتی کار کنید به این شکل است. من می‌دانم که دست‌کم در برخی از آنها، حقوق شما به مقدار درآمدی که خودتان برای شرکت درمی‌آورید بستگی دارد. در آنجا نیز این همبستگی [بین درآمدی که تولید کرده‌اید و حقوقتان] وجود دارد.مطلب این است که اگر تعداد زیادی مشاوره‌های کوچک انجام دهید، باید انعطاف خیلی زیادی در مورد تعطیلی‌‌هایتان داشته باشید. مجبورید وقتی می‌خواهید تعطیلات داشته باشید، کار کنید. من دیگر این کار را نمی‌کنم به همین خاطر است که درآمدم طی چند سال اخیر کاهش یافته است چون نمی‌خواهم همه وقتم را با مشتری سپر کنم و هر روزه سفر کنم.بنابراین، این مورد [درآمد] هم قطعاً بالقوه یک مورد مثبت است. اما آیا مورد مثبت دیگری هم در مورد شغل ما وجود دارد؟ به نظرم، بزرگترین مزیت شغل ما همین یادگیری در مورد سیستم‌های مختلف و جاهایی است که افراد آن را استفاده می‌کنند. منظورم این است که [بفهمید] فناوری‌هایی که شما می‌توانید بفروشید را افراد چگونه و کجا استفاده می‌کنند. زیرا اگر بر موضوع خاصی تمرکز کنید و روی آن موضوع با مشتری‌های مختلف کار کنید، می‌توانید ببینید که مثلاً افراد DSL ها را چگونه استفاده می‌کنند و با این مشاهدات خیلی یاد می‌گیرید که جذاب است.بسیار خوب، فکر می‌کنم اینها اساساً چیزهایی بودند که آماده کرده بودیم. درست است؟بله، چیزهایی بودند که بصورت نقل قول آماده کرده بودیم.بله، از قصد خیلی محاوره‌ای ضبط کردیم و برایش خیلی زیاد آماده نکردیم. ما هر دو تجربه مشاوره داریم و نمی‌خواستیم در قالب مصاحبه‌گر و مصاحبه‌شونده اجرا کنیم. بنابراین شاید یک کمی آماده‌نشده و آشفته به نظر برسد. با این حال امیدواریم خوشتان آمده باشد.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Fri, 06 May 2022 16:31:42 +0430</pubDate>
            </item>
                    <item>
                <title>الگوها</title>
                <link>https://virgool.io/se-radio/%D8%A7%D9%84%DA%AF%D9%88%D9%87%D8%A7-vrtk7c2h8jit</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت اول از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت، مایکل و مارکوس در ارتباط با الگوها صحبت می‌کنند. آن‌ها با الگوهای «بیشتر استفاده شده» خود آغاز کرده و به سراغ برخی جزییات تاریخچه الگوها می‌روند. سپس اشکال مختلف الگوها و همین‌طور برخی تصورات غلط درباره الگوها را توضیح می‌دهند. بحث‌های دیگر این مصاحبه شامل حوزه‌هایی که الگوها آن‌ها را پوشش داده‌اند و همین‌طور زبان‌های الگو است. ۳ مثال خیلی مطرح از الگوها که می‌توانید عنوان کنید، کدامند؟فکر می‌کنم الگویی که بیشترین استفاده را داشته و احتمالاً بیش از همه شناخته شده است، الگوی ناظر (Observer) است که در آن یک شیء، مجموعه‌ای از اشیاء دیگر را از وقوع تغییرات باخبر می‌کند. مثلاً اگر یک برنامه گرافیکی داشته باشید که در آنجا چند منظر (View) داشته باشید که تغییراتی در نوعی ساختارهای داده را انعکاس می‌دهند، وقتی ساختار داده تغییر می‌کند، اشیاء مختلف، اشیاء منظر را از تغییرات باخبر می‌کند و اشیاء منظر، در مورد داده‌های تغییریافته پرس‌وجو می‌کنند و خود را متناظر با آن تغییر می‌دهند.الگوی معروف دیگر، احتمالاً الگوی نماینده (Proxy) است. این الگو، همیشه در سیستم‌های از راه دور (Remoting Systems) استفاده می‌شود. به‌جای اینکه با یک شیء مستقیم صحبت کنید -که در مورد شیء‌های دور (Remote Objects) امکانپذیر نیست- با یک شیء محلی صحبت می‌کنید که مانند شیء دور به نظر می‌رسد و شیء محلی یا همان نماینده، همه فراخوانی‌ها را از طریق شبکه یا روش‌های دیگر، به شیء دور، ارسال می‌کند.الگوی دیگر، الگوی رآکتور (Reactor) است. فکر کنم بهتر باشد که شما توضیحش دهید.رآکتور، اساساً کارهای ناهمبسته‌سازی (Decouple)، مقسم‌سازی (Demultiplexing) و توزیع (Dispatching) رخدادها را انجام می‌دهد. به‌عنوان مثال، در مورد رخدادهای شبکه این کار را انجام می‌دهد و این امور را از منطقی که برنامه برای رسیدگی به رخدادها دارد مجزا می‌سازد. در یک طرف رآکتور را دارید و در طرف دیگر رسیدگی‌کننده‌هایی (Handler) دارید که برای رخدادهای مختلف در رآکتور ثبت‌نام (Register) می‌شوند. هرگاه یک رخداد ثبت‌نام شده رخ دهد، رسیدگی‌کننده موردنظر درگیر شده و به آن عکس‌العمل نشان می‌دهد.آیا این الگو، غالباً در سیستم‌های مقیاس‌پذیرِ چندنخی (Multithread) استفاده می‌‌شود؟در واقع در سیستم‌های چندنخی خیر. رآکتور می‌تواند به خوبی برای طراحی برنامه‌های تک‌نخی مقیاس‌پذیر استفاده شود. البته می‌توانید در محیط‌های چندنخی نیز با آن کار کنید. در آن صورت به الگوهای دیگر مثلاً الگوی پیشوا-پیروان (Leader/Followers) نیاز دارید تا به همروندی، بپردازید.بسیار خوب. قبل از اینکه بخواهیم به جزییات زیاد بپردازیم بهتر است که کمی در مورد تاریخچه الگوها صحبت کنیم. فکر کنم کانینگهام اولین کسی باشد که بخواهیم در موردش صحبت کنیم. درسته؟کانینگهام و کنت بک در سال ۱۹۸۷ کار بر روی مستندسازی حداقل ۵ الگوی واسط کاربری (User Interface) را آغاز کردند و آن را در c2.com مستند کردند. از آنجا بود که همه چیز شروع شد. در دهه ۹۰ اریک گاما ، این سبک نگارش الگو را آغاز کرد که بعداً در سال ۱۹۹۵ به کتاب معروف الگوهای طراحی انجامید که توسط اریک گاما ، ریچارد هلم ، راف جانسون و جان وسیدس، معروف به دسته چهارتایی‌ها (Gang of Four)، نوشته شد.جالب است زیرا فکر می‌کنم غالب افراد فکر می‌کنند که کتاب GOF، اولین نوشته در مورد الگوها در دنیای IT بوده است اما اینطور نیست.بله، کمی بعد از GOF، کار کتاب معماری نرم‌افزار الگو‌گرا (Pattern Oriented Software Architecture) آغاز شد که بوشمن ، منییِر ، رونرت ، سامرلد و استال نویسندگان جلد اول کتاب بودند. بیشتر آن را با عنوان POSA1 می‌شناسند.تفاوت‌هایی بین الگوهای کتاب GOF و کتاب POSA هست. الگوهای کتاب GOF، الگوهای طراحی کلاسیک هستند. محتوای کتاب POSA1 چیست؟بله. POSA1 در ارتباط با الگوهای معماری است. گاهی با عنوان سبک‌های معماری (Architectural Styles) نیز نامیده می‌شود.بسیار خوب. قبل از آنکه بخواهیم در مورد محتوای برخی الگوهای خاص صحبت کنیم، فکر می‌کنم بهتر باشد یک نگاهی به شکل الگوها بیاندازیم. الگوها با یک روش کاملاً مشخص، مستند می‌شوند. در واقع، چندین روش وجود دارد. فکر می‌کنم در کتاب GOF برای هر الگو، ۱۱ بخش داریم. درسته؟بله، فکر می‌کنم.مهمترین آنها، زمینه (Context)، مسأله (Problem) و راه حل (Solution) است. اگر بخواهیم الگو را تعریف کنیم گفته می‌شود الگو، مسأله‌ای معروف در یک زمینه خاص است که راه حل مشخصی دارد. مستندسازی یک الگو تنها در صورتی معنی می‌دهد که افراد زیادی با مسأله‌اش احتمالاً در زمینه‌های تکنیکی مختلف مواجه شده باشند و راه‌حل‌های مختلفی داشته باشد. بخش زمینه یک الگو هر محیط یا شرایطی که در ارتباط با نرم‌افزار دارید را توضیح می‌دهد. بعد از آن بخش مسأله مطرح می‌شود و بعد از آن راه حل را نشان می‌دهید که کمک می‌کند در آن زمینه خاص مسأله را حل کنید. بخش مهم دیگر الزامات (Forces) است. شما تنها در صورتی می‌توانید یک مسأله را به یک روش خاص حل کنید که بدانید هنگام حل آن، چه مواردی را باید در نظر داشته باشید؛ مواردی از قبیل اینکه سیستم باید سریع اجرا شود یا اینکه کمترین مقدار ممکن از حافظه را مصرف کند. وقتی دارید در یک الگو مسأله را توضیح می‌دهید همواره باید الزاماتی که شما را در جهت یافتن راه حل کمک می‌کند را توضیح دهید. به این شکل یک دانش قابل استفاده مجدد تهیه می‌شود که دیگران می‌توانند آن را بخوانند و در محیط یا نرم‌افزار خودشان به‌کار گیرند.در این مورد، من اغلب اصطلاحِ ‌زمینه حاصل (Resulting Context) را می‌شنوم. زمینه حاصل شده از یک الگو واقعاً چیست؟اگر راه‌حل یک الگو را توضیح دهید و آن راه‌حل به روش خاصی مسأله را با درنظر گرفتن الزاماتش حل کند، بعد از پیاده‌سازی آن راه حل، پیامدهایی حاصل خواهد شد. مثلاً اینکه حل مسأله به یک روش، باعث می‌شود سیستم خیلی سریع شود یا کند شود یا کوچک شود یا مقیاس‌پذیر باشد یا ... . بعد از آن، می‌توانید مسائل جدیدی که با بکارگیری آن الگو، به‌وجود می‌آیند را توضیح دهید که جاده را برای الگوهای دیگری که در ادامه الگوی کنونی می‌آیند باز می‌کند. به این ترتیب که اگر شما فلان الگو را پیاده‌سازی کنید، می‌توانید پیاده‌سازی الگوی دیگری را نیز در نظر بگیرید زیرا پیامد حاصل شده از آن، چنین چیزی را توصیه می‌کند. این موضوع خصوصاً در زبان‌های الگو (Pattern Languages) و دنباله‌‌های الگو (Pattern Sequences) اهمیت می‌یابد که فکر می‌کنم بعداً در مورد آن توضیح دهیم.من می‌دانم برای الگوها، شکل الکساندری وجود دارد، شکل GOF را داریم، POSA هم شکل خودش را دارد، شکل پورتلند را هم داریم و ... . تفاوت‌های اصلی میان این شکل‌ها چیست؟ چرا شکل‌های مختلفی وجود دارد؟فکر می‌کنم جامعه قبول دارد که همان‌ طور که قبلاً گفتم الگو بیان یک مسأله در یک زمینه خاص با یک راه حل خوب است. با این وجود انواع مختلفی از الگوها وجود دارد که در ادامه خواهیم دید. این الگوهای مختلف می‌توانند در شکل‌های لفظی متفاوتی بهتر توضیح داده شوند. به‌عنوان مثال، اگر الگویی داشته باشید که خیلی فنی باشد و مربوط به تکنیک طراحی باشد، شکل GOF می‌تواند خیلی مفید باشد زیرا در این شکل، بخش‌هایی مانند ساختار (Structure) را دارید که عموماً در آنجا یک نمودار کلاسی یا چیز مانند آن می‌افزایید و همین طور بخش تعاملات (Interactions) را دارید که در آنجا از نمودار توالی (Sequence Diagram) یا چیزهای شبیه به آن استفاده می‌کنید تا نشان دهید که تعاملات میان شرکت‌کنندگان در الگو چگونه شکل می‌گیرد. با این وجود اگر یک الگوی سازمانی (Organizational Pattern) داشته باشید -که ما چند دقیقه دیگر در مورد آن صحبت خواهیم کرد- این الگوها لزوماً نمی‌توانند با این‌گونه اصطلاحات و نمودارهای فنی بیان شوند. بنابراین شکل‌های دیگری وجود دارد که برای این نوع از الگوها، مفیدتر است.در مورد شکل الکساندری، جالب است که این شکل در اصل توسط کریستوفر الکساندر ، ابداع شده است که یک معمار ساختمان است و ارتباطی با نرم‌افزار ندارد. او کسی است که در اصل، استفاده از این شکل الگوها برای توضیح دادن چیزها را اختراع کرد. او کتابی با عنوان یک زبان الگو نوشت که فکر می‌کنم ۲۵۳ الگو دارد که در قالب یک زبان الگو سازماندهی شده‌اند. او کمک می‌کرد که افراد طراحی‌های خوبی برای شهرها، ساختمان‌ها، اتاق‌های نشیمن‌ و چیزهای شبیه به آن داشته باشند. او از شکل خاصی استفاده می‌کرد که ساختار خیلی کوچکی داشت. اینطور نبود که مثلاً ۱۱ زیربخش داشته باشد، فکر می‌کنم ۴ یا ۵ بخش داشت. اگر درست به‌خاطر بیاورم، زمینه، مسأله و الزامات آن، راه‌حل، زمینه حاصل و بعد هم مثال‌ها بود. چنانچه بخواهید چیزهای غیرفنی را توضیح بدهید، این شکل، خوب است. البته می‌توانید مباحث فنی را هم با آن توضیح دهید همان طور که ما در کتابمان، برای توضیح دادن زیرساخت‌های امور راه دور (Remoting Infrastructure) استفاده کردیم.شکل GOF، با یک تیتر آغاز می‌شود و بعد بخش‌های کوچکی، شاید یکی دو بخش داریم که هدف الگو را بیان می‌کند. سپس، با توضیح انگیزه (Motivation) ادامه می‌دهیم که عموماً یک شرایطی است که شما دوست دارید از الگو استفاده کنید. بخش بعدی، محل‌های قابل استفاده (Applicability) است که توضیح می‌دهیم در حالت کلی در چه شرایطی این الگو به‌کار می‌آید. نکته جالب این است که واقعاً هیچ بخشی که عنوانش دقیقاً راه حل باشد وجود ندارد. در ادامه بخش ساختار را داریم که ساختار راه حل توضیح داده می‌شود. سپس، شرکت‌کننده‌های مختلف توضیح داده می‌شوند به‌عنوان مثال، در مورد الگوی ناظر (Observer)، (در بخش شرکت‌کننده‌ها)، موضوع (Subject) را داریم که تغییرات را خبر می‌دهد و ناظر‌ها را داریم که چیزهایی هستند که باید از تغییرات آگاه شوند. بعد تعاملات را دارید که از یک دیدگاه پویا (Dynamic) به نحوه تعاملات بین شرکت‌کننده‌ها می‌پردازد. بعد پیامدها (Consequences) را داریم و بعد یک بخش مهم در مورد طراحی‌های سطح پایین یا پیاده‌سازی کدهای الگو داریم. معمولاً می‌توانید یک الگو را به روش‌های مختلفی پیاده‌سازی کنید. در بخش پیاده‌سازی، نحوه پیاده‌سازی یک الگو به‌صورت گام‌ به گام نمایش داده می‌شود و اگر روش‌های متنوعی برای پیاده‌سازی باشد آنها را نشان می‌دهد. بخش بعدی، کد مثالی (Sample Code) است که حتی کدهای بیشتری را فراهم می‌کند و مرتبط با انگیزه مقدماتی مطرح شده است. و بعد یک بخش خیلی مهم در توضیح الگوها داریم که استفاده‌های شناخته شده (Known Uses) است؛ یک الگو چیزی نیست که شما اختراعش کنید بلکه چیزی است که با کاوش سیستم‌های موجود، استخراجش می‌کنید. برای اینکه اثبات کنید که چیزی که توضیح داده‌اید، یک راه حلی است که شناخته شده هست و به خوبی برای حل مسأله استفاده شده است، برخی استفاده‌های شناخته شده آن را فهرست می‌کنید و توضیح می‌دهید. در انتها، شکل GOF با بخش ارجاع به تعدادی الگوهای مرتبط دیگر پایان می‌پذیرد که نقشه راهی از خلال کتاب برایتان فراهم می‌آورد.لطفاً شما هم کمی در مورد شکل POSA صحبت کنید.شکل POSA یک شکل دیگر است که در ۳ جلد گذشته کتاب استفاده شده است (در زمان مصاحبه یعنی سال ۲۰۰۶ سه جلد از کتاب POSA منتشر شده بود. در سال ۲۰۰۷ جلدهای ۴ و ۵ کتاب POSA هم منتشر شدند - مترجم). این شکل بیشتر مربوط به همان کتاب POSA است. شاید به‌ همین خاطر من شکل POSA را بیشتر دوست دارم. در شکل POSA، صریحاً یک بخش با عنوان راه حل وجود دارد و صریحاً الزامات را برجسته و فهرست می‌کند. من فکر می‌کنم خیلی باارزش است که بدانیم مصالحه‌هایی (Tradeoff) که در ارتباط با الگو وجود دارد و باید در نظر بگیریم، کدامند؟ همچنین در این شکل، صریحاً یک بخش با عنوان گونه‌ها (Variations) داریم که در آنجا تعدادی از گونه‌های مشخصی که درباره بطن الگو وجود دارد مستند می‌شود بنابراین به جای اینکه برای آن فقط یک الگو داشته باشید، گونه‌هایی از آنها را خواهید داشت. به‌غیر از آن، بخش‌های زیادی هم مشترک (با شکل GOF) است. در اینجا، بخش زمینه (Context) معادل با بخش انگیزه (Intent) [در کتاب GOF] است.بگذارید به برخی برداشت‌های نادرست در مورد الگوها بپردازیم. فکر می‌کنم چندین مورد وجود دارد. آیا دوست دارید توضیح دهید؟بله، خیلی می‌شنوم که الگوها به‌عنوان یک طرح UML نگریسته می‌شوند. اینکه الگوها همواره باید یک ساختار پیاده‌سازی و کلاسیِ شی‌ءگرا داشته باشند و الگوها فقط درمورد شیءگرایی هستند. این درست نیست. الگوها را می‌توانید برای سیستم‌های دیگر هم به‌کار بگیرید. حتی برای روش‌های غیرشیءگرای حل مسأله و برنامه‌نویسی. در برخی ابزارهای مهندسی نرم‌افزار به کمک کامپیوتر (Computer Aided Software Engineering) که امروزه ابزارهای مهندسی نرم‌افزار مبتنی بر مدل (Model Driven Software Development) خوانده می‌شوند، چیزهایی وجود دارد که طرح‌های اولیه (Blueprint) خوانده می‌شوند و الگوهایی وجود دارد اما باید در مورد اینکه آنها چه هستند دقت داشته باشید. دوست دارم شما در مورد این مطلب ادامه دهید.بله، این چیزی است که من نظر صریحی در مورد آن دارم. اغلب ابزارهای توسعه مبتنی بر مدل در مورد پیاده‌سازی الگوها به‌صورت خودکار صحبت می‌کنند که تا حدی بی‌معنی است. از یک طرف، اگر تصمیم بگیرید که می‌خواهید یک الگوی خاص را در یک شرایط خاص به‌کار ببرید، می‌توانید با ابزار تولیدکننده خود، ابزار توسعه مبتنی بر مدل یا ... مطمئن شوید که ابزار، الگوی مورد نظر را در کدی که تولید می‌کند، پیاده‌سازی می‌کند اما اینکه الگو را به چیزی که در چنین ابزارهایی خودکار شده، تنزل دهیم واقعاً ایده بدی است زیرا الگوها اساساً، [از جنس] مستندات هستند. جنبه‌های خیلی زیادی وجود دارد که نمی‌تواند خودکار شود. مواردی از قبیل الزامات، راهنمایی‌هایی که شما را هدایت می‌کند که آیا از الگو استفاده کنید و از کدام‌یک از گونه‌ها استفاده کنید و چرا و چگونه این کار را بکنید، این موارد چیزهایی نیستند که بتوانید به‌راحتی در ابزارها، خودکار کنید. بهتر است اصطلاح الگو را از خودکارسازی‌های تولید کد موجود در ابزارها مجزا کنیم. احتمالاً بهتر است آنها را قالب (Template) بنامیم. البته اگر قالب‌هایی دارید که الگوی ناظر (Observer) را پیاده‌سازی می‌کنند، خوب است که بگویید تولیدکننده کد، در داخل خود از الگوی ناظر استفاده می‌کند.برداشت نادرست دیگر که متداول است این است که الگوها، نوآوری هستند. در واقع، برعکس است. الگوها سرمشق (Best Practice) هستند. الگوها باید بکارگیری‌های شناخته شده‌ای در سیستم‌های موجود داشته باشند بنابراین دیگر نوآوری نیستند. با این حال به منظور مستندسازی و تبادل سرمشق‌ها خیلی ارزشمند هستند. به‌عنوان مثال برای حوزه‌های جدید برنامه‌نویسی، مثلاً در زمینه مهندسی نرم‌افزار جنبه‌گرا (Aspect Oriented) چنانچه الگوها را از ابتدا تنها بر پایه تجربیات خودمان بسازیم، الگو نیستند. باید حوزه‌ای که می‌خواهیم کار کنیم، بالغ شده باشد. افراد باید ابتدا بیاموزند و تجربه‌هایی داشته باشند و بعد با همدیگر، الگوها را استخراج نمایند.این به آن معناست که اغلب الگوها توسط محققان دانشگاهی نوشته نمی‌شود چراکه آنها مجبورند مقالاتی در مورد چیزهای جدید بنویسند در عوض، الگوها بیشتر توسط افراد شاغل در صنعت نوشته می‌شود. درسته؟بله.بیایید به برخی حوزه‌ها که با الگوها پوشش داده شده‌اند، نگاهی بیاندازیم. فکر می‌کنم اکثر افراد، کتاب GOF را می‌شناسند بنابراین با الگوهای طراحی آشنا هستند. [الگوهای طراحی]، الگوهایی هستند که کمک می‌کنند طراحی شیء‌گرای بهتری داشته باشید. این کمترین چیزی است که افراد باید از الگوها بدانند. فکر می‌کنم همه این را می‌دانند اما بیایید کمی در مورد برخی حوزه‌های الگوها که خیلی شناخته شده نیستند، صحبت کنیم.نزدیکترین این حوزه‌ها، حوزه معماری نرم‌افزار است و قطعاً POSA1 یکی از مثال‌های این حوزه است. همچنین موارد دیگر مثلاً الگوهای طراحی واسط کاربری، الگوهای تعاملات کاربر، الگوهای تست و الگوهای تدریس را داریم. آیا می‌خواهید در مورد الگوهای تدریس توضیح دهید؟بله، ایده این بوده است که الگوها و رویه‌های مرتبط با حوزه تدریس گردآوری و توضیح داده شود. بنابراین توضیح داده می‌شود که چطور به‌صورت مؤثر مفاد و برنامه درسی را طراحی کنیم، اجرای کلاس‌ها به چه ترتیب باشد و مواردی از این قبیل. در این ارتباط، یک انجمن بزرگ با عنوان پروژه الگوهای آموزشی شکل گرفته است که اخیراً خیلی فعال نبوده‌اند اما الگوهای خیلی جذابی در این حوزه نوشته شده است. اگر فردی هستید که با آموزش و برنامه‌ریزی کلاس‌ها سروکار دارید، خیلی می‌ارزد که به آن نگاهی بیاندازید.حوزه بعدی، مستندسازی است. در این‌باره، کتاب الگوهای مستندسازی چابک را داریم که نوشته اندرآس روپینگ است. حوزه دیگر، حوزه سازمانی است که اخیراً جیمز کوپلین و نیل هریسون به آن پرداخته‌اند (اشاره به کتاب الگوهای سازمانی توسعه چابک نرم‌افزار - مترجم) که قطعاً ارزش خواندن دارد و چیزهای زیادی می‌توانید از آن فرا بگیرید.همچنین کتاب‌هایی در مورد الگوهای میان‌افزارها (Middleware) و چیزهای زیرساختی از قبیل امور راه دور (Remoting) و مؤلفه‌ها (Component) وجود دارد که فکر می‌کنم بهتر باشد در قسمت‌های بعدی به آنها بپردازیم بنابراین اینجا وارد جزییات نمی‌شویم. درسته؟بله.فکر می‌‌کنم یک مورد که باید درموردش صحبت کنیم این است که چطور الگوها، شکل گرفتند. همان طور که قبلاً گفتم الگوها از تجربیات اجتماع، استخراج شدند. همچنین یک انجمن فعال خوبی وجود دارد که کمک می‌کنند پیشنهاد کنندگان الگوها، آنها را بهبود دهند. شاید بهتر باشد چند دقیقه در مورد کنفرانس PLoP و روش کارش صحبت کنیم.بله. PLoP مخفف زبان‌های الگوی برنامه‌نویسی (Pattern Languages of Programming) است و در اوایل دهه ۹۰ آغاز شد. فکر می‌کنم اولین کنفرانس سال ۱۹۹۴ بود. این کنفرانس‌ها یک شکل خیلی رایج دارند که رخداد‌ مهم در آنها، کارگاه‌های نویسندگان است. ممکن است توضیح دهید که یک گارگاه نویسنده چیست؟بله، ایده کنفرانس‌های در مورد الگو، این نیست که افراد بیایند و کارهای‌شان را به مخاطبینی نشان دهند که آنجا هستند و نشسته و گوش می‌دهند. البته، نویسنده‌ها به آنجا می‌روند و کارشان را عرضه می‌کنند اما بعد از آن، بازخورد می‌گیرند. اولین گام در این کنفرانس‌ها چیزی است که شبانی (Shepherding) خوانده می‌شود. شما مقاله‌تان را می‌فرستید و بعد یک نویسنده باتجربه در حوزه الگو، یک بازخورد بسیار دقیق در سطح ریز جزییات به شما می‌دهد. این روندی است که حدود ۲ ماه طول می‌کشد که معمولاً ۲ تا ۴ مرحله خواهد داشت. در نتیجه، الگوی شما نه تنها از نظر محتوا بلکه از لحاظ ساختار و زبان نیز نسبت به مقاله ارسالی اولیه بهتر خواهد شد. گام بعدی این است که به کنفرانس می‌روید و همه را ملاقات می‌کنید و کلی خوش خواهد گذشت! بعد در کارگاه نویسنده، معمولاً گروهی حدود ۶ تا ۱۲ نفر حضور دارند که معمولاً به‌صورت گرد نشسته‌اند. شما به‌عنوان نویسنده چیز زیادی نمی‌گویید، بلکه آنجا می‌نشینید و به توضیحات همکاران‌تان که الگوی شما را توضیح می‌دهند، گوش می‌دهید. آنها می‌گویند که از چه چیز الگوی شما خوش‌شان می‌آید و شما برخی ایده‌های خوب را تأیید می‌کنید. آنها همچنین به شما می‌گویند که چه چیزی در الگو باید بهبود داده شود. بعد از معمولاً حدود نیم ساعت که به حرف‌هایشان گوش دادید، ایده‌های زیادی در مورد چگونگی بهبود الگوی‌تان می‌گیرید. در نتیجه، بعد از آنکه الگویی، چنین کارگاهی را طی می‌کند، معمولاً خیلی بهتر می‌شود. حداقل از دیدگاه خوانایی بهتر می‌شود و این کمک می‌کند که کیفیت الگوهایی که منتشر می‌شود افزایش یابد.بسیار خوب. و کنفرانس PLoP اصلی همانی است که در ایلینویز آمریکا برگزار می‌شود اما انشقاق‌هایی از آن در اروپا مثلاً در اسکاندیناوی و آلمان و همین طور در جنوب آفریقا برگزار می‌شود.خوب است که اشاره نماییم که اگر به الگوها علاقه‌مندید و می‌خواهید کمی عمیق‌تر از این باشد که فقط از الگوهای طراحی استفاده کنید، احتمالاً یکی از نقاط شروع خوب، رفتن به این کنفرانس‌ها است. حتی اگر مقاله‌ای نداشته باشید کمک می‌کند که با انجمن در ارتباط باشید و از رویه کار مطلع شوید.یک لینک خوب برای بررسی، hillside.net است. این گروه انجمنی درباره الگوها است. در آنجا همه اطلاعات و لینک‌های مرتبط در مورد انجمن، الگوها، کتاب‌های نوشته شده و تقریباً همه چیز را می‌یابید.پیش از این در مورد اصطلاح زبان الگو (Pattern Language) صحبت کردیم. فکر می‌کنم باید در مورد اصطلاحات و ادبیات الگوها کمی بیشتر صحبت کنیم. آیا می‌خواهید شروع کنید؟بله. کتاب POSA1 اصطلاح سیستم الگوها (System of Patterns) را مطرح کرد که الگوهایی هستند که ارتباط سستی با هم دارند. گاهی از اصطلاح کاتالوگ هم برای آن استفاده می‌شود. از طرفی، اصطلاح الگوی مرکب (Compound Pattern) را هم داریم به‌عنوان مثال الگوی بروکراسی (Bureaucracy Pattern) از دریک‌ ریله یک الگوی مرکب است. الگوی مرکب شامل ترکیب خلاقانه الگوهای دیگر است. به‌عنوان مثال در مورد الگوی بروکراسی، در داخل خودش از الگوی ترکیب (Composite)، الگوی واسط (Mediator)، الگوی زنجیره مسئولیت‌ها (Chain of Responsibilities) و الگوی ناظر (Observer) برای رسیدن به راه‌حل موردنظرش استفاده کرده است.یعنی تعدادی از الگوهای موجود را برمی‌دارید و آنها را ترکیب کرده و اسم جدیدی به آنها می‌دهید؟نه، به این شکل نیست. این‌طوری، مجوز برگزاری کارگاه را دریافت نمی‌کنید. باید ارزش افزوده ایجاد کنید. باید یک ترکیب جدید و بامعنی از الگوها باشد. مرز ظریفی بین الگوی مرکب قابل پذیرش و غیر قابل پذیرش وجود دارد.بسیار خوب. مورد بعدی از اصطلاحات الگوها، دنباله‌های الگو (Pattern Sequences) است.بله، دنباله‌های الگو موضوعی است که همچنان در حال بالغ شدن است. دنباله الگو اساساً توضیح می‌دهد که چطور سیستم نمو می‌کند. اینکه اولین الگویی که استفاده شده است کدام است؟ الگوی دوم کدام بوده است؟ در واقع، اصلاح کردن و توسعه گام به گام معماری‌تان است. دنباله الگوها، یک روش مفید به منظور اصلاحات گام به گام برای ساختن سیستم با استفاده از الگوها است.بسیار خوب، احتمالاً روشی برای ترکیب کردن الگوها که بیش از همه سازماندهی‌ شده باشد، زبان‌های الگوها است.بله، زبان‌های الگو، چندین دنباله الگو را برای یک حوزه خاص با هم ترکیب می‌کند. به‌عنوان مثال در حوزه‌ای مانند امور راه دور، زبان الگو، متداول‌ترین و کارآمدترین الگوهای حوزه و همین طور مصالحه‌ها (Trade-off) و گزینه‌های جایگزین (Alternative) آنها را مستند می‌کند. هرگاه الگویی را انتخاب کنید بسته به زمینه‌ای که حاصل می‌شود، در نتیجه آن الگوهای دیگر را اختیار می‌کنید و با عبور از خلال زبان الگوها، دنباله‌های الگو توضیح داده می‌شود.شاید خیلی سودمند به نظر نرسد اما اگر برخی کتاب‌هایی که در این زمینه نوشته شده است را ببینید، یک راهنمای عملی در مورد موضوعاتی که بالقوه می‌توانند خیلی پیچیده باشند، ارائه می‌کنند. به‌عنوان مثال در مورد امور راه دور (Remoting)، با چیزهایی از قبیل نماینده (Proxy) و جاآرایی (Marshaling) آغاز می‌کنند و بعد در مورد اینکه چگونه می‌توان چرخه حیات این اشیاء راه دور را مدیریت کرد، صحبت می‌کنند، در مورد ارتباطات ناهمگام (Asynchronous) صحبت می‌کنند و ... . اینکه یک حوزه را عمیق‌تر متوجه شوید خیلی سودمندتر است تا اینکه فقط یک API مثلاً CORBA را یاد بگیرید. فکر می‌کنم این ما را به موضوع بعدی می‌برد و آن مزایای الگوها است. چرا الگوها مهم هستند؟فکر می‌کنم، پیش از هرچیز، الگوها به این خاطر ایده‌ خوبی هستند که اجازه می‌دهند بهتر در مورد نرم‌افزار گفتگو کنیم. روشن است که نرم‌افزار را نمی‌توانید لمس کنید. بدون الگوها، صحبت کردن در مورد ساختارهای داخلی و منطق طراحی‌ نرم‌افزار همواره سخت بوده است. به‌وسیله الگوها ابزار و زبان مشترکی برای صحبت کردن در مورد نرم‌افزار، ساختار آن، طراحی‌ آن و همه چیز حول آن را داریم.مورد دوم، استفاده مجدد (Reuse) است. ما تجربیات و سرمشق‌ها (Best Practice) را به اشتراک می‌گذاریم و تا حدی، حوزه توسعه نرم‌افزار را نمو می‌دهیم. همچنین یک هدف غایی وجود دارد که یک رساله معماری نرم‌افزار (Software Architecture Handbook) تهیه شود. چندین بار در مورد آن تلاش شده است اما هنوز به‌دست نیامده است.مورد اخیرش، رهیافت گردی بوش است (اشاره به سایت handbookofsoftwarearchitecture.com - مترجم). درسته؟بله. اما امیدواریم و سرانجام اجتماع ما در آینده موفق خواهد شد. چنین چیزی واقعاً می‌تواند مفید واقع شود تا توسعه نرم‌افزار به یک حوزه مهندسی بالغ تبدیل شود. تا بیشتر ساختار داشته باشد و به جنبه مهندسی در مهندسی نرم‌افزار دست یابیم.:-) این مهم است؛ ما الان در رادیوی «مهندسیِ» نرم‌افزار هستیم!مورد دیگر این است که واقعاً به من کمک می‌کند که افکارم را سازمان دهم. کمکم می‌کند که روش فکر کردن و روش کار مهندسی نرم‌افزارم را سازمان دهم. تمرکز قوی بر روی ساختار، در خوب نوشتن مشخصه‌های نیازمندی هم کمکم می‌کند زیرا می‌دانم بعداً که بخواهم سیستمم را طراحی کنم، باید بر نیازمندی‌هایم تکیه کنم تا تصمیمات طراحی خوبی بگیرم.اگر شما الگوهای زیادی خوانده باشید و احتمالاً الگوهایی را هم نوشته باشید، کمک‌تان می‌کند که به‌صورت طبیعی با همین قطعه‌های دانش که الگو خوانده می‌شوند، فکر کنید. اگر مجبور باشید که چیزهایی را توضیح دهید و یا چیزی را بنویسید و یا سیستمی را بسازید به‌صورت طبیعی این طور آغاز می‌کنید که به روش الگوها فکر می‌کنید. فکر می‌کنید که مسئله‌ای دارید و فکر می‌کنید که من درباره الگویی شنیده‌ام که این مسأله را به روشی حل می‌کند، کتابی را باز می‌کنید یا اینترنت را می‌گردید تا جزییات آن را بخوانید و واقعاً کمک می‌کند که کار توسعه هرروزه‌‌تان را سازمان دهید. فکر می‌کنم این واقعاً مهم است.چیز دیگری که فکر می‌کنم مهم است این است که نوشتن الگوها نیز کمک می‌کند که چیزها را بهتر فرا بگیرید. خیلی وقت پیش که اولین بار کتاب GOF را خواندم، کمکم کرد که بفهمم، شیءگرایی فراتر از ارث‌بری و محصور کردن (Encapsulation) است. در گام بعدی، ساختن سیستم‌های شیءگرا بر اساس کتاب GOF را فراگرفتم. بعد که نوشتن الگو را آغاز کردم، خودش گام بعدی بود زیرا سبک نگارشم را بهبود داد. اگر امروزه بخواهم مقاله یا هر نوع مستند دیگری را بنویسم که زمان کافی برای درست نوشتنش را داشته باشم، همواره تا حدودی مانند الگو خواهد شد. تلاش می‌‌کنم که اول ‌زمینه کار را توضیح دهم، بعد مسئله‌ای را طرح می‌کنم که سعی دارم با این سیستمی که مستند می‌کنم، حلش کنم. بعد راه حل را می‌آورم و توضیح می‌دهم که پیامدها چه هستند و با یک مثال که فهمش ساده باشد، انگیزه همه آنها را می‌سازم. بنابراین نوشتن الگو تنها برای گرفتن بلیط پرواز به ایلینویز برای کنفرانس نیست بلکه واقعاً کمک‌تان می‌کند که سبک نگارش‌تان را بهبود دهید. و این چیزی است که خیلی از افراد باید انجام دهند.منم gosh!بله! برای اینکه توضیح داده باشم، اصطلاح gosh در دومین کارگاه نویسندگان برای بیان اینکه شما هم دقیقاً همان عقیده را دارید، استفاده می‌شد. در عوض اینکه یک چیز را دوباره و دوباره تکرار کنید این اصطلاح را می‌گفتید تا دقیقاً با چیزی که نفر دیگر گفته بود موافقت کنید.قبل از پایان دادن به مصاحبه و ذکر مراجع اضافی، فکر می‌کنم واقعاً جالب باشد که به حجم نوشته‌هایی اشاره نماییم که توسط انجمن الگوها ایجاد شده است. فکر می‌کنم حدود ۵۰ کتاب باشد.بله، من به تازگی در سایت hillside.net جستجو کردم و بین ۵۰ تا ۷۰ کتاب جدی در مورد الگوها بود. (آمارها مربوط به زمان مصاحبه در سال ۲۰۰۶ است - مترجم)منظورتان از جدی این است که مربوط به کارگاه‌ها بوده است؟بله، مربوط به کارگاه‌ها بوده است و با قواعد انجمن تطابق کامل داشته‌اند، نه اینکه فقط چون اسمش را الگو گذاشته‌اند ادعا کرده باشند راه‌حل‌شان الگو است.بله، خصوصاً در گذشته مشاجره جدی در این زمینه وجود داشت که عنوان الگو را بر روی جلد کتاب‌تان بگذارید. شاید سختگیرانه باشد که بگوییم اگر کسی در کنفرانس‌ها شرکت نکرده است اجازه استفاده از عنوان الگو را ندارد اما امروزه افراد تا حدی انتظار دارند که الگوهایی که در کتاب‌ها می‌آید یا حداقل بخشی از آنها از کارگاه‌های یکی از کنفرانس‌ها آمده باشد. درسته؟بله، بنابراین در انجمن ما، کنفرانس‌های PLoP، تضمین‌کننده کیفیت است.همچنین به غیر از فهرست‌های جامعی که از منابع مختلفی مانند صفحات وب می‌توانید بیابید، فهرست بهترین‌ها نیز وجود دارد. انتشارات Addison-Wesley یک مجموعه با نام PLoPD (مخفف Pattern Languages of Program Design) منتشر کرده است. تا بحال ۴ جلد منتشر شده است البته جلد ۵ باید خیلی وقت پیش چاپ می‌‌شد و انتشارات گفته است که چاپش در مراحل نهایی است. این مجموعه PLoPD، یک مجموعه منتخب حتی بهبودیافته‌تر از الگوهای کنفرانس‌های مختلف است و به نوعی، بهترین‌ها است.نکته دیگری که خوب است اشاره کنم، تقویم الگو (Pattern Almanac) نوشته لیندا رایزینگ است که الگوهای تا سال ۲۰۰۰ را دارد اما هنوز معتبر است و می‌توانید ایندکس آن را استفاده نمایید تا الگوهای مرتبط با مشکلی که با آن مواجه شده‌اید، را بیابید.آیا یک کاتالوگ (کاملِ) الگوها در وب وجود دارد؟ فکر می‌کنم وجود نداشته باشد.خیر، هنوز وجود ندارد. همانند رساله معماری نرم‌افزار، (برای این موضوع هم) خیلی‌ها تلاش کرده‌اند اما هنوز وجود ندارد. من می‌دانم قطعاً برایش برنامه‌ریزی شده است و هرگاه فراهم شود مطمئنم که می‌توانید لینک آن را در hillside.net بیابید.بسیار خوب، فکر می‌کنم بحث ما در مورد الگوها به پایان می‌رسد.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Thu, 24 Mar 2022 12:14:22 +0430</pubDate>
            </item>
                    <item>
                <title>تاریخچه JUnit و آینده تست</title>
                <link>https://virgool.io/se-radio/%D8%AA%D8%A7%D8%B1%DB%8C%D8%AE%DA%86%D9%87-junit-%D9%88-%D8%A2%DB%8C%D9%86%D8%AF%D9%87-%D8%AA%D8%B3%D8%AA-fjnjorc07akj</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۱۶۷ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت با کِنت بِک درباره این چیز کوچکی که خیلی سال پیش ساخته و کار روزانه برنامه‌نویسانِ بسیار بسیار زیادی را تغییر داده صحبت می‌کنیم: تست خودکار واحد (Unit Testing) و JUnit. به شکل مختصر تاریخچه JUnit را مرور می‌کنیم و دراین‌باره صحبت می‌کنیم که چطور آغاز شد و بعد از آن چه رخ داد.  ما درباره توسعه مبتنی بر تست (Test Driven Development) یا به اختصار TDD بحث خواهیم کرد و دراین‌باره صحبت می‌کنیم که چه زمانی باید TDD کرد و چه زمانی نباید کرد و درباره تجربه‌های دنیای وحشی گپ می‌زنیم. این قسمت با برخی دیدگاه‌های شخصی در مورد آینده تست و به شکل عمومی‌تر مهندسی نرم‌افزار پایان می‌یابد.خوش آمدی کِنت!خیلی ممنونم. خوش‌وقتم که اینجا هستم.خیلی خرسندیم که با شما مصاحبه می‌کنیم. لطفاً خود را برای شنوندگان معرفی کنید و کمی در مورد گذشته و پیش‌زمینه خود برایمان بگویید.من یک خوره نسل سومی هستم. پدربزرگم یک خوره رادیو بود. پدرم یک خوره الکترونیک بود که خوره برنامه‌نویسی شد. حالا من پیشه خانوادگی‌مان را در پیش گرفته‌ام. من در محیطی آکنده از تکنولوژی بزرگ شدم. وقتی ۱۲-۱۳ ساله یا شاید ۱۱ ساله بودم، برنامه‌نویسی را آغاز کردم؛ روی ماشین حسابی که پدرم به خانه آورده بود برنامه‌نویسی می‌کردم.نمی‌دانم چه چیزهایی را برجسته کنم که برای شنوندگان جذاب باشد! خیلی کارها کرده‌ام. الگوهای نرم‌افزاری مبحثی بود که در ابتدا بر روی آن کار کردم. [کارهای دیگری هم کرده‌ام مثلاً] متدولوژی Extreme Programming  و توسعه مبتنی بر تست (Test Driven Development)، معماری xUnit که اولین بار برای زبان SmallTalk پیاده‌سازی شد و بعداً به‌وسیله اریک ‌گاما و من به زبان جاوا ترجمه شد. غیر از آن مثلاً بر روی طراحی واکنشی (Responsive Design) هم کار کرده‌ام. به چه چیز دیگری علاقه‌مندید؟!شما کتاب‌های زیادی نوشته‌اید. این خیلی خوب است.بله، فکر می‌کنم تا الان ۸ کتاب نوشته باشم.فکر می‌کنم به مقیاس جامعه ما زیاد باشد.بله، با استاندارد خوره‌ها، زیاد است.فکر می‌کنم در توییتر خواندم که از هواداران قسمت‌های رادیو مهندسی نرم‌افزار هستید. درسته؟بله، من در ۸ هکتار از زمین‌های چمنزار و جنگلی زندگی می‌کنم که در خارج از یک دهکده کوچک قرار دارد که آن هم خارج از یک شهر کمی‌ بزرگتر است؛ در وسط ناکجا آباد! به همین خاطر، تفریحات زیادی دارم. من به پادکست‌های زیادی گوش می‌دهم از جمله فکر می‌کنم به همه قسمت‌های رادیو مهندسی نرم‌افزار گوش داده‌ام. خیلی خوب است که موقعی که در حال بیل زدن، کودپاشی و غذا دادن به حیوانات هستید، به چیزی گوش دهید که غذای ذهنتان باشد.جالب است. خیلی باعث افتخار است که شنونده همه قسمت‌ها بوده‌اید. لطفاً کمی در مورد تاریخچه JUnit برایمان بگویید. کار چطور آغاز شد؟بله، اولین کار تجاری من در زبان SmallTalk بود. SmallTalk یک تاریخچه‌ای از تست داشت اما تست خودکار نبود. تغییرات کمی در برنامه‌تان می‌دادید و مدتی می‌گذشت و تغییرات بیشتری می‌دادید. بنابراین، این چرخه‌های افزایشی (Incremental) شکل گرفته بود اما تست خودکار نبود. من زنجیره‌ای از کارها را تجربه کردم و ۴-۵ تکنیک مختلف برای نوشتن تست‌های خودکار را آزمودم. بعد، یک روز از من خواسته شد که به یک تیم توسعه، مشاوره بدهم.اوایلِ کار مشاوره‌ام بود. من می‌دانستم که می‌خواهم به آنها بگویم که تست خودکار بنویسند اما روشی برایشان نداشتم که چطور این کار را بکنند. در همان حالی که نوعی اضطراب و هراس داشتم گفتم به من اجازه بدهید که از همان ساختاری که برای تست در محیط SmallTalk داریم استفاده کنم. ما متغیرهایی داریم که مقداردهی اولیه می‌شوند و بعد هم عبارات را داریم. گفتم که چطور است که آن‌ها را بی‌هیچ تکلفی، به مدل اشیاء برگردانیم. محیط کاری شما معادل می‌شود با یک کلاس. متغیرهایی که استفاده می‌کنید تبدیل می‌شود به نمونه‌های متغیر (Instance Variable) و تکه کدی که برای تست می‌نویسید، متدهای کلاس می‌شوند. این، نوعی نگاشت بی‌تکلف بود. من گفتم به‌جای اینکه تست را دستی انجام دهیم و ببینیم که چه چیزی در خروجی چاپ می‌شود و آن وقت مطمئن شویم که تست موفق بوده، بگذاریم کامپیوتر این کار را بکند. از همین جا بود که اعلان‌ها (Assertion) آمدند. منشأ معماری از اینجا بود و این مربوط به سال ۱۹۹۲ می‌شود. این اولین فریم‌ورک تست واحد بود که همه این موفقیت‌ها از آنجا ناشی شد.چند سال بعد، وقتی در زوریخ زندگی می‌کردم، با اریک گاما هر ازچند گاهی برنامه‌نویسی می‌کردم. در آن زمان جاوا کاملاً جدید بود. من می‌خواستم آن را یاد بگیرم. یک بار من و اریک با هواپیما داشتیم برای کنفرانس OOPSLA می‌رفتیم. او از من شنیده بود که در مورد این معماری تست صحبت کرده بودم و من هم صحبت‌های او را شنیده بودم که جاوا خیلی جالب است. ما همانجا نشستیم و اولین نسخه JUnit را با روش تست اول، نوشتیم که این خودش یک مسأله جالب خودراه‌اندازی بود! چگونه می‌توان تستی نوشت که یک فریم‌ورک تست را تست کند؟ مشکلات مختلفی خواهد داشت. شما می‌دانید که ما این گونه چالش‌های فکری را دوست داریم.وقتی از هواپیما پیاده می‌شدیم اولین نسخه JUnit را نوشته بودیم. منظورم این است که چیزی که نوشتیم خیلی کوچک بود. JUnit چیز خیلی کوچکی است. آیا با این وجود می‌توانست مفید باشد؟ وقتی رسیدیم آنجا در آتلانتا آن را به مارتین فاولر دادیم. او خیلی سریع امتحانش کرد و گفت چیز خیلی خوبی است. ما آن را به چند نفر دیگر هم دادیم و بازخوردهای واقعاً خوبی گرفتیم. این گونه بود که کار آغاز شد.و واقعاً موفق بوده است. امروزه، JUnit تبدیل به یک استاندارد نوشتن تست خودکار برای جاوا شده است. درست است؟بله.بعد از آن چه شد؟ این مربوط به خیلی وقت پیش می‌شود. بعد از آن، چه بر سر JUnit آمد؟بله، سال ۱۹۹۷ بود که نسخه اول را نوشتیم. یک تغییر بزرگ معماری که بعدها اتفاق افتاد، تغییر از سبک فریم‌ورک که در آن فرزندانی برای کلاس‌های موجود می‌نویسید و برخی متدها را بازنویسی (Override) می‌کنید به سبک DSL بود که در جاوا با حاشیه‌گذاری (Annotation) پیاده‌سازی می‌کنید. من NUnit را در همان اوایل کار -وقتی فقط چند فایل بر روی سیستم جیمز نیوکِرک بود- دیدیم و آنجا حاشیه‌گذاری‌ها (Annotation) را دیدم و همان موقع گفتم این ایده خیلی جالبی است.بعد از آن متوجه روش‌های دیگری شدم مثلاً اینکه متدها مجبور باشند که با عبارت test آغاز شوند که این هم خود نوعی فراداده (Metadata) است زیرا ما آن را تحلیل می‌کنیم. شما می‌دانید که JUnit یک زبان است که نحو خاص خودش را دارد که با نحو زبان جاوا متفاوت است. به‌عنوان مثال ارث‌بری به روش متفاوتی از جاوا، انجام می‌شود. ما این زبان را در جاوا ساخته‌ایم اما واقعاً جاوا نیست و تحلیل می‌شود. اما کامپایلر جاوا می‌تواند در مورد حاشیه‌گذاری‌ها کمک کند. اگر کسی تستش را با عبارت test آغاز کند، این معنی خاصی نمی‌دهد و باعث نمی‌شود که آن تست اجرا شود اما با استفاده از حاشیه‌گذاری‌ها می‌توانید این‌ کار را به‌درستی انجام دهید.ترجمه‌های زیادی از فریم‌ورک JUnit برای زبان‌های دیگر وجود دارد. نظر شما در مورد این جنبش چیست؟در چندین سطح می‌توانم آن را تعبیر کنم. یک سطح این است که یک طراحی خوب بوده است. منظورم این است که یک چیز مرسوم برای تست است. شما می‌خواهید که دسته‌های مجزا داشته باشید، بتوانید آنها را بدون اینکه با هم تداخل کنند، با هم ترکیب کنید و می‌خواهید همه این کارها را در همان زبان کد برنامه انجام دهید. اینکه تست شما در همان زبان کد برنامه نباشد مزایای زیادی دارد اما در همین حال، اینکه مانند JUnit، تست شما در زبان کد برنامه باشد نیز مزایای زیاد خود را داراست.الان چه کسی دارد روی نسخه جاری کار می‌کند؟ شما همچنان کار می‌کنید. درسته؟بله، هر هفته با دیوید سَف که الان در گوگل هست، جمع می‌شویم و چند ساعت روی آن کار می‌کنیم.شما الان، برای نسخه بعدی برنامه‌ریزی کرده‌اید؟بله، داریم روی آن کار می‌کنیم البته ما یک تیم جدید بزرگی نیستیم.نسخه آخر یک ویژگی خیلی جالب ارائه کرد که راه خودش را در بین کاربران پیدا کرد. مزیت اینکه یک پروژه را برای ۱۳ سال اداره کنید این است که ارزش بردباری را درمی‌یابید. اگر یک ویژگی جدید ابداع کنید که فکر می‌کنید خارق‌العاده است، در صورتی که ۵ سال بعد، افراد در حال استفاده از آن باشند، آن وقت می‌توان گفت که بله، واقعاً ویژگی جالبی بوده است. اما اگر ۳ سال گذشته و افراد هنوز از آن استفاده نمی‌کنند، هنوز نمی‌توان فهمید آیا ویژگی جالبی است یا نه.اما ویژگی جالبی که الان بحثش را کردم، چیزی است که ما به آن قاعده (Rule) می‌گوییم. اگر بخواهم ساده توضیحش دهم باید بگویم وقتی تست اجرا می‌شود، زنجیره‌ای از اشیاء ایجاد می‌‌شوند. یک شیء متد Before را اجرا می‌کند، یک شیء دیگر Timeout را Catch می‌کند، شیء دیگری خطا را گزارش می‌کند و ... . حال با استفاده از Rule، شما می‌توانید اشیائی به این زنجیره اضافه کنید. (قاعده‌ها) به نوعی اشیاء فراداده برای تست هستند. این چیز مهمی است. به‌جای اینکه برای اشتراکات تست‌ها از ارث‌بری استفاده کنید، از ترکیب کردن اشیاء (Composition) استفاده می‌کنید. این روش، منعطف‌تر است. افرادی که به‌دنبال یک ویژگی جالب در JUnit هستند، این چیزی است که باید یک نگاهی به آن بکنند.فکر می‌کنید این یک ویژگی کلیدی برای امکان استفاده‌ مجدد (Reuse) در کدهای تست است؟نمی‌دانم که ویژگی کلیدی است یا نه. ما ۱۳ سال بدون آن سپری کرده‌ایم! ولی فکر می‌کنم خیلی مفید است. من کوشیده‌ام تا نوعی عبارات بیانی (Declarative) برای تست داشته باشیم. اینکه تست را بخوانید و برایتان یک داستان بگوید. قاعده‌ها روشی برای آماده کردن صحنه تست است، روشی که واضح باشد و در عین حال کاملاً ساده باشد. مثلاً شما می‌توانید قاعده‌ای داشته باشید که یک پوشه (Folder) موقتی بسازد و همه کارهایی که در هنگام تست با فایل‌‌ها انجام می‌دهید، بعد از آن، به‌طور خودکار پاک شود. بنابراین وقتی دارید تست را می‌خوانید، می‌‌گویید: «ببین، اینجا یک پوشه موقتی ساخته شده است، مطمئنم که قرار است کار با فایل در اینجا انجام شود.» بنابراین قاعده‌‌ها، گرچه در یک زبان دستوری (Imperative) قرار می‌گیرند اما یک حس بیانی (Declarative) ایجاد می‌کنند که فکر می‌کنم برای تست مفید است.بنابراین فقط نوعی ابزار برای استفاده‌ مجدد (Reuse) نیست بلکه برای گویاتر کردن هم هست. درسته؟بله. چون هر تستی باید داستانی برایتان بگوید. باید ابتدا، وسط و انتها داشته باشد. باید نوعی جریان و فراز و نشیب داشته باشد. فراتر ار این‌ها، باید مقصود داشته باشد؛ باید بتوانید از تست مقصودش را بخوانید. قاعده‌‌ها روش دیگری برای مهیا کردن زمینه تست است. چیزی که از همه قبلی‌ها کمی قوی‌تر است.و در کدام نسخه معرفی شد؟ نسخه ۴ ممیز چند؟فکر می‌کنم ۴ ممیز ۸. می‌توانید آن را در GitHub بیابید، جایی که ما الان کدها را نگهداری می‌کنیم البته بعد از مدت طولانی و موفقیت‌آمیزی که در SourceForge نگهداری می‌شد.شما اصطلاح توسعه مبتنی بر تست (Test Driven Development) را ابداع کردید. آیا می‌توانید یک آشنایی مختصر بدهید که توسعه مبتنی بر تست چیست؟بله، این یک ایده مضحک است. همیشه بهترین ایده‌ها، مضحک هستند. یعنی اگر ایده مضحکی داشته باشید که کار کند، حتماً چیز ارزشمندی است. اگر ایده خوبی داشته باشید که کار کند اهمیتی ندارد زیرا حتماً کس دیگری به آن فکر کرده است اما اگر ایده مضحکی داشته باشید که کار کند، می‌توانید به‌وسیله آن برتری یابید. [توسعه مبتنی بر تست،] ایده مضحکی است که می‌گوید وقتی می‌خواهید کد بنویسید، اول تستی بنویسید که رَد می‌شود و فقط وقتی تست قبول می‌شود که کدی که تصورش را کرده‌اید واقعاً موجود باشد. یعنی جریان کار برنامه‌نویسی را برعکس می‌کند.فکر می‌کنید وقتی توسعه مبتنی بر تست می‌کنید، مهمترین جنبه‌اش چیست؟ اینکه چون اول تست‌ها را می‌نویسید ابتدا به طراحی فکر می‌کنید و پیاده‌سازی برآمده از دیدگاه کاربر کلاس است؟ یا چیز دیگری است؟چیزی که بعد از چندین سال توسعه مبتنی بر تست، در ذهن من رخ می‌دهد، این است که ابتدا یک عملکردی را تصور می‌کنم و فکر بعدی من این است که چگونه آن را تست کنم. بعد از اینکه یک عملکردی را تصور می‌کنم، هیچ‌گاه فکر نمی‌کنم که مثلاً باید از فلان کلاس ارث ببرم و آن یکی را استخراج کنم و دیگری را آنجا بگذارم و .... . در مورد این چیزها که همه‌شان مربوط به پیاده‌سازی هستند فکر نمی‌کنم بلکه بعد از تصور یک عملکرد، گام بعدی من این است که به این فکر می‌کنم که چطور می‌خواهم آن را تست کنم.برای من کار بزرگی است که بخواهم در مورد نحوه پیاده‌سازی یک چیزی فکر کنم و در همان حال، در مورد این فکر کنم که -چون ممکن است اشتباه کرده باشم- چطور می‌خواهم از درست بودن آن مطمئن شوم. گاهی برایم خیلی بزرگ است که همه‌اش را در ذهنم بیاورم. اگر بتوانم آن را به دو بخش مجزا کنم و ابتدا این را رسیدگی کنم که چطور می‌خواهم آن را تست کنم، آن وقت یک کار ساده‌تر و کم‌استرس‌تری دارم که تمرکز کردن بر روی آن راحت‌تر است.اگر نمی‌توانید برای چیزی تست بنویسید، در واقع موضوع برنامه‌نویسی ندارید. این برای اغلب برنامه‌ها درست است. البته وقتی موضوع کارم خیلی اکتشافی باشد، در مورد این چیزها فکر نمی‌کنم یعنی اگر بخواهم بفهمم که آیا کلاً می‌توانم برنامه‌ای بنویسم که فلان کار را انجام دهد، آن موقع، کد را می‌نویسم و دستی آن را تست می‌کنم. بعد وقتی فهمیدم بله، ممکن است؛ آنگاه روش را عوض می‌کنم و کمی عقب رفته و در مورد نحوه تستش فکر می‌کنم.خیلی از افرادی که من با آنها صحبت کرده‌ام هنوز هم فکر می‌کنند که تست کردن قبل از نوشتن خود کد، واقعاً کار احمقانه‌ای است. بعضی وقت‌ها از انجام آن می‌ترسند. مشاهدات شما از تطابق افراد با توسعه مبتنی بر تست در عمل چیست؟من کنجکاوم بدانم چه مشکلی پیش می‌آید. مغزتان منفجر نمی‌شود! بگذارید از شما بپرسم آیا توسعه مبتنی بر تست کرده‌اید؟بله.پس خودتان وقتی کسی به شما چنین چیزی بگوید، چه می‌گویید؟من می‌گویم به من کمک می‌کند که در گام‌های کوچک رو به جلو حرکت کنم. گام‌های پایداری برایم فراهم می‌کند. کمکم می‌کند که به این فکر کنم که چه کاری لازم است انجام دهم و چطور باید آن را پیاده‌سازی کنم.بله، این همان حس و تجربه من هم هست. من فکر می‌کنم برخی موانع، اجتماعی هستند. وقتی وارد رشته کامپیوتر می‌شوید می‌بینید دانشجویان با رتبه آ، برنامه‌نویس می‌شوند و دانشجویان با رتبه ب، تست می‌کنند. بخشی از آنچه باید برآن فائق آیم، این نوعِ دید اجتماعی است. اینکه (کسی فکر کند) من برنامه‌نویسم، مجبور نیستم تست بنویسم! که البته درست نیست اما داریم در مورد ذهن بشر صحبت می‌کنیم. البته من در مورد افرادی که شما درموردشان صحبت می‌کنید چیزی نمی‌دانم اما برای من چنین مانعی وجود داشته است.من باید به‌شکل مشخص ۳۰ تا ۴۰ درصد از زمان خود را به نوشتن تست اختصاص دهم اما وقتی تست می‌نویسم فقط خود تست نوشتن نیست؛ در آن زمان من در حال تصمیمات API و تحلیل هم هستم و تست‌ها، روشی است که برای ثبت این تصمیمات به‌کار می‌گیرم و سرانجام تعدادی تست هم خواهم داشت.فکر می‌کنید توانسته‌اید اکثر افرادی که با آنها صحبت کرده‌اید را قانع کنید؟نمی‌دانم. من دیگر تلاش نمی‌کنم که افراد را قانع کنم. فکر می‌کنم واقعاً ۱۰ سال را این‌طور سپری کردم که تلاش می‌کردم افراد را برای TDD و برنامه‌نویسی زوج (Pair Programming) و انواع باید و نبایدها قانع کنم اما دیگر این کار را نمی‌کنم. من همواره کار می‌کنم تا تجربیاتم را بهبود دهم. من مشتاقم آنچه می‌آموزم را به اشتراک بگذارم و همین طور تلاش می‌کنم که به آنچه دیگران در کارهایشان تجربه کرده‌اند گوش دهم و فرا بگیرم. من پیگیر این نیستم که چه تعداد افرادی TDD انجام می‌دهند. فکر می‌کنم اگر روی‌هم‌رفته، روش توسعه نرم‌افزار بهبود یافته باشد، خیلی خوب است و اگر من هم تأثیر کوچکی در آن داشته باشم، آن هم خیلی خوب است.شما سئوالی پرسیدید که میزان انتشار TDD بین افراد چقدر است. من فکر می‌کنم هنوز درصد خیلی کمی از افراد هستند که واقعاً این‌طور کار کنند که هیچ خط کدی ننویسند مگر آنکه قبل از آن یک تست رَد شده برایش نوشته باشند. اما فکر می‌کنم افراد خیلی زیادی هستند که تست و ارزش بالقوه آن برایشان آشکار شده است.اما هنوز پیش می‌آید که به جایی می‌روم و می‌گویند که ما یک مقداری تست کردیم اما کارمان را متوقف می‌کرد و آن را رها کردیم. این برای من خیلی عجیب است. به نظرم ارسطو هم شگفت‌زده می‌شد، منطق این کار جور در نمی‌آید. منطق تست این است که اگر تست کار می‌کند پس برنامه‌ام هم کار می‌کند و اگر تست کار نمی‌کند پس برنامه‌ام هم کار نمی‌کند. اگر وقتی تست کار نمی‌کند، عمل بعدی شما این باشد که تست را پاک می‌کنید و گزارش تست را نادیده می‌گیرید، این به آن معناست که برنامه‌تان کار نمی‌کند. بنابراین نتیجه‌ای که از این بحث می‌توانم داشته باشم این است که به‌غیر از کار کردن برنامه، فشارهای زیاد دیگری هم بر روی افراد هست اما خیلی بد است زیرا فکر می‌کنم یک سود بالقوه‌ای وجود دارد که افراد به‌عنوان برنامه‌نویس در صورتی می‌توانند آن را داشته باشند که به تست کردن اعتماد کنند و بیشتر به آن توجه کنند.در مورد تست، فلسفه‌های دیگری هم وجود دارد مثلاً برخی بجای TDD، توسعه مبتنی بر رفتار (Behavioral Driven Development) را عنوان می‌کنند. نظر شما در این باره چیست؟فکر می‌کنم از جنبه کلی، این خیلی مثبت است که برنامه‌نویسان فعالانه، مسئولیت کیفیت کارشان را می‌پذیرند. این چیز خوبی است و اینکه چه عنوانی به آن می‌دهید، مسئله ثانوی است. یکی از چیزهایی که در همان اولین توضیحاتم در مورد TDD، روی آن بحث می‌کردم اهمیت تست کردن در سطوح مختلف بود. بنابراین این‌طور نیست که TDD، همان فلسفه تست یونیت باشد. من در هر سطحی که به پیشرفت گام بعدی کارم کمک کند تست می‌نویسم. بعضی مواقع ممکن است برخی افراد آنها را تست عملکردی (Functional) بنامند. به‌عنوان مثال، ۴۰٪ از تست‌های JUnit از طریق API عمومی کار می‌کنند و ۶۰٪ از آنها بر روی اشیاء سطح پایین‌تر کار می‌کنند. API عمومی چیز خوبی برای تست کردن است. اینکه شما باید این سهم ۴۰ و ۶۰ را داشته باشید یا سهم ۱۰ و ۹۰ یا اینکه ۹۰ و ۱۰ باشد را من واقعاً نمی‌دانم. فقط می‌خواهم این ایده را مطرح کنم که بخشی از TDD این است که بتوانید بین سطوح مختلف جابجا شوید.مثلاً وقتی مشتری می‌گوید که فلان سناریو باید مقدار ۵ برگرداند، شما یک تست می‌نویسید. همین که چنین سناریویی باید مقدار ۵ برگرداند و وقتی برنامه‌تان را تست می‌کنید و عمیق‌تر می‌شوید می‌بینید که بله، یک شیءای که مقادیر ورودی ۵ و ۷ را می‌گرفته باید ۵ برمی‌گردانده است. این جا موقعیت مناسبی برای نوشتن تست [بعدی] است زیرا این تکه دیگری از داستان است که باید بازگو شود. اما آیا اینکار توسعه مبتنی بر تست‌های پذیرش (Acceptance Test) است؟ یا BDD است؟ فکر می‌کنم اینکه بین سبک‌های مختلف، دیوارهای محکمی بنا کنیم، اشتباه است. من به‌عنوان برنامه‌نویس نیاز دارم که همه این سطوح را بشناسم. تست کمکم می‌کند که آنها را بفهمم و به‌همین دلیل در همه سطوح تست می‌نویسم.این ما را تا حدودی به بحث مقیاس‌های بزرگ می‌کشاند. من پروژه‌هایی را دیده‌ام که هزاران تست واحد (Unit Test) دارند و با این حجم عظیم تست‌های واحد مشکلاتی دارند. نظر شما چیست؟ آیا تست واحد واقعاً مقیاس‌پذیر است؟ شما در سطوح کوچک (و نه در سطح تست‌های پذیرش)، هزاران کلاس دارید و حجم عظیمی از تست‌های واحد وجود خواهد داشت که گاهی ۲-۳ برابر کدهای اصلی می‌شوند. تجربه شما دراین‌باره چیست؟به نظر من اگر ۲-۳ برابر کد، تست وجود دارد کدهای محصول حتماً خیلی پیچیده هستند اما داشتن این مقدار تست کاملاً طبیعی است. یکی از اشخاصی که از تست‌هایی که می‌کرد، بیشترین چیز را یاد گرفتم، یک کامپایلرنویس بود. او برای هر خطی از کد کامپایلر ۵ خط تست نوشته بود. او یکی از موثرترین افرادی است که تا به‌حال دیده‌ام بنابراین این واقعاً برایم الهام‌بخش بود. اما البته داخل کامپایلر به‌شدت پیچیده است بنابراین اینکه نسبت ۱ به ۱ باشد یا ۱ به ۵ باشد، من را نگران نمی‌کند.اما شما همچنان فکر می‌کنید که TDD یا تست خودکار را برای سطوح مختلف داشته باشید. هم تست‌های خیلی کوچک برای واحدهای خیلی کوچک و هم چیزهای بزرگ‌تر و هم چیزهای در سطح تست پذیرش.دیوید سَف که الان در JUnit مشارکت دارد، مدعی است که تست‌ها تمایل دارند که یا به سمت کوچکترین سطح اشیاء مهاجرت کنند و یا به سمت بزرگترین سطح اشیاء. او داشت در مورد تست برای نرم‌افزارهای Eclipse صحبت می‌کرد [که این را مطرح کرد]. من نمی‌توانم این را بپذیرم. من در تجربیاتم متوجه چنین چیزی نشده‌ام. من تست‌هایی در همه سطوح میانی داشته‌ام که از داشتن آنها خوشحال بوده‌ام و هزینه زیادی برایم نداشته است.شما الان گفتید که اگر فقط بخواهید بفهمید که آیا پیاده‌سازی یک چیزی ممکن هست یا خیر، تستی برایش نمی‌نویسید. آیا موارد دیگری هم هست که فکر می‌کنید برای آنها TDD نکنید؟ من یک توییت در توییتر را به‌خاطر می‌آورم که می‌گفت توسعه‌دهندگان خوب می‌دانند که چه موقع تست کنند و چه زمان تست نکنند. آیا ممکن است یک کم در این مورد توضیح دهید.تست هزینه‌ها و منافع خودش را دارد. برخی از منافعش کوتاه‌مدت هستند و برخی بلندمدت هستند. همین‌طور برخی از هزینه‌ها کوتاه مدت و برخی دیگر بلندمدت هستند. و شرایط مختلف، مقاطع کوتاه مدت و بلند مدت متفاوتی دارند. به‌عنوان مثال، یک زمان من یک سایت تمرین پوکر راه‌اندازی کردم. زیرا من داشتم پوکر بازی کردن را یاد می‌گرفتم و در انجام تطبیق الگو (Pattern Matching) مشکلاتی داشتم. مثلاً اینکه اگر ۷ کارت داشته باشیم چطور تشخیص دهم دست من چیست؟ آیا یک زوج دارم یا دو زوج دارم یا ...؟ اول می‌خواستم بدانم اگر نرم‌افزاری برای این کار داشته باشم که قدرت تشخیص‌‌مان را بالا ببرد، چیز جالبی خواهد شد؟ من نسخه اول نرم‌افزار را به زبان SmallTalk نوشتم و بعد آن را به Java Script ترجمه کردم. من تستی نداشتم اما متوجه شدم که بله، چیز جالبی می‌شود. بعد خواستم که آن را به شرایط بیشتری گسترش داده و مدل حوزه‌اش (Domain Model)‌ را غنی‌تر کنم. وقتی این کار را کردم، آن موقع شروع به نوشتن تست کردم. وقتی تست نوشتن را آغاز کردم متوجه شدم که تکه کار خیلی بزرگ است و بخشی را خارج کردم و توانستم تست‌ها را راحت‌تر بنویسم. اما یک بازه انتقال وجود داشت. در ابتدا، نگران این بودم که آیا کار واقعاً مفید خواهد بود یا خیر و البته جواب می‌توانست خیر باشد بنابراین منافع بلندمدت اینکه با دقت برایش تست بنویسم رفته بود. وقتی فهمیدم که چیز خوبی است و من می‌خواهم آن را داشته باشم و برای مدتی از آن نگهداری کنم، در آن زمان منافع بلندمدت مجدداً وارد شده و احتمال بیشتری یافتند طوری که من می‌توانستم آنها را ببینم؛ بنابراین روش را عوض کردم.اما در مجموع آنچه من به آن فکر می‌کنم این است که هزینه‌ها و منافع، در کوتاه‌مدت و در بلند‌مدت چه هستند؟ وقتی JUnitMax که یک پلاگین Eclipse بود را شروع کردم، نوشتن تست برای پلاگین Eclipse سخت نبود -می‌دانید که من با اریک یک کتاب در مورد آن نوشته‌ام- با این وجود برخی مواقع، با بعضی چالش‌های واقعی مواجه می‌شدم زیرا API به شدت قدرتمند و منعطف بود اما آن‌چنان برای تست کردنِ مجزا تنظیم نشده بود. بنابراین وقتی JUnitMax را آغاز کردم، تست خودکار نداشتم. این به آن خاطر نبود که ندانم آیا قرار است برای مدت طولانی این کد را پشتیبانی کنم زیرا من آن موقع می‌دانستم که ایده JUnitMax خیلی خوب است و حتی اگر هیچ کس دیگر آن را نخواهد من برای خودم آن را می‌خواهم و نگهداری‌اش می‌کنم اما دلیل آن این بود که هزینه نوشتن چنان تست‌هایی خیلی زیاد بود خصوصاً در اولین ماهی که JUnitMax را می‌نوشتم. آن موقع تست خودکار نداشتم و دستی تست می‌کردم اما زمانی رسید که پیچیدگی کد به حدی رسید که من نگران این موضوع شدم که اگر بخواهم چیزی را تغییر دهم، ممکن است چیز دیگری را خراب کند. در آن زمان، تست نوشتن را آغاز کردم. هم‌اکنون برای JUnitMax به مقدار کافی تست دارم. در واقع، به‌علت اینکه هزینه‌های کوتاه‌مدت خیلی زیاد بود، با وجود اینکه می‌دانستم منافع بلندمدتی خواهم داشت، برایش تست خودکار ننوشته بودم و در اینجا نیز وقتی متوجه شدم که تعادل میان اینها (هزینه‌ها و منافع)، عوض شده است، روشم را تغییر دادم یعنی گفتم ویژگی قبلی را بدون تست خودکار انجام دادم اما برای این ویژگی می‌خواهم تست خودکار داشته باشم حتی اگر قرار باشد هزینه قابل ملاحظه‌ای برای تستش داشته باشم و با این کار خوشحالم. فکر می‌کنم به این روش فکر می‌کنم.این خیلی جالب است زیرا من افرادی را می‌شناسم که نسبت به تست واحد و TDD خیلی بیشتر تعصب دارند و می‌گویند قبل از پیاده‌سازی هر خط کد از هرچیزی، تست بنویسید زیرا موجب می‌شود در مورد طراحی تکه کدتان فکر کنید و ... . آنها از شما خیلی متعصب‌تر هستند. دیدن این ایده‌های مختلف جالب است.به نظر من می‌ارزد که به تعصب، به‌عنوان یک ابزار یادگیری بنگریم. (تجربه کنم که) اگر بگویم همواره برای همه چیز تست می‌نویسم چه اتفاقی می‌‌افتد؟ و بعد ببینم که چه خوب بوده که این کار را کرده‌ام یا اینکه متأسف شده‌ام که این کار را کرده‌ام. [ببینم] چقدر شده که با خود گفته‌ام ای‌کاش تست واحد نمی‌نوشتم و چقدر از نوشتن تست‌ها خوشحال شده‌ام و از اینها برای پیشرفت کارم بهره ببرم.برخی در وبلاگ‌هایشان می‌نویسند یا می‌گویند که: «آیا امروزه بیش از حد تست نمی‌نویسیم؟» نظر شما چیست؟بگذار این به یک مشکل بزرگ تبدیل شود بعد تلاش کنیم که آن را برطرف کنیم!:-) باشه!منظورم این است که به‌نوعی یکی از خِرس‌های همان داستان سه خِرس است. حتماً «خیلی کم» وجود دارد، شاید «خیلی زیاد» هم وجود داشته باشد و جایی هم در میانه آنها هست که دقیقاً درست است. آیا داستان سه خرس را می‌دانید؟فکر نکنم.یک دختر کوچولو داخل خانه خرس‌ها می‌شود. از غذای پدر خانه می‌خورد که زیادی داغ است، از غذای مادر خانه می‌خورد که زیادی سرد است، در نهایت از غذای بچه خرس می‌خورد که مناسب است. وقتی این داستان را تعریف می‌کنم منظورم این است که بله، می‌توانید خیلی زیاد داشته باشید، می‌توانید خیلی کم داشته باشید و جایی در میانه آن درست است اما من فکر نمی‌کنم افراد واقعاً بدانند «خیلی زیاد» واقعاً چیست. من می‌خواهم چنین چیزی را تجربه کنم که هم تست‌ها و هم فعالیت‌های تیم، آن‌قدر بشود که حس کنم خیلی زیاد است اما با وجود اینکه تلاش کرده‌ام هیچ‌گاه به چنین چیزی نرسیده‌ام!بسیار خوب. چه چیزی باعث می‌شود یک تست یا تست واحد خوب شود و چه چیزی باعث می‌شود بد باشد؟ من مطمئنم که شما تعداد زیادی از هر دو مورد تست‌های خوب و بد را دیده‌اید.من فکر می‌کنم هر تستی باید داستانی را روایت کند که اگر کسی بعداً بیاید و آن را بخواند باید چیزی مهم در مورد برنامه بفهمد. بنابراین اولین صافی من، گویایی آن برای افراد است. اگر بخواهیم به زبان پزشکی بگوییم، تست‌ها باید تشخیص تفاضلی (Differential Diagnosis) داشته باشند. مثلاً وقتی تست خون می‌دهید بر اساس نتیجه آن، می‌توانید برخی چیزها را از تشخیص‌تان خارج سازید و برخی چیزهای دیگر را تأیید کنید. هر تستی باید بتواند برنامه خوب را از بد، مجزا سازد. اگر تستی داشته باشید که پیشرفتی در جهت فهم برنامه خوب از بد ایجاد نکند، احتمالاً تست خوبی نیست. اگر فضای کلیه برنامه‌هایی که تلاش در حل مسأله‌تان دارند را درنظر بگیرید، تعداد خیلی اندکی می‌توانند این کار را بکنند و بقیه نمی‌توانند. یک تست باید بخش بزرگی از آن فضا را هرس کند. هر برنامه‌ای که این تست را ارضاء نکند، قطعاً مسأله اصلی را نمی‌تواند حل کند.مورد دیگر افزونگی‌ها (Redundancy) است. اگر تعدادی تست داشته باشید که دقیقاً چیز یکسانی را بگویند، من می‌گردم که ببینم کدام‌یک از آنها کمترین ارزش افزوده را دارد و آن را پاک می‌کنم البته باید دقیقاً درباره چیزی باشد که قبلاً پوشش داده شده باشد.آیا فکر می‌کنید قواعد طراحی که همه ما در مورد برنامه‌نویسی عادی می‌شناسیم، برای کدهای تست هم معنی می‌دهند؟ مثلاً ارث‌ بردن؟در مورد خاص ارث‌بری، من برای کدهای تست، موافقش نیستم زیرا دوست دارم تست‌هایم مانند یک داستان خوانده شوند. یکی از امکانات JUnit این است که می‌توانید یک کلاس والد راه‌انداز (Setup) داشته باشید که قبل از همه تست‌ها اجرا شود. به این ترتیب می‌توانید کدهای مشترک مربوط به راه‌اندازی تست‌های مختلف در کلاس‌های مختلف را استخراج کنید. اگر این کار (ارث‌بری) را برای ۳ یا ۴ سطح انجام دهید در آن صورت، تست خیلی بی‌شاخ و برگ می‌شود. تست فقط می‌گوید که یک شیء یا پیغام داریم و این مقدار باید برگشت داده شود اما اگر بخواهید بفهمید واقعاً چه اتفاقی دارد می‌افتد و داستان را بفهمید، باید به کلاس و Setup آن و کلاس والد و Setup آن و کلاس والد والد و Setup آن و ... نگاه کنید، این کار زمان می‌برد. این روش مانند این است که یک لطیفه را بدون اینکه مقدماتش را بگوییم، نقل کنیم که مزه‌ای ندارد.آیا قاعده واقعاً عجیب دیگری در مورد تست مشاهده کرده‌اید؟بله، وجود دارد. یکی از آنها که واقعاً عجیب است اما خیلی مفید است و می‌توانم توضیح بدهم این است که تست به‌صورت تصادفی، رد نمی‌شود. اگر یک تست یک بار رد شود، احتمال اینکه همان تست به‌زودی بازهم رد شود، نسبت به جمعیت کلیه تست‌ها، بیشتر است. بیشتر تست‌ها این طورند که وقتی قبول می‌شوند دیگر رد نمی‌شوند. این مبتنی بر مشاهدات صدها میلیون اجرای تست از توسعه ۵۰ توسعه‌دهنده در طول یک سال است. اگر یک تست شروع کند به کار کردن، (به احتمال زیاد)‌ همچنان قبول خواهد شد اما اگر یک تستی رد شود احتمال اینکه در اجرای بعدی هم رد شود خیلی بیشتر است. ما از این موضوع در JUnitMax که یک پلاگین تست برای جاوا در Eclipse بود استفاده کردیم تا تست‌ها را اولویت‌بندی کنیم و تستی که بیشترین احتمال رد شدن را دارد را ابتدا اجرا کنیم. توجه‌ ما براین موضوع بوده که از تستی که اجرا می‌کنید بیشترین بازخورد را بگیرید. زیرا اگر واقعاً بتوانید -و من فرض می‌کنم با استفاده از تحلیل‌های آماری بتوانید- اثبات کنید که اگر تستی آخرین بار قبول شده، این بار هم قبول خواهد شد دیگر نیازی به اجرای آن نخواهید داشت. این قاعده آخرین رد شده‌ها، اکتشافی است که با هزینه خیلی کم می‌توان آن را محاسبه نمود زیرا فقط کافیست مقدار کمی حافظه در مورد رخدادهای گذشته، داشته باشید و با استفاده از آن می‌توانید تست‌ها را اولویت‌بندی کنید؛ تست‌های جدید و تست‌هایی که اخیراً رد شده‌اند ابتدا اجرا می‌شوند.مورد دیگر این است که اگر هر مجموعه تستی را در نظر بگیرید، می‌بینید که اجرای برخی تست‌ها زمان کمتری می‌برد و اجرای برخی دیگر طولانی‌تر است. این زمان‌های اجرا، توزیع توانی (Power Law) دارند. به این ترتیب که تعداد خیلی خیلی زیادی تست دارید که خیلی سریع اجرا می‌شوند و تعداد اندکی تست دارید که خیلی طول می‌کشد تا اجرا شوند. اگر نمودار هیستوگرام آنها را بکشید می‌توانید این آمار مضحک را ببینید. من نمی‌توانم توضیح دهم که چرا این درست است اما این را آن‌قدر در جاهای مختلف دیده‌ام که باور دارم کاملاً عمومی است.در این صورت آیا شما این دو مجموعه را از هم مجزا می‌کنید و مثلاً تست‌های طولانی‌مدت را با نرخ کمتر و یا در بیلدهای شبانه اجرا می‌کنید؟آنچه این توزیع توانی می‌گوید این است که بیشتر تست‌ها می‌توانند در یک زمان کوتاه اجرا شوند بنابراین می‌توانید به این شکل آنها را از هم مجزا کنید. در واقع وقتی JUnitMax را اجرا می‌کنید، تست‌های کوتاه‌مدت‌تر را اول اجرا می‌کند. آنچه من هنوز تایید نکرده‌ام و خیلی دوست دارم داده‌های بیشتری در مورد آن داشته باشیم این است که آیا تست‌های طولانی‌مدت‌تر، احتمال رد شدن بیشتری دارند یا خیر. بدترین نتیجه در صورتی خواهد بود که هرچه تست‌ها زمان بیشتری بگیرند، اطلاعات بیشتری هم تولید کنند اما اگر همبستگی بین آنها وجود نداشته باشد، بهترین حالت است. در آن صورت، با اجرا کردن تست‌های کوتاه‌مدت‌تر، بیشترین اطمینان را از برنامه‌تان حاصل می‌کنید.ممکن است کمی بیشتر در مورد JUnitMax توضیح دهید. شما چند بار به آن اشاره کردید، ممکن است به ما بگویید دقیقاً چه چیزی است؟حتماً. JUnitMax، یک تست‌کننده مستمر برای Eclipse است. [با استفاده از آن،] اگر پروژه‌ای را در Eclipse اجرا کنید می‌بینید که همه تست‌ها به‌صورت خودکار اجرا می‌شوند. دقیقاً مشابه کامپایلر است؛ در Eclipse ابزار مجزایی برای کامپایل ندارید که به‌سراغش بروید و اجرایش کنید بلکه اگر تغییری در کد بدهید، کامپایلر به‌صورت خودکار اجرا می‌شود و بازخورد می‌دهد، با بکارگیری JUnitMax، تست‌ها هم همین‌گونه خواهند شد. یک ابزار تست مجزا نخواهید داشت، یک پنجره مجزایی نخواهید داشت که به‌سراغش بروید بلکه بازخوردها را همان موقع می‌گیرید.هرچه من بیشتر TDD انجام می‌دادم، بیشتر تست‌ها را اجرا می‌کردم. اگر فرض کنیم که اجرای تست‌ها، ۱۰ ثانیه طول بکشد، اگر آنها را در هرساعت، ۲۰ بار اجرا کنید - که احتمالاً یک تخمین محتاطانه است- و هربار که تست‌ها را اجرا می‌کنید منتظر پاسخش بمانید، با این فرض‌ها، می‌توانید محاسبه کنید که چه هزینه‌ای فقط برای انتظار کامل شدن اجرای تست‌ها می‌پردازید. من می‌خواستم این هزینه را از میان ببرم. برای این منظور از حقه اولویت‌بندی تست و یکپارچه کردن اجرای تست با محیط استفاده کردم. رَد شدن تست‌ها درست مانند خطاهای کامپایل، نمایش داده می‌شود. برای دریافت بازخوردها لازم نیست، به جای دیگری بروید. بنابراین فقط لازم خواهد بود چند ثانیه صبر کنید تا با خود بگویید همین‌قدر کافی است و به کد زدن بازمی‌گردم. هر زمان که من خواستم این اعداد را محاسبه کنم، مضحک به نظر آمد بنابراین به‌عهده خوانندگان می‌گذارم که حساب کنند چه مقدار زمان انتظار برای تست‌ها صرف می‌کنند و اگر نتایج تست را در ۱۰٪ آن زمان داشته باشند چه مقدار صرفه‌جویی مالی خواهند داشت.بنابراین بخشی از انگیزه من از آنجا ناشی می‌شد که این برایم ناامیدکننده بود که بخشی از زمانم را در انتظار پاسخ تست‌ها صرف می‌کردم و بخش دیگر انگیزه من از آنجا بود که می‌خواستم زندگی برنامه‌نویسی خودم را داشته باشم. من می‌توانم به اینجا و آنجا مسافرت کنم و سخنرانی کنم و مشاوره بدهم و ... اما این نوعی زندگی خوشگذرانی است. من ترجیح می‌دهم این کار را نکنم. من عاشق برنامه‌نویسی هستم. این راهی بود که می‌توانستم زندگی برنامه‌نویسی خودم را بسازم. بنابراین ترکیبی از این دو انگیزه بود: یکی کمتر منتظر شدن برای تست‌ها و دیگری به‌عنوان روشی برای پرداخت هزینه‌های خودم، خانواده‌ام، شهریه دانشگاه و ... از طریق فعالیتی که هنوز هم واقعاً عاشقش هستم و آن JUnitMax بود.جالب است. آیا لازم است برای آن تست‌های خاصی بنویسیم یا همان تست‌های عادی نوشته شده برای مثلاً نسخه‌ ۲ یا ۳ از JUnit را می‌توان به‌وسیله آن اجرا نمود؟شما می‌توانید این‌طور به آن نگاه کنید که یک جایگزین برای همان اجراکننده تست JUnit است که با Eclipse همراه است.بنابراین لازم نیست هیچ کد خاصی در برنامه‌ام برای آن داشته باشم.نه، به‌هیچ وجه. فقط نتایج تست را با انتظار کمتری برایتان فراهم می‌کند.از کجا می‌توانم آن را بگیرم؟از JUnitMax.comاز com. به نظر می‌رسد که متن‌باز نباشد و باید بابتش پول بدهیم.بله، ۱۰۰ دلار برای هر سال. هرباری که محاسبه کرده‌ام دیده‌ام هر ۲ روز یک‌بار هزینه‌اش را برگردانده است.بسیار خوب. ما خیلی در مورد تاریخچه تست و تست در گذشته صحبت کردیم. بیایید نگاهی به آینده بیاندازیم.فکر می‌کنم JUnitMax نوعی از باورهای من در مورد مسیر آینده است؛ جایی که تست به میزان کامپایلر برای برنامه‌نویسی اهمیت می‌یابد؛ وقتی که تست، هر دقیقه برایتان منفعت می‌آورد پس شما هم سرمایه‌گذاری بیشتری روی تولید آنها می‌کنید. فکر می‌‌کنم گرایش فراوانی در زمینه طراحی برای تست‌پذیری (Design for Testability) شکل خواهد گرفت. مثلاً سیستمی مانند Eclipse طراحی زیبایی دارد اما سخت است که برایش تست‌های موجزی بنویسیم که سریع اجرا شوند. قطعاً راه‌های طراحی دیگری هم وجود دارد که بتوانیم به‌سادگی تست‌هایی بنویسم که به‌سرعت اجرا شوند و از شکست به علت عوامل خارجی در امان باشند.برای اینکه واقعاً چطور این کار را خواهید کرد، فکر می‌کنم خیلی چیزها باید فراگرفته شود. اما وقتی ارزش تست کردن افزایش می‌یابد، همزمان ارزش فراگیری این مهارت‌های طراحی هم افزایش خواهد یافت. در نتیجه، این چرخه شکل خواهد گرفت که «تست بیشتر»، انگیزه‌ای می‌شود که نیاز به «طراحی تست پذیرتر» داشته باشیم که آن نیز خود منجر به این می‌شود که تست کم‌هزینه‌تر و باارزش‌تر شود که آن هم خود دوباره منجر به «تست بیشتر» می‌شود. و اینکه تست‌ها با تکرار بیشتری اجرا خواهند شد؛ بیشتر تست‌ها در اغلب زمان‌ها اجرا می‌شوند. این مرحله بعدی با چیزهایی مانند JUnitMax خواهد بود. اگر بخواهید در هر ثانیه از تجربه برنامه‌نویسی، بازخوردهای بیشتری داشته باشید، باید تست‌ها به‌صورت موازی با کار اجرا شوند.چیزی مانده که بخواهید با شنوندگان ما در میان بگذارید؟ یک توصیه‌ خردمندانه؟توصیه‌ خردمندانه‌ من این است که به توصیه‌های خردمندانه اعتماد نکنید. من به نتیجه‌گیری‌های اخلاقی که افراد در پایان داستان‌هایشان می‌کنند اعتمادی ندارم. من خیلی دوست دارم که به داستان‌هایشان گوش دهم اما وقتی می‌خواهند نتیجه‌گیری کنند که بنابراین شما باید درست مانند من این کارها را بکنید، فکر می‌کنم خیلی از شرایط زمینه‌ای را نادیده می‌گیرند. بنابراین «به داستان‌ها گوش دهید و داستان‌ها را تعریف کنید.» این به نوعی نتیجه‌گیری اخلاقی من است و چون یک داستان‌ نیست می‌توانید نادیده بگیریدش! :-)یک سئوال شاید سخت می‌خواهم بپرسم. فکر می‌کنید مهندسی نرم‌افزار در ۵ سال آینده، به چه شکل خواهد بود؟گرایش زیادی به مستقر کردن (Deployment) بیشتر وجود دارد که همه چیزهای دیگر از آن نشأت می‌گیرند. همه تغییرات اجتماعی، تغییرات فنی، تغییرات در زبان‌ها و رویه‌ها، تغییرات در زیرساخت‌ها و همه تغییراتی که لازم است رخ دهند از اینجا ناشی می‌شوند. اگر قرار باشد هر روزه ۵۰ بار (محصول را) مستقر کنید پایگاه داده و ابزارهای استقرارتان باید تغییر کنند. جداسازی میان واحدهای کاری دیگر و کار توسعه باید از میان برود. بازاریابی، فروش، مدل تجاری و همه چیزهای دیگر وقتی خیلی خیلی زیاد استقرار داشته باشید، تغییر خواهند کرد. این گرایشی است که من توقفی برای آن نمی‌بینم.بسیار خوب. شاید ما باید قسمتی را به صحبت در مورد استقرار مستمر (Continuous Deployment) بپردازیم.من خیلی دوست دارم.خیلی خوب. بسیار ممنونم که به این مصاحبه آمدید.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Tue, 01 Mar 2022 20:19:43 +0330</pubDate>
            </item>
                    <item>
                <title>مستندسازی چابک</title>
                <link>https://virgool.io/se-radio/%D9%85%D8%B3%D8%AA%D9%86%D8%AF%D8%B3%D8%A7%D8%B2%DB%8C-%DA%86%D8%A7%D8%A8%DA%A9-uwfzzfwfe0nb</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۳۱ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت می‌خواهیم در مورد مستندسازی و به‌طور خاص در مورد مستند‌سازی چابک صحبت کنیم. ممکن است فکر کنید که علاقه‌ای به مستندسازی ندارید زیرا خود کد را ترجیح می‌دهید. احتمالاً این یکی از مشکلات اصلی پروژه‌های نرم‌افزاری است زیرا مستندسازی -اگر در نظر گرفته شود- بعد از همه کارهای دیگر است. به‌همین علت مستندات بد هستند و زشت به نظر می‌رسند. افراد نمی‌دانند چه چیزی را، چگونه و چه زمانی مستند کنند. در این قسمت قصد داریم برخی از این موارد را روشن کنیم. برای این منظور اندراس روپینگ مهمان ماست. او نویسنده کتاب مستند‌سازی چابک است که انتشارات Wiley آن را منتشر کرده است.اندراس لطفاً کمی در مورد خودتان و موضوع مستند‌سازی چابک صحبت کنید.سلام ، برای دعوتتان متشکرم. همین طور به شنوندگان سلام می‌کنم. من یک معمار و مهندس نرم‌افزار مستقل در هامبورگ هستم که بر روی پروژه‌های IT مختلفی کار کرده‌ام. خیلی وقت است که در این حوزه مشغولم. امروزه بیشتر تمرکزم بر روی معماری‌های مبتنی بر اینترنت و نرم‌افزارهای مدیریت محتوای تحت‌وب است. موضوع مستندسازی، موضوعی است که چند سالی است بر روی آن کار می‌کنم زیرا در هر پروژه‌ای، مستقل از نوع تکنولوژی‌‌اش، می‌توانیم سرمشق‌هایی (Best Practice) را در ارتباط با مستندسازی مشاهده کنیم که خوب عمل می‌کنند و چیزهایی را هم ببینیم که خوب عمل نمی‌کنند.سرانجام، شروع کردم که این تجربه‌های مربوط به سرمشق‌ها را در قالب تعدادی الگو (Pattern) شکل بدهم و به این ترتیب بود که کتاب مستندسازی چابک نمو یافت. عنوان چابک از این موضوع ناشی می‌شود که خواسته‌ام بر روی چیزهایی که متدهای چابک‌ (Agile Method) در مورد مستندسازی می‌گویند، تأکید کنم. اینکه مستندسازی بیش از حد، بیش از آنکه خوب باشد، زیان‌بار است. و اینکه می‌توانیم از متدهای چابک‌، اطلاعات زیادی در ارتباط با اینکه مستندسازی خوب چیست و چه چیز نیست، بدست بیاوریم. فکر می‌کنم یکی از نکات مهمی که می‌توانیم از متدهای چابک‌ بیاموزیم این است که «مستندسازی» و «فراگیری»، یکسان نیستند. شما می‌توانید خیلی چیزها را مستند کرده باشید اما این به آن معنی نیست که همه چیزهایی که تیم فراگرفته است را مستند کرده‌اید. به همین ترتیب می‌توانید مستندات را بخوانید اما ممکن است همه دانشی که نویسندگان در ابتدای کار، در مستندات قرار داده‌اند را بدست نیاورید.دانش عظیمی در یک پروژه وجود دارد. چطور می‌‌توان این کار (انتقال آن به مستندات) را انجام داد؟ برخی متدهای چابک‌ به این سمت گرایش می‌یابند که «بیایید اصلاً هیچ چیزی را مستند نکنیم» که در واقع درست نیست. اما اغلب متدهای چابک‌، توصیه می‌کنند که مستندسازی خود را محدود به چیزهایی کنید که واقعاً ضرورت دارند و مستند کردن آن‌ها سودمند است. آنچه من انجام دادم این بود که برخی سرمشق‌‌ها و الگوها را جمع‌آوری کردم که در این مورد هستند که چه مستنداتی سودمند هستند. و همچنین اینکه چطور مستنداتی که فکر می‌کنید در پروژه‌تان ضروری است را شکل دهید. بنابراین کتابی که به آن اشاره کردید، در واقع از دو ایده مجزا تشکیل یافته است. یکی اینکه مستنداتتان را به یک اندازه منطقی کاهش دهید و دیگر اینکه مستندسازی‌هایی که تصمیم می‌گیرید ضرورت دارند را به روشی انجام دهید که سودمند، خوانا و قابل درک باشد و به‌طور کلی ارزش مستندسازی و ارزش خواندنش را داشته باشد.احتمالاً می‌توانیم دو روش برای مستندسازی داشته باشیم. یک روش این است که خیلی چیزها را با یک قالب دم‌ دستی مستند کنیم و روش دیگر این است که چیزهای کمتری را مستند کنیم اما اطمینان یابیم که همه چیز واقعاً خیلی خوب و دقیق مستند شده‌اند. آیا ترجیحی در مورد این دو روش وجود دارد؟قطعاً روش دوم [ارجحیت دارد]. شما می‌توانید مستندسازی‌ خیلی زیادی داشته باشید اما خیلی با دقت نباشد. در این صورت آنچه در نهایت به آن می‌رسید فقط مستندات است! تهیه مستندات، مدتی وقت خواهد گرفت (نه خیلی زیاد) اما کسی به هیچ عنوان آنها را نخواهد خواند. بنابراین این کار هیچ فایده‌ای نخواهد داشت. آنچه من توصیه می‌کنم این است که فهرستی از همه‌ انواع مستندات ممکن فراهم کنید، آنگاه تصمیم بگیرید که در ارتباط با پروژه خاص شما، کدامیک از آن‌ها واقعاً ضرورت دارد؟ باید درنظر داشته باشید که مواردی وجود دارند که بهتر است بین اعضای تیم توضیح داده شود و احتمالاً وقتی که فردی آنها را در مستندات بخواند، آنچه در مستندات آمده است، دیگر منسوخ شده است. بنابراین این موارد ارزش مستندسازی را ندارند. اما تنها در صورتی تصمیم بگیرید که چیزی را مستند کنید که واقعاً آن را بخواهید. به این معنی که اگر این کار را نکنید افراد در مراحل بعدی پروژه یا در پروژه‌های آتی، به‌علت نداشتن آن مستندات، واقعاً به دردسر بخورند. اگر تصمیم گرفتید که به علتی به نوع خاصی از مستندات نیاز دارید، آنگاه من توصیه می‌کنم که این کار را خوب انجام دهید.چه چیز‌هایی یک مستند خوب را می‌سازند؟ چه چیزهایی ارزش مستندسازی دارند؟ مثلاً یک چیزی که واضح است، راهنمای کاربری است. اگر لازم باشد که افراد بتوانند بدون اینکه نیاز باشد کنار آنها بنشینیم از سیستم استفاده کنند باید یک چیزهایی را برایشان مستند کنیم. احساس می‌کنم این موضوع بحث نیست زیرا روشن است. اما چطور تشخیص می‌دهید که چه چیزهایی را مستند کنید؟این به پروژه بستگی دارد. نمی‌توان خیلی قطعی پاسخ داد و مورد به مورد، متفاوت است. راهنمای کاربری لازم است زیرا تقریباً در همه موارد، توسعه‌دهندگان و کاربران سیستم، دو گروه مجزا هستند. یک معیار این است که چنانچه اطلاعاتی وجود دارد که می‌خواهید برای افراد خارج از تیم در دسترس باشد، آن‌ها ارزش مستندسازی دارند چرا که دانش تیم لزوماً در دسترس این افراد نیست. به طور کلی‌تر باید بدانید که مخاطبین‌تان کدامند. در مورد راهنمای کاربری، مخاطبین، کاربران هستند. مخاطبین دیگری که می‌توانند مطرح باشند، تیم‌های پروژه‌های دیگر هستند. پروژه‌های مجاوری که کارهای مرتبطی انجام می‌دهند و به نرم‌افزار شما گره خورده‌‌اند. یا ممکن است مخاطبین‌تان، تیم آینده باشد که بر روی نسخه بعدی پروژه‌تان کار می‌کند. همچنین اگر تیم‌هایی دارید که قرار است در مکان‌های مختلفی مستقر شوند، نیاز دارید که مستنداتی توزیع کنید.این مطلب اهمیت دارد که [محتوای مستندات] در بلندمدت، موضوعیت داشته باشد. اکثر اطلاعات، نسبتاً به‌سرعت منقضی می‌شوند اما برخی اطلاعات هستند که محتمل است که در یک بازه معقول زمانی، پایدار باشند. جزییات طراحی اغلب به سرعت تغییر می‌کند. اما اصول طراحی، نمای کلی و منطق طراحی، اطلاعات احتمالاً ارزشمندی هستند. حتی برای یکی دو سال ارزشش را دارند که آنها را نگهداری و مراقبت کنیم و در دسترس همکاران و تیم‌های آینده قرار دهیم.یک چیزی که دوست دارم اضافه کنم این است که به‌‌شکل خاص، اخیراً یک مشتری داشتم که من را استخدام کرد تا راهی بیابم که چگونه معماری‌شان را مستند کنیم. و این سئوال سختی بود زیرا آن‌ها کار را با نوشتن صدها صفحه مستند آغاز کرده بودند که کلی مفاهیم معماری، اینترفیس‌ها، بیان مشخصات و غیره را توضیح می‌داد اما متوجه شدند که هیچ‌کس آن را نمی‌خواند و اساساً بی‌فایده بوده است. روش دیگری در مستندسازی معماری هم هست که لااقل در آن مورد، موفق‌تر بوده است و الان داریم انجام می‌دهیم. به این شکل است که تعدادی درس آموزشی (Tutorial)  و راهنمای گام‌به‌گام (Walkthrough) بنویسیم زیرا مخاطبانی که این مستند، برای آن‌ها نوشته شده است، مدیران فنی سطح بالا نیستند که بخواهید برایشان، تصمیمات معماری‌تان را توجیه کنید. در عوض می‌خواهید برای توسعه‌دهندگان، چگونگی پیاده‌سازی سیستم بر اساس معماری را بیان کنید و این چیزی نیست که با نوعی مستند مرجع بخواهید بیان کنید بلکه به نوشته‌ای نیاز دارید که توسعه‌دهندگان در دست داشته باشند و با آن، بتوانند مسیر یک سناریوی مرسوم برنامه‌شان، را ببینند. این، به همان مطلب مخاطبان هدف بر می‌گردد. باید نه تنها در مورد اینکه چه چیزهایی را می‌نویسید بلکه حتی در مورد روشی که آن را می‌نویسید نیز اطمینان یابید. به مسأله سبک‌های نگارش بر می‌گردد؛ اینکه آیا اول‌شخص، صحبت می‌کنید یا با افعال مجهول صحبت می‌کنید، که در نهایت به این بر می‌گردد که با چه کسی صحبت می‌کنید.بله، موافقم. وقتی می‌گویم باید از مخاطب هدف‌تان مطلع باشید، اولین چیزی که باید از آن اطمینان یابید این است که اصلاً مخاطب هدفی وجود داشته باشد. اینکه مستندی ننویسید که هیچ کس آن را نخواهد خواند. مطلب دومی که شما به آن اشاره کردید این است که باید مستندسازی خود را از لحاظ لغاتی که به‌کار می‌برید، اصطلاحات فنی و ... با مخاطبان‌تان تطبیق دهید. اغلب عاقلانه است که با مثال‌های واقعی بررسی کنید که آیا افرادی که انتظار می‌رود، مستند را بخوانند می‌توانند آن را درک کنند.فکر می‌کنم سئوال مهم دیگری که باید در مورد آن بحث کنیم این است که چه زمان باید مستندسازی کنیم؟ آیا در انتهای پروژه وقتی همه چیز تمام شد؟ آیا همراه با کار، آن را انجام دهیم؟ بعنوان مثال JavaDoc از مثال‌های مرسومی است که همراه کار، آن را انجام می‌دهید و اصلاً جزء تعریف API است. آیا ایده‌ای دارید که چه زمانی موقع مناسب برای نوشتن هرکدام از انواع مستندات است؟واقعاً به نوع مستند بستگی دارد. چیزهایی است که لازم است از پیش مستند شود. یک مطلب مهم در اینجا این است که گاهی شما از خود مستند کردن، چیز یاد می‌گیرید. گاهی واردتر می‌شوید. شما چیزی را به روی کاغذ می‌آورید و متوجه می‌شوید که آن را واقعاً نفهمیده بودید. اغلب درباره بیان مشخصات (Specification)، این‌گونه است. اغلب وقتی لازم دارید همراه با مشتری شفاف‌سازی داشته باشید، این‌گونه است زیرا تلاش می‌کنید آن را بنویسید و آن وقت می‌فهمید که به‌خوبی آن را نفهمیده بودید. بنابراین به عقب برمی‌گردید و شاید از مشتری می‌خواهید که بازبینی کند. آنگاه متوجه سوءتفاهم‌ها می‌شوید. چون این در مقاطع بعدی پروژه به کمک شما می‌آید، مهم است که آن را از پیش انجام دهید. این به آن معنی نیست که باید بیان مشخصات را تا ریزترین جزییات انجام دهید زیرا به این کار نیازی ندارید. خیلی مواقع خوب است که همان قدری مستند کنید که کار بتواند آغاز شود.درباره مستندات طراحی، من فکر می‌کنم که خوب است آن‌ها را زمانی انجام دهیم که طراحی کامل شده است زیرا اگر بخواهید همه تصمیمات طراحی را بلافاصله مستند کنید، دائماً در حال مستند کردن آن‌ها خواهید بود. وقت زیادی خواهد گرفت و سرانجام، افراد خسته می‌شوند و انگیزه‌شان را برای بروزرسانی‌های دائم از دست می‌دهند و مستندات بروز نخواهند شد و شاید نادقیق و اشتباه باشند.بنابراین واقعاً بستگی دارد. اگر چیزی را برای مراحل بعدی پروژه یاد می‌گیرید، باید آن را از پیش انجام دهید اما اگر چیزی را برای مراحل بعدی، مستند می‌کنید، می‌توانید مستندسازی را تا زمانی که طراحی یا معماری کامل شده باشد یا حتی سیستم اجرایی شده باشد، به تعویق بیاندازید.فکر می‌کنید این کار توسعه‌دهنده‌ها است که مستندسازی کنند یا فکر می‌کنید لازم است نویسندگان فنی داشته باشیم که مستندسازی کنند یا لااقل مستندات را بازبینی کنند؟فکر می‌کنم در حالت کلی این توسعه‌دهنده‌ها و طراح‌ها هستند که باید کار خودشان را مستند کنند. خیلی دشوار است که افکار کس دیگری را مستند کنیم یا شاید غیرممکن باشد.از طرفی چنین چیزی لازمه‌اش این است که توسعه‌دهندگان‌ و معماران، واقعاً بتوانند چنین مستنداتی را بنویسند. آنها باید از پسِ این کار برآیند که در نوشته‌هایشان جریان خوب و شاید ظاهر خوب داشته باشند. در ادامه در مورد مطالب مربوط به چینش و ظاهر مستندات صحبت خواهیم کرد اما اینجا می‌خواهم بپرسم چه تعداد از توسعه‌دهندگانی که شما می‌شناسید در نوشتن چنین چیزهایی خوب هستند؟در واقع من فکر می‌کنم تعدادشان از آنچه شما فکر می‌کنید بیشتر است. تقریباً در همه پروژه‌هایی که من انجام داده‌ام، افراد مشتاق به مستندسازی بوده‌اند. البته من پروژه‌هایی را برخورد داشته‌ام که واقعاً هیچ کس نمی‌خواست این کار را انجام دهد اما فکر می‌کنم این شرایط معمولش نیست.در اینجا می‌خواستم قبل از اینکه به برنامه اصلی مصاحبه‌مان بپردازیم نظری بدهم. خیلی وقت پیش وقتی من همچنان در استخدام یک شرکت مشاوره‌ای بودم، تلاش کردم تعدادی راهنما در این مورد بنویسم که چطور همکارانم باید مستندسازی کنند و یک کاری که کردم این بود که از یک نمونه الگو استفاده کردم و گفتم هرگاه خواستید چیزی را مستند کنید همواره با بیان زمینه کار (Context) آغاز کنید. پس از آن مسئله‌ای که می‌خواهید حل کنید را توضیح دهید. بعد، راه حل و تأثیرات آن را بگویید و در نهایت تعدادی مثال‌ بیاورید و احتمالاً برخی مسائل دیگری که تحت تأثیر راه‌حل شما برطرف می‌شود را بگویید. بنابراین، اگر نمی‌دانید برای توضیح دادن چیزی چطور به مستندتان ساختار دهید، شاید بهتر باشد که به سبک ارائه الگو (Pattern) که در مسائل مرسوم و عموماً پیچیده استفاده می‌شوید، نظر داشته باشید و از آن برای ساختاردهی به مستندات خود الهام بگیرید. من از این کار خیلی سود برده‌ام.بله، می‌توانم تصورش کنم. اغلب قالب‌هایی برای مستندات دارید و در این کار می‌توانید فراتر از این بروید که فقط ساختار استاندارد را تعریف کنید. می‌توانید حتی فهرست مطالب استاندارد (Table of Content) را هم فراهم کنید تا به عنوان نوعی راهنما برای توسعه‌دهنده‌ها به خدمت گرفته شود تا متوجه شوند که برخی موارد که باید به آن اشاره می‌کردند را فراموش کرده‌اند. شما فقط کمک‌شان می‌کنید که مستندات ضروری را فراهم کنند.از طرف دیگر همان طور که در اول مصاحبه اشاره کردیم، ضرورتی ندارد که لزوماً به یک سری مستندات حجیم برسیم. در واقع این چیز بدی است. آنچه من توصیه می‌کنم و آنچه متد‌های چابک توصیه می‌کنند این است که مستندات را در حد چیزهایی که واقعاً لازم هستند، کم کنید. فکر می‌کنم برای توسعه‌دهندگان این یک مزیت بزرگ است. آن‌ها علاقه ندارند کار مستندسازی را برای هفته‌ها و هفته‌ها انجام دهند زیرا ضرورتی ندارد و سودی ندارد.نکته مهم این است که ایده‌های اصلی و مهمترین مفاهیم و ایده‌های طراحی را نگهداری کنیم تا بین اعضاء تیم گم نشود که نیازمند مقدار مشخصی مستندسازی است. من به شخصه فردی هستم که می‌خواهم مقدار مشخصی مستندسازی کنم و دوست ندارم منحصراً فقط مستندسازی کنم. حتماً می‌خواهم طراحی کنم، حتماً می‌خواهم مقداری برنامه‌نویسی کنم و با مستندسازی گهگاه هم رابطه خوبی دارم. این تجربه من است و مقالاتی هم وجود دارد که جمع‌بندی‌هایی در این مورد دارند.باید تأیید کنم که من واقعاً دوست دارم چیزی را عالی مستند کنم که خودش عالی باشد. اگر طراحی و معماری عالی باشد، نوشتن مستند عالی برای آن هم گاهی لذت‌بخش است.بیایید کمی در مورد ساختار یک مستند خوب صحبت کنیم. ما به شکل الگو (Pattern Form) اشاره کردیم اما این همه چیز نیست. آیا توصیه‌ای دارید که چگونه مستندات را به‌خوبی ساختار دهیم که برای مخاطبینِ بالقوه خوانایی خوبی داشته باشد؟فکر می‌کنم تکنیک‌های ساده‌ای وجود دارد که می‌تواند خیلی کمک‌تان کند. تکنیک‌های ساده و آسانی که زمان زیادی از شما نمی‌گیرد. یکی اینکه هر مستند باید با یک راهنما برای خوانندگان همراه باشد. ما به افراد کمک می‌کنیم که بفهمند کدام مستندات را باید مطالعه کنند، چه چیزهایی را خوب است که بدانند و چه چیزهایی کاملاً نامربوط هستند.دیگر اینکه می‌توانید از تگ‌های ساخت‌یافته استفاده کنید. این می‌تواند خیلی مشابه با شکل الگو باشد اما می‌تواند هر نوع تگ‌های ساخت‌یافته‌ای و هر نوع اطلاعات تکرارشونده و سیستماتیک دیگر هم باشد. به‌عنوان مثال می‌توانید از جداول استفاده کنید. خیلی از افراد جامعه IT، تمایل دارند که به چیزها به شکل دسته‌ها و گروه‌ها نگاه کنند. بنابراین جداولی از ستون‌ها و سطرها برای جامعه IT، امری طبیعی هستند و چیزها را به شکل خیلی واضحی نمایش می‌دهند و خیلی آسان تولید می‌شوند. البته نمودارها هم می‌توانند خیلی مفید باشند. اِشکال‌ آنها این است که تولیدشان پرهزینه است. از طرف دیگر، می‌دانیم یک تصویر، گاهی [عملکردش] بیش از ۱۰۰۰ کلمه است. [تهیه تصاویر] در مورد طراحی و معماری، مقداری زمان می‌برد اما به کیفیت مستند می‌افزاید. اگر واقعاً می‌خواهید که ایده‌های طراحی و نمای کلی (Big Picture) یک معماری را برسانید، فکر می‌کنم می‌ارزد که نمودارهای واقعاً سودمند را مستند کنید.فکر می‌کنم باید اشاره شود که نمودارها هیچ‌گاه به تنهایی جواب نمی‌دهند. وقتی ما کتاب الگوهای راه‌دور (Remoting Patterns) را نوشتیم، در آنجا طبعاً معماری زیرساخت‌های راه دور را توضیح دادیم. در آنجا، همواره در انتهای هر فصلی مجموعه‌ای از نمودار‌های توالی (Sequence Diagram) داشتیم که نشان می‌داد چطور مؤلفه‌های مختلفی که توضیح ‌داده‌ شده‌اند به هم دیگر می‌پیوندند و با هم تعامل می‌کنند. اما بازخوردی که از همه کسانی که کار را بازبینی کرده بودند، داشتیم این بود که: «نمودارهای توالی خوب هستند، اما لطفاً با متن ساده توضیح دهید که آنها شامل چه چیزی هستند.» آن‌وقت من با خودم فکر می‌کردم: «عجب! یعنی شما نمی‌توانید نمودارهای توالی را بخوانید؟» اما نکته‌ای که من فهمیدم این بود که اغلب وقتی شما به یک نمودار نگاه می‌کنید در آن خیره می‌شوید و خیره می‌شوید و خیره می‌شوید تا اینکه یک چیزی را ببینید. اما به راهنمایی نیاز دارید تا شما را از میان نمودار عبور دهد و نقاط کانونی را نشان‌تان دهد و کمک‌تان کند که به کجا نگاه کنید و تمرکزتان را به چه جایی ببرید. بنابراین نمودارها به‌عنوان اطلاعات اضافی خوب هستند اما فکر می‌کنم نباید به‌عنوان منبع انحصاری اطلاعات استفاده شوند. بدترین شکلش این است که اگر مستندات شما در قالب یک مدل Rose بزرگ است، صرفاً بگویید: «فایل Rose را با نرم‌افزارش باز کرده و در آن بگردید.» من فکر نمی‌کنم این کار معمولاً مناسب باشد.بله، من کاملاً موافقم. نمودارها کمک می‌کنند اما جایگزین متن نیستند. شما قطعاً می‌توانید نمودار توالی را بخوانید اما سئوال این است که چرا نمودار توالی به این شکلی که هست آمده است؟ من پیش از این گفتم که طراحیِ بامنطق داشته باشید و بگویید که چرا به این طراحی رسیدید؟ گزینه‌های دیگر طراحی چه بودند؟ چرا گزینه‌های دیگر را انتخاب نکردید؟ احتمالاً این اطلاعات طی چند سال آینده وقتی نسخه‌های بعدی سیستم در راه هستند، خیلی مفید خواهند بود. این اطلاعاتی مفیدی هستند که از نمودارها حاصل نمی‌شوند. باید این چیزها را توضیح دهید و زبان، برای بیان این چیزها از نمودار تنها، خیلی قدرتمندتر است.یک نظر دیگر در مورد آن -هرچند شاید نباید این‌قدر در مورد این موضوع صحبت کنیم- این است که اگر بخواهید یک سیستم یا معماری را به‌صورت سیستماتیک توضیح دهید، خیلی مهم است که شما به‌عنوان نویسنده بر روی تعداد محدودی از اصطلاحات و لغات توافق کنید. باید اطمینان یابید که از یک زبان سازگار استفاده می‌کنید و احتمالاً استفاده از یک واژه‌نامه (Glossary) می‌تواند به این منظور کمک کند. بنابراین در ابتدا، تعدادی اصطلاح را تعریف کنید. فرضاً اگر بخواهم شما را به مبحث برنامه‌نویسی به روش برآمده از مدل (Model Driven Development)، ارجاع دهم در حالت منتهایش، یک متامدل می‌کشید. به هرحال فکر می‌کنم حفظ سازگاری در اصطلاحاتی که استفاده می‌کنید و در روشی که برای بیان مطالب دارید، خیلی مهم است زیرا در غیر این صورت، تنها خواننده را گیج خواهید کرد.اجازه دهید به برنامه مصاحبه‌مان برگردم. مطلبی هست که دوست دارم در مورد آن دقیق‌تر شویم: مستنداتی هستند که آنها را در قطار یا اتاق می‌خوانید و در مقابل مستنداتی هستند که در جستجو استفاده می‌شوند. مثلاً JavaDoc از اینگونه مستندات است. مواردی که تا کنون توضیح دادید در مورد کدام‌یک از این دو می‌توانند به‌کار روند؟ آیا از لحاظ اهمیت تفاوت دارند؟ آیا یکی از دیگری مهم‌تر است؟ ایده‌ای در این مورد دارید؟فکر می‌کنم اساساً دو روش مختلف برای دسترسی به منابع نوشتاری وجود دارد. یک روش، خواندن آن است و دیگری گشتن (Browse) آن است. این‌ها دو روش کاملاً متفاوت هستند. خواندن کاری است که در مورد چیزهایی پرینت‌شده بر روی کاغذ انجام می‌دهید و گشتن کاری است که وقتی انجام می‌دهید که به‌دنبال اطلاعاتی می‌گردید و ارزیابی می‌کنید که آیا این اطلاعات همین حالا بر روی اینترنت یا ویکی یا ... موجود هستند یا خیر.اگر یک مفهوم طراحی یا توصیفی از معماری که به بلوغ رسیده باشد را در اختیار داشته باشید، در آن صورت این‌ها واجد شرایط مستندسازی می‌شوند؛ مستنداتی که قابل خواندن باشند. اکثر افراد دوست دارند که آن را مطالعه کنند و جلو و عقب بروند و از آن یادداشت‌نویسی کنند. شاید بخواهند آن را به خانه ببرند. بنابراین باید این مستندات در قالبی که برای پرینت مناسب باشد، فراهم باشد که در اغلب موارد، صفحات HTML این‌گونه نیست.از طرف دیگر، چیزهایی از قبیل بیان مشخصات API، مثال‌های مرسوم از چیزهایی هستند که باید در دسترس باشند. به‌عنوان مثال، در هنگام برنامه‌نویسی وقتی چیزهایی را از مشخصات جستجو می‌کنید، از JavaDoc استفاده می‌کنید. در این حالت، چیزهایی را جستجو می‌کنید و باید به آسانی در دسترس باشند. البته که همپوشانی‌هایی (Overlap) بین آنها (این دو نوع مستندات) هست. شکی نیست که برخی مستندات هم باید برای پرینت کردن و هم به‌صورت برخط فراهم باشد. این چیزی است که نمی‌توانید از آن بپرهیزید و باید فکری به حالش بکنید.این ما را به بحث تکنولوژی و تکنیک‌ها رهنمون می‌کند. آیا باید مستنداتم را در Word بنویسم یا از ابزارهای تولیدکننده مستندات و نمودارها از قبیل Rose و ... استفاده کنم؟ می‌دانم که این موضوع پیچیده‌ای است اما آیا در این مورد سرمشق‌هایی (Best Practice) هست که بخواهید توصیه کنید؟فکر می‌کنم چیزی که شما می‌دانید این است که می‌توانید نماها (View) را بسازید اما نمی‌توانید محتوا را [به‌شکل خودکار] بسازید. در خیلی مواردی که می‌خواهید مستندی روی یک مدیا بسازید که آن را پرینت کنید، باید آن را بنویسید و نمی‌توانید آن را به‌صورت خودکار بسازید. اما آنچه می‌توانید تلاش کنید که به‌طور خودکار بسازید، مربوط به همپوشانی‌ها است. مثلاً اگر می‌خواهید یک مستند به‌صورت HTML و هم در وب در دسترس باشد، در آن صورت این گزینه وجود دارد که یک نمای آن، احتمالاً نمای وب آن را به‌صورت خودکار بسازید. یکی از مثال‌های برجسته تولید خودکار مستندات، JavaDoc است. همه می‌دانند و همانطور که می‌بینید خیلی سودمند است که مستقیماً از کد و [مستندات] کنار کد به مستندات و بیان مشخصات API برسیم. بنابراین می‌توانید از تکنیک‌هایی استفاده کنید که از یک اطلاعات واحد، نماهای مختلفی تولید کنید اما به‌صورت عمومی تولید خودکار مستندات، محدودیت دارد.مطلب بعدی که می‌خواهم در مورد آن صحبت کنیم، نحوه چینش و ویژگی‌های بصری یک مستند خوب است. برای اینکه کمی به تاریخچه‌اش بپردازیم، اولین موردی که من به شخصه در مورد مستندسازی دیدم که شما هم در آن کار می‌کردید، در واقع یک زبان الگو (Pattern Language) بود که در این مورد صحبت می‌کرد که چطور یک مستند را خوب قالب‌بندی کنیم. ما مقاله شما که به کنفرانس اروپا و دیگر کنفرانس‌ها فرستادید، را به همراه تعدادی مثال در توضیحات این مصاحبه قرار خواهیم داد و من واقعاً این منابع را دوست دارم. فکر می‌کنم -البته این اعتقاد و ادعای من است- که اگر چیزها به خوبی قالب‌بندی شده باشند خواندن آن‌ها برای افراد ساده‌تر می‌شود. من واقعاً از این‌گونه مستنداتی که فاصله خط‌ها از اندازه فونت کوچک‌تر است یا خط‌های خیلی طولانی دارند یا ... نفرت دارم. من فکر می‌کنم باید کمی در مورد سرمشق‌های مربوط به نحوه قالب‌بندی خوب مستندات عمیق‌ شویم.بله، در واقع این چیزی نیست که به‌طور خاص مربوط به متدهای چابک باشد. این‌ها مشخصات یک مستندسازی خوب در همه جا است. برخی قواعد عمومی و چینشی در مورد تایپوگرافی وجود دارد. در واقع تایپوگرافی خود یک هنر است و چیزهای زیادی هست که می‌توانید انجام دهید اما در عین حال برخی قواعد ساده وجود دارد که به‌سادگی می‌تواند رعایت شود تا مستندتان خیلی بهتر به نظر برسد و خیلی خواناتر شود.یک قاعده این است که نباید از فونت‌های مختلف استفاده کنیم. گاهی مواقع در یک مستند، ۴، ۵ یا ۶ نوع فونت استفاده می‌شود. این خواندنش را خیلی سخت می‌کند. خوب است که از فونت نوع Serif به عنوان فونت اصلی (نه لزوماً برای تیترها) استفاده کنید (به فونت‌هایی که لبه‌های زبانه‌دار دارند، فونت‌های Serif گفته می‌شود - مترجم). زیرا این نوع فونت خوانایی بیشتری دارد و شواهدی هم برای آن هست؛ هم‌اکنون ما بیش از ۵۰ سال تجربه داریم که چه نوع تایپوگرافی، به خوانندگان کمک می‌کند تا بهتر بخوانند. یک مثال افراطی این است که فقط از حروف بزرگ استفاده کنیم. برخی افراد این کار را می‌کنند تا بخش‌هایی از متن که خیلی مهم انگاشته می‌شوند را مشخص کنند. اما اگر در تمام متن آن را استفاده کنید، متن کاملاً ناخوانا می‌شود و خواندن متن تا ۲۰٪ الی ۳۰٪ بیشتر طول خواهد کشید و نتیجه‌اش این می‌شود که اصلاً آن را نمی‌خوانند.موارد دیگری هم هست. مثلاً اینکه متن خیلی زیادی را در یک صفحه قرار ندهید و یک حاشیه‌ منطقی را خالی بگذارید. برخی قواعد ساده وجود دارد که من آن را به شکل الگو درآورده‌ام و آن را در کتابم آورده‌ام. این‌ها لزوماً مربوط به چابک بودن نیستند و ویژگی‌های عمومی مستندسازی خوب هستند. اما به‌نظر می‌رسد افراد از آن خوششان آمده است و وقتی من سمینارهای مستندسازی داشته‌ام، یک مطلب جالب این بود که اغلب برای افراد جذاب بود. در ضمن، این‌ها خیلی ارزان به‌دست می‌آیند. همانطور که قبلاً اشاره کردم، معمولاً شما در سازمان‌تان یکسری قالب (Template) برای مستندات دارید و همه، خودشان، قالب‌های مستندسازی را ابداع نمی‌کنند. کاری که باید بکنید این است که قالبی را طراحی کنید که مهمترین قواعد تایپوگرافی در آن رعایت شده باشد. این کار منفعت زیادی دارد و به‌سادگی قابل انجام است.دو قاعده دیگر از مواردی که در الگوهای شما آمده است، طول خطوط و فاصله خطوط است. من این دو را مهم‌ترین موارد یافتم و فکر کردم باید به آن اشاره کنم.اگر خطی داشته باشید که خیلی کوتاه باشد، ممکن است مناسب باشد و این همان چیزی است که در روزنامه‌ها داریم اما در این‌ صورت مجبور می‌شوید بیشتر از خطی به خط دیگر بروید. باید یک اندازه منطقی برای طول خط در کاغذهای مربوط به محیط‌های عادی داشته باشید. یعنی چیزهایی که در خانه بر روی میز خوانده می‌شوند. اگر طول خط‌ها خیلی زیاد باشد، ناخوانا می‌شود زیرا افراد خطوط را قاطی می‌کنند. این‌ها چیزهایی است که ناآگاهانه اتفاق می‌افتد و می‌توانید تأثیرات آن را اندازه بگیرید. قاعده کلی این است که در حدود دو سری الفبای کوچک در یک خط جا شود. همین طور، در مورد فاصله خطوط، هم قاعده کلی این است که فاصله خطوط ۱.۲ برابر اندازه فونت باشد یعنی اگر اندازه فونت شما ۱۰ پیکسلی است نیاز به ۱۲ پیکسل برای هر خط دارید. این همان چیزی است که اغلب ویرایشگرها به درستی انجام می‌دهند اما ارزش دارد که آن را چک کنید.همان‌ طور که گفتم این چیزهایی که در موردش صحبت کردیم، ویژگی‌های بصری مستند هستند. در صفحه‌ توضیحات این مصاحبه، تعدادی نمونه قرار می‌دهیم و شاید تعدادی مقاله‌های اصلی که الگوها در آن آمده است را هم قرار دهیم.شما چگونه مستندات را ارزیابی کیفی می‌کنید؟ در حالت ایده‌آل شاید بخواهید برای مستندات تست واحد (Unit Test) بنویسید اما کار به این سادگی نیست. شاید راه حلش بازبینی و یا خواندن و تصحیح آن‌ها (Proofreading) باشد. چگونه می‌توان آن را در عمل اجرا کرد؟همان طور که کدها نیاز به تست دارند، مستندات نیز نیاز به بازبینی دارند. روشن است که بازبینی از تکنیک‌های سودمند است اما نباید آن را خیلی زیاد انجام دهید. نیازی نیست که همه مستندات را بازبینی کنید یا بدهید کسی آنها را بازبینی کند. اما برخی مواقع هست که بازبینی ضروری می‌شود خصوصاً وقتی که قرار است مستنداتی به مشتریان تحویل شود. فکر می‌کنم قبل از اینکه مستندات به مشتری تحویل شود مهم است که کسی آن را بازبینی کند. گاهی مواقع بازبینی می‌تواند توسط خود مشتری انجام شود. شما می‌توانید مشتری را هم شریک کنید تا آنها این حس را داشته باشند که جدی گرفته شده‌اند. در این حالت، احتمالاً چیزهای زیادی فرامی‌گیرید زیرا تجربه نشان می‌دهد، تیم توسعه و مشتریان اغلب از زبان یکسانی استفاده نمی‌کنند و به‌سادگی ممکن است درک نادرستی حاصل شود.روشن است که شما جلساتی با مشتری دارید. این همان چیزی است که یک متد چابک می‌گوید. مشتری به سایت شما می‌آید یا شما به سایت مشتری می‌روید. این به آن خاطر است که تعاملات‌تان شکل بگیرید و از درک نادرست، جلوگیری شود. این مطلب در مورد مستندات نیز صادق است. بنابراین بدهید آن‌ها را بازبینی کنند. بازبینی کردن توسط مشتریان تکنیک خیلی مفیدی است.از طرفی، واضح است که می‌توانید از افراد تیم بخواهید که طراحی‌هایی که مستند کرده‌اید را بازبینی کنند زیرا به شما اجازه می‌دهد که بازخوردهای سهل و سریع‌تری داشته باشید. معمولاً مستند طراحی‌ها، بحث‌های مطرح‌شده در جلسات طراحی را در برمی‌گیرد و علی‌القاعده، جمع‌بندی بحث‌هایی است که چندین نفر در آن شرکت داشته‌اند.در مورد همه‌ مستندات، مهم است که به یک مرحله نهایی برسند که بتوانید آن را در معرض تعداد زیادی از کسانی که به آن نیاز دارند قرار دهید. باید اطمینان یابید که به‌علت وجود اطلاعات نادقیق در مستندات، در عوض کمک کردن، باعث گیج شدن افراد نشوند.الان که در مورد مستندات نوشتاری صحبت کردیم و همه این قسمت به این موضوع اختصاص داشت، آیا فکر نمی‌کنید که ارزشش را دارد که دیگر قالب‌های مستندات را نیز بررسی کنیم؟ به‌عنوان مثال در عوض داشتن یک مستند طراحی می‌توانیم یک ویدئو از دو نفر از اعضای تیم داشته باشیم که در مقابل یک تخته ایستاده‌اند و طراحی را برای یکدیگر توضیح می‌دهند. به این ترتیب افراد جدید تیم به جای خواندن می‌توانند این ویدئو‌ها را مشاهده کنند. آیا در مورد مناسب بودن این روش‌ها، عقیده یا تجربه خاصی دارید؟فکر می‌کنم ارزش امتحان کردنش را دارد. فکر می‌کنم خیلی به خود پروژه و شرایط آن، بستگی دارد. کارهای زیادی می‌توانید بکنید. ضبط ویدئو یک کار است. یک روش خیلی ساده دیگر این است که در انتهای جلسه طراحی، با یک دوربین تصویربرداری، یک عکس از تخته وایت‌برد بگیریم. اعتقاد دارم این‌ها، تا حدی مفید است. دوربین تصویربرداری، احتمالاً تنها نتیجه طراحی را تصویر می‌گیرد. اگر خوانا باشد و کیفیت تصویر خوب باشد، می‌توانید از آن در مستند طراحی، بهره ببرید.در مورد فیلم‌برداری ویدئویی، به نظر من ایده جالبی است و آن را دوست دارم. اما گمان می‌کنم در خیلی موارد، خیلی راحت در دسترس نیست و افراد نمی‌توانند مانند مستندات نوشتاری، به راحتی صفحات را عقب و جلو کنند. اما اگر بتوانید یک بحث واقعاً جالب را به‌سادگی ضبط کنید، من تشویق می‌کنم که امتحانش کنید.فکر می‌کنم ایده خوبی باشد و شاید در پروژه بعدی انجامش دهم. واقعاً در خیلی از پروژه‌ها، برای اینکه افراد به یک نقطه مشترک برسند باید با همدیگر تعامل داشته باشند. چرا هرچند روز یک‌بار بحث‌های مابین معمار، مدیر، توسعه‌دهنده و ... را ضبط نکنیم؟ چرا به‌دنبال اطلاعاتی نباشیم که نیاز است افراد بدانند؟ضبط کردن، به نظر ایده خوبی می‌آید. ضبط ویدئویی یا mp3 به نظر سودمندتر از یک تصویر ساده می‌آید.بله، این چیزی است که در پروژه بعدی‌ام امتحانش‌ خواهم کرد. برای اینکه بحث را ببندیم، بیایید به بحث چابک بودن برگردیم. احتمالاً اکثر شنوندگان، در پروژه‌هایی شرکت دارند که کم‌وبیش خود را چابک می‌خوانند. سئوال این است که چطور فعالیت مستندسازی یا بازبینی را در یک پروژه چابک قرار می‌دهید؟ فکر می‌کنم باید کمی در این مورد صحبت کنیم.آنچه در ابتدای بحث گفتم این بود که مهم است که مستندسازی را محدود به مواردی کنیم که ضروری هستند. چنین قاعده‌ای وجود ندارد که هر چه بیشتر مستند کنید بیشتر سود می‌برید. این یک رابطه خطی نیست. واقعاً ‌باید دقت کنید که بیش از حد مستند نکنید بلکه در مورد سودمندی مستندات، خیلی مشکوک باشید. به‌غیر از اینکه آگاه باشید که چه مقدار مستندسازی ضروری است، باید آن را در برنامه پروژه هم قرار دهید و در نهایت به آن بودجه اختصاص دهید. باید بسته کارها را تعریف و مشخص کنید و مسئولیت‌ها را مشخص کنید. باید یک فرد مسئول باشد؛ نه همه کس و نه هیچ کس. باید به‌عنوان بخشی از برنامه‌ریزی، مهلت تحویل مشخص باشد.به‌عنوان جمع‌بندی، فکر می‌کنم مهم است که بدانیم مستندسازی و تعامل کلامی، در تقابل با یکدیگر نیستند و متدهای چابک، بر روی اهمیت تعاملات کلامی تأکید دارند و توصیه می‌کنند که خوب است مقدار کمی مستندات نوشتاری داشته باشیم که من نیز تأیید می‌کنم و با آن موافقم. من فکر می‌کنم که مستندات نوشتاری و تعاملات کلامی یکدیگر را تکمیل می‌کنند. آنها دو گزینه مجزا نیستند بلکه همدیگر را تکمیل می‌کنند.چابک بودن یک گرایش و چیزی بیش از تعدادی تکنیک است. چابک بودن، گرایشی است که بهترین نفع توضیحش این است که: «کار درست را انجام دهید. فقط کارهایی را انجام دهید که واقعاً مهم هستند. به این فکر کنید که چه چیز واقعاً اهمیت دارد و آن را انجام دهید.» اگر این گرایش را به‌کار گیرید، احتمالاً مستندسازی‌های زیادی نخواهید داشت بلکه فقط مجموعه‌ای از مستندات را خواهید داشت که مفیدند و در کارتان و مراحل بعدی پروژه‌تان، کمک می‌کنند.اگر بگویم حتی می‌توانید رویه‌های (Practice) چابک بیشتری را استفاده کنید بیراه گفته‌‌ام؟ مثلاً [اگر این رویه را دارید] که مشتری را در سایت خود دارید، [در مستندسازی] این معنی را می‌دهد که می‌توانید مشتری را برای نوشتن مستندات استفاده کنید یا می‌توانید در نوشتن مستندات جفت شوید. یا اگر توسعه برآمده از تست (Test Driven Development) دارید، [در مستندات] هم معنی می‌دهد که ابتدا تعریف کنید که اهداف‌ مستندسازی چیست و تعریف ‌کنید که مخاطبان مستند، چه کسانی هستند؛ اینکه اول تعریف کنید می‌خواهید به چه چیزی برسید و بعد، شروع به مستندسازی کنید. در واقع، تکنیک‌‌های موجود در متدهای چابک بیشتری وجود دارد که می‌تواند به طریقه دیگری برای مستند‌سازی هم بیان شود.بله، فکر می‌کنم می‌توانید. چابک بودن مجموعه‌ای از تکنیک‌ها است اما بیش از آن، یک گرایش است. این تکنیک‌ها فقط مربوط به توسعه نرم‌افزار نیستند بلکه در این موردند که چطور در یک پروژه با هم رفتار کنیم، چطور حجم کارهای‌مان را مدیریت کنیم، اینکه چطور در یک تیم تعامل داشته باشیم. و بله، درست است؛ این تکنیک‌ها می‌توانند برای مستندسازی هم به‌کار روند.فکر می‌کنم بحث‌مان به پایان می‌رسد. از شرکت در مصاحبه ممنونم.از اینکه من را دعوت کردید، ممنونم.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Sun, 20 Feb 2022 19:27:12 +0330</pubDate>
            </item>
                    <item>
                <title>نگاشت‌گر‌های شیء به رابطه (ORM)</title>
                <link>https://virgool.io/se-radio/%D9%86%DA%AF%D8%A7%D8%B4%D8%AA-%DA%AF%D8%B1-%D9%87%D8%A7%DB%8C-%D8%B4%DB%8C%D8%A1-%D8%A8%D9%87-%D8%B1%D8%A7%D8%A8%D8%B7%D9%87-orm-m6vqhhqddg5c</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۱۲۱ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت با مایکل پلاد درباره فناوری نگاشت شیء به رابطه مصاحبه می‌شود. او درباره مفاهیم مشترک نگاشت‌گرها صحبت می‌کند و طیف ابزارهای مختلفی که تحت این نام وجود دارند را با هم مقایسه می‌کند. در ادامه به پیامدهایی که استفاده از نگاشت‌گرهای شیء به رابطه در معماری و طراحی دارند می‌پردازد.مایکل، لطفاً خود را معرفی کنید.سلام، از اینکه به این مصاحبه رادیو مهندسی نرم‌افزار گوش می‌دهید ممنونم. نام من مایکل پلاد است. من در شرکت فناوری‌های سناکور در نورمبرگ آلمان کار می‌کنم. نقش من توسعه‌دهنده ارشد یا معمار (هر چه اسمش را بگذارید) است. معمولاً بر روی پروژه‌های بلندمدت‌تر کار می‌کنم. چند سال پیش کار با نگاشت‌گرهای شیء به رابطه را آغار کردم. بیشتر با نگاشت‌گرهای مبتنی بر جاوا از قبیل Hibernate و JDO و امروزه JPA کار کرده‌ام. خوشحال می‌شوم که سئوالات شما را بشنوم و امیدوارم بتوانم به آن‌ها جواب دهم.بیایید با این سئوال شروع کنیم که نگاشت‌گر شیء به رابطه چیست؟ درباره چیست؟اساساً نگاشت‌گر شیء به رابطه چیزی است که به مسأله عدم تطابق بین اشیاء با روابط می‌پردازد. بین یک نرم‌افزار شیء‌گرا و پایگاه‌های داده یک عدم تطابق طبیعی وجود دارد. به‌عنوان مثال اگر به نحوه گروه کردن اشیاء یک حوزه (Domain) در مقابل نحوه تعریف کردن شِمای رابطه‌ای (Schema) نگاه کنید، به‌روشنی می‌بینید که از یک طرف با کلاس‌ها و خواص (Attribute) کار می‌کنید و نوع‌های داده‌ای دارید که یا مربوط به زبان برنامه‌نویسی است یا انواع داده‌ای است که خودتان داخل زبانی که با آن کار می‌کنید، تعریف می‌کنید. اما در طرف دیگر با جداول و ستون‌ها کار می‌کنید و این چیزها را داخل شِماها، گروه می‌کنید. در یک پایگاه داده رابطه‌ای نیز یک سیستمِ انواع داده دارید. اما در غالب پایگاه‌های داده این سیستم انواع داده خیلی ایستا است. البته برخی از پایگاه‌های داده، گونه‌هایی از پشتیبانی انواع‌های داده تعریف شده توسط کاربر را دارند. اما غالباً این پشتیبانی خیلی پیشرفته نیست.مطلب دیگر، جابه‌جا شدن (Navigation) است. وقتی در گرافی از اشیاء جابه‌جا می‌شوید، در یک نرم‌افزار شیء‌گرا یا کلاً در نرم‌افزار می‌دانید که چطور از یک موجودیت (Entity) مثلاً موجودیت A به سمت موجودیت B جابه‌جا شوید. اما در طرف دیگر (در پایگاه‌های رابطه‌ای)، جابه‌جایی، جهت ندارد. می‌توانید از جدول مشتریان به جدول صورتحساب‌ها جابه‌جا شوید اما در همان حال می‌توانید از طریق کلید خارجی (Foreign Key) از جدول صورتحساب‌ها به جدول مشتریان هم جابه‌جا شوید. بنابراین می‌بینید که یک مسیر جابه‌جایی وجود ندارد.بسیار خوب، اما برای دسترسی به داده‌ها، زبان برنامه‌نویسی SQL را دارید. چرا به نگاشت‌گر شیء به رابطه نیاز دارید؟ مزیت استفاده از یک نگاشت‌گر شیء به رابطه بر روی SQL نسبت به استفاده از فنونی که برای دسترسی مستقیم به پایگاه داده در زبان‌های برنامه‌نویسی وجود دارد، چیست؟اساساً از یک نگاشت‌گر  شیء به رابطه برای کپسوله کردن پایگاه داده استفاده می‌کنید. خیلی از شرکت‌ها می‌گویند که با استفاده از نگاشت‌گر شیء به رابطه می‌توانید به‌سادگی بین پایگاه‌های داده مختلف تعویض کنید. بله، این درست است. اما من می‌گویم که در اکثر پروژه‌های شرکت‌های بزرگ، تعویض کردن پایگاه داده، چیز خیلی نادری است. فکر می‌کنم مورد کاربرد و مزیت اصلی استفاده از یک نگاشت‌گر OR این است که توسعه‌دهندگان با اشیاء کار کنند و مقدار زیادی کدهای منطق کسب و کار (Business Logic) ننویسند که اغلب مربوط به پردازش دستورات SQL باشد.به‌علاوه، کتابخانه‌هایی که تعامل با SQL را پیاده‌سازی می‌کنند، خیلی سطح پایین هستند. به‌عنوان مثال اگر به JDBC، دقت کنید، یک کتابخانه سطح پایین است که در آن با دستورات و ResultSet ها کار می‌کنید و باید بر روی نتایج حرکت کنید و خیلی از امور مربوط به مدیریت منابع (Resource Management) را انجام دهید. از این منظر، نگاشت‌گر شیء به رابطه کاملاً این چیزها را کپسوله می‌کند. [در آنجا] با فایل‌های XML، یا حاشیه‌‌گذاری‌ها (Annotation) یا حتی از طریق قراردادهای نامگذاری (Code Convention)، گونه‌هایی از فراداده (Metadata) را دارید که به‌وسیله آن‌ها، توضیح می‌دهید که چطور کلاس‌هایتان را به جداول‌ نگاشت می‌کنید و توضیح می‌دهید که چطور ارث‌بری و روابط یا چیزهای دیگر را نگاشت می‌کنید.بنابراین، آیا کاربرد نگاشت‌گر شیء به رابطه، به‌منظور شبیه ساختن یک پایگاه داده رابطه‌ای به یک پایگاه داده شیء گرا است؟خیر، فکر نمی‌کنم منظور اصلی این بوده باشد. البته از منظر توسعه‌دهنده‌ها، در عین حال که با اشیاء کار می‌کنید همچنان به پایگاه داده هم دسترسی دارید. به‌عنوان مثال در JPA یا Hibernate، چیزی با عنوان جلسه (Session) یا مدیر موجودیت (Entity Manager) دارید که یک زمینه ثبت کردن (Persistence Context) است که می‌تواند به مثابه یک پایگاه داده شی‌ء گرا نگریسته شود. در آنجا برخی متدهای مرتبط با ثبت از قبیل ()save و ()list و ()retrieve و چیزهای شبیه به این داریم. اما آنها در واقع، پایگاه داده شیء گرا نیستند. به نظر من اشتباه است که با نگاشت‌گرهای شیء به رابطه مانند پایگاه داده‌های شیءگرا رفتار کنیم. البته آن‌ها برخی ویژگی‌های پایگاه داده‌های شیء گرا را دارند. مثلاً برخی پرس‌وجوهایی که به‌صورت ضابطه (Criteria) در برخی پیاده‌سازی‌های نگاشت‌گرهای شیء به رابطه داریم را در پایگاه داده‌های شیء گرا هم داریم اما در اینجا در انتها داده‌ها بر روی یک مخزن داده رابطه‌ای ذخیره می‌شوند.بنابراین گرچه یک الگوی برنامه‌نویسی شیء گرا دارید، همچنان باید آگاه بود که به‌علت جنبه‌های مربوط به کارایی و دیگر جنبه‌های غیرعملکردی (Nonfunctional)، داده‌ها بر روی یک پایگاه رابطه‌ای ذخیره می‌شوند.دقیقاً. من می‌گویم این توهم است که فکر کنید وقتی از یک نگاشت‌گر شیء به رابطه استفاده می‌کنید، دیگر نیازی به نگرانی در مورد مفاهیم رابطه‌ای و SQL ندارید. می‌دانم که تبلیغات زیادی دراین‌باره وجود دارد اما فکر می‌کنم این طرز فکر واقعاً خطرناک است زیرا شما به‌عنوان توسعه‌دهنده‌ای که با یک نگاشت‌گر شیء به رابطه کار می‌کنید باید بتوانید ببینید که چه جملات SQL ای به پایگاه داده ارسال می‌شود و آیا آن‌ها جملات SQL خوبی هستند یا جملات بدی هستند؟ و اینکه آیا تعداد خیلی زیادی از آنها ارسال می‌شود؟ بنابراین به‌عقیده من، اگر می‌خواهید کارتان را با یک نگاشت‌گر شیء به رابطه آغاز کنید همچنان به پیش‌زمینه SQL و پایگاه داده رابطه‌ای‌تان، نیاز دارید. خصوصاً اگر کارایی بالا (Performance) بخواهید این مطلب خیلی اهمیت می‌یابد.بله، متوجه می‌شوم. اما چند لحظه پیش گفتید که نگاشت‌گر شیء به رابطه، پایگاه داده را از شما کپسوله می‌کند اما الان می‌گویید که همچنان باید از جملات SQL ای که بخش‌های مابین نگاشت‌گر و پایگاه داده است نیز آگاه باشید. آیا این مزایایی که می‌توانید داشته باشید را کاهش نمی‌دهد؟بله و خیر. واقعیت‌هایی دراین‌باره وجود دارد. به‌عقیده من، نگاشت‌گر شیء به رابطه یک راه حل صددرصد کامل برای همه کاربردهای موجود نیست. خصوصاً اگر بخواهید بهبودهایی در میران کارایی پایگاه داده‌های میراث (Legacy) داشته باشید. من می‌گویم استفاده از نگاشت‌گر شیء به رابطه همواره یک راه حل ۹۵ درصدی یا ۹۰ درصدی برای زمانی است که با مسأله ترکیب کردن یک پایگاه داده رابطه‌ای با مدل‌های شیء گرا روبرو هستید. در اغلب موارد، کپسوله‌سازی را انجام می‌دهد. یعنی دیگر نیاز ندارید جملات SQL را بنویسید یا مدیریت منابع کنید. در غالب موارد فقط توضیح می‌دهید که یک شیء چگونه به پایگاه داده نگاشت می‌یابد و بدون اینکه مشکلی داشته باشید با آن کار می‌کنید. البته شرایط نادری وجود دارد که ممکن است به گزینه برگشت به SQL فکر کنید. من قطعاً این گزینه را منع نمی‌کنم اما فقط بادقت آن را اختیار کنید. برگشت به SQL، تنها در حالت‌های استثنا، ارزش فکر کردن دارد.بنابراین، [استفاده از نگاشت‌گرهای شیء به رابطه] مفید است. در اکثر موارد از طریق کپسوله‌سازی‌های خیلی زیاد کمک می‌کند اما در برخی شرایط خاص باید از اینکه زیر آن چه اتفاقی می‌افتد آگاه باشید. یعنی در وراء تبلیغاتی که در مورد آن می‌شود، باید بدانید هر چند مفید است اما به هر حال برای برخی شرایط باید از جزییات آگاه باشید.قطعاً. من می‌گویم وقتی که از نگاشت‌گرهای شیء به رابطه استفاده می‌کنید، لازم است که افرادی را در تیم داشته باشید که دانش جزییات نگاشت‌گرهای شیء به رابطه و SQL را داشته باشند. آنگاه آن‌ها، دانش را انتشار خواهند داد. بنابراین توسعه‌دهنده‌ای که در حال کد زدن منطق‌های عادی کسب و کار است نیاز ندارد که به همه ریزه‌کاری‌ها و اجزاء دقت کند. بنابراین من نمی‌گویم که باید همه توسعه‌دهنده‌ها در زمینه نگاشت‌گرهای شیء به رابطه یا SQL حرفه‌ای باشند. فقط لازم است اطمینان یابید که دانش در دسترس‌تان هست. و این برای توسعه‌دهنده‌های جاوا و روبی چیز کاملاً مطلوبی است که به‌سراغ مدیرسیستم پایگاه داده (DBA) بروند و به او بگویند:‌ «آیا این کاری که من اینجا دارم می‌کنم درست است؟». اغلب بین این تیم‌ها (تیم توسعه و تیم پایگاه داده و DBA) مرزهای زیادی وجود دارد اما اشتباه است و این مرزها نباید باشد.قطعاً درست است. بگذارید به‌سراغ جزییات مفاهیم پشت نگاشت‌گرهای شیء به رابطه برویم. نگاشت‌گر شیء به رابطه عملاً چه کاری می‌کند؟آنچه که نگاشت‌گر شیء به رابطه انجام می‌دهد این است که در ابتدای کار یک سری تنظیمات دریافت می‌کند به‌عنوان مثال تعریف می‌کنید که چگونه به پایگاه داده رابطه‌ای دسترسی پیدا می‌کنید. می‌گویید که برای همگام‌سازی تراکنش‌ها (Transaction) و برای پیدا کردن منابع داده (Data Source) و اتصالات به پایگاه داده، آیا در محیط‌های مدیریت‌شده (Managed) کار می‌کنید یا محیط‌های غیرمدیریت شده. تفاوت‌هایی بین محیط‌هایی که بر روی آن اجرا می‌شوید وجود دارد اما من نمی‌خواهم اینجا وارد جزییات شوم زیرا این‌ها بیشتر مرتبط با زیرساخت‌ها است. مطلب مهم‌تر این است که نگاشت‌گر شیء به رابطه، نوعی اطلاعات فراداده‌ای را می‌خواند که بیان می‌کند چگونه اشیاء را به جداول، نگاشت می‌دهید و اینکه چگونه روابط بین اشیاء را تعریف می‌کنید و چطور این روابط در پایگاه داده انعکاس می‌یابد. مثلاً برای یک رابطه یک به چند به منظور الحاق جداول به هم، گزینه‌های خیلی زیادی دارید. باید این اطلاعات را فراهم کنید و نگاشت‌گر شیء به رابطه با استفاده از این اطلاعات قادر خواهد بود دستورات SQL ای را فراهم کند که با اعمالی که می‌خواهید با نگاشت‌گر انجام دهید مطابقت داشته باشد.مفهوم مهم دیگر که در ارتباط با یک نگاشت‌گر شیء به رابطه داریم، مفهوم «لهجه» (Dialect) است. لازم است که نگاشت‌گر بتواند با انواع پایگاه داده‌های ممکن صحبت کند زیرا قصد دارید انتزاع داشته باشید و محدود به یک پایگاه داده خاص، نباشید. به همین دلیل است که [استفاده از] نگاشت‌گر شیء به رابطه، برای نرم‌افزارهایی که فروخته می‌شوند تا بر روی همه محیط‌های ممکن اجرا شوند، خیلی محبوب است.یعنی اگر تولیدکنندگان مختلف پایگاه داده، یک مسأله را با راه‌های مختلفی حل کرده باشند، نگاشت‌گر شیء به رابطه می‌داند که با هرکدام از آنها چگونه و با چه لهجه‌ای، صحبت کند بدون اینکه توسعه‌دهنده را مجبور کند که تفاوت‌های همه این محصولات را بشناسد.بله، دقیقاً. و حتی یک نگاشت‌گر شیء به رابطه خوب، بیشتر از این‌ها دانش دارد. به‌عنوان مثال، برخی دستورات SQL بر روی یک پایگاه داده خاص، بهتر از دستورات دیگر عمل می‌کنند. بنابراین دستورات SQL بهینه شده‌ برای لهجه‌های مختلف هم خواهید داشت. وقتی بخواهیم در مورد تأثیرات نگاشت‌گرهای شیء به رابطه بر روی کارایی صحبت کنیم، به این مبحث باز خواهم گشت.از مفاهیم اصلی دیگر یک نگاشت‌گر شیء به رابطه، سیستم انواع (Type System) است. در دنیای برنامه‌نویسی که شما با آن کار می‌کنید انواعی از داده‌‌ها وجود دارد و پایگاه داده هم، انواع داده خاص خودش را دارد. بنابراین، گاهی مواقع می‌خواهید که این انواع را به هم تبدیل کنید. نگاشت‌گر باید تسهیلاتی برای چگونگی نگاشت‌ دادن انواع‌تان داشته باشد به‌عنوان مثال وقتی می‌خواهید چگونگی ذخیره شدن نوع داده پول (Currency) در پایگاه داده را تعریف کنید. این بخش هم، یک بخش خیلی مهم از نگاشت‌گر شیء به رابطه است.بنابراین، نگاشت‌گر شیء به رابطه، به‌نوعی، بر میزان انتزاع می‌افزاید. وقتی می‌خواهید داده‌هایتان را در پایگاه داده مستقر کنید، سطح انتزاع بالاتری خواهید داشت. نیاز ندارید که همه تبدیلات را صریحاً در دستورات خام SQL قرار دهید. درست است؟بله، دقیقاً. شما از سیستم انواع، انتزاع می‌یابید. شما به عنوان یک برنامه‌نویس جاوا یا روبی یا ....، با انواع خودتان کار می‌کنید و لازم نیست که با هیچ نوع خاصی از SQL یا نوع خاصی از نگاشت‌گر شیء به رابطه، کار کنید و نگاشت‌گر است که لازم است این انتزاع از انواع داده خاص پایگاه داده را فراهم کند.بنابراین شما می‌گویید که یک نگاشت‌گر شیء به رابطه، سیستم انواع مربوط به برنامه را به سیستم انواع پایگاه داده تبدیل می‌کند و شما نحوه نگاشت بین آن دو را در تنها یک مکان تعریف می‌کنید و می‌توانید در همه جا از انواع داده مخصوص به منطق برنامه خودتان استفاده کنید و عملیات نگاشت به‌صورت خودکار انجام می‌شود.دقیقاً. در حالت ایده‌آل، برخی پیش‌فرض‌ها را دارید مثلاً string را به text یا varchar تبدیل می‌کنید. اما می‌توانید این را تغییر داده و بگویید می‌خواهم این چیز را به آن چیز نگاشت دهم.بسیار خوب. اینها در مورد انواع اولیه (Primitive) زبان بودند. در ارتباط با رابطه بین داده‌ها، ارجاعات، کلید خارجی و این چیزها چطور؟این چیزها باید در فراداده‌های (Metadata) نگاشت‌گر، مشخص شوند. یک مثال سنتی در مورد تفاوت بین پایگاه داده‌های رابطه‌ای و نرم‌افزارهای شیء گرا، روابط چند به چند هستند. در دنیای رابطه‌ای، برای آن‌ها، با ۳ جدول کار می‌کنید و همواره یک جدول الحاق (Join Table) یا نگاشت در میان قرار می‌گیرد، در حالی که در نرم‌افزار، فقط دو کلاس دارید که در هر کدامشان یک مجموعه (Collection) دارید. بنابراین اگر در کدتان، روابط یک‌طرفه یا دوطرفه‌ای داشته باشید، باید مشخص کنید که این روابط چگونه در پایگاه داده طراحی شوند. به‌عنوان مثال اگر یک رابطه یک به چند داشته باشید و اگر مثلاً این رابطه اختیاری (Optional) باشد، می‌توانید مشخص کنید که برایش یک جدول الحاق داشته باشید و ستون کلید خارجی و مواردی از این قبیل را تعیین کنید. این بخشی از فراداده و نیز بخشی از کدتان است. نکته خیلی مهم در اینجا این است که غالب نگاشت‌گرهای شیء به رابطه، برای شما، روابط دوطرفه را مدیریت نمی‌کنند. بنابراین این چیزی است که باید در کد شما انجام شود.در ارتباط با هویت شیء (Object Identity) چطور؟ در دنیای رابطه‌ای، همه چیزها مبتنی بر مقدار (Value Based) هستند و اگر دو سطر باشند که در مقادیر کلیه فیلدهایشان برابر باشند، نمی‌توان آنها را از هم تمیز داد اما در زبان‌های شیءگرا می‌توانید اشیائی داشته باشید که مقادیر و فیلدهای یکسانی داشته باشد اما همچنان اشیاء مجزایی باشند. نگاشت‌گرهای شیء به رابطه چگونه این فاصله را پر می‌کنند؟من با مفهوم موجودیت‌ها (Entity) آغاز می‌کنم. تعداد زیادی از نگاشت‌گرهای شیء به رابطه بین مولفه‌ها یا اشیاء مبتنی بر مقدار با موجودیت‌ها تفاوت قائل می‌شوند. موجودیت همواره یک شناسه ثابت دارد. این مفهومی است که به خوبی توسط  اریک ایوانز در کتاب طراحی مبتنی بر دامنه (Domain Driven Design) بیان شده است. من دوست دارم که همین دو کلمه را برای نگاشت‌گرهای  شیء به رابطه هم استفاده کنم. بگذارید با موجودیت آغاز کنیم. موجودیت، یک شناسه ثابت دارد. این، در دنیای رابطه‌ای به کلید اصلی (Primary Key) ارجاع دارد. اگر در یک مجموعه نتایج (Result Set) سطری داشته باشیم که کلید اصلی آن با سطر دیگری در مجموعه نتایج دیگری برابر باشد، آن دو سطر یکسان هستند. به همین خاطر است که همواره برای یک نگاشت‌گر شیء به رابطه، خصوصیت کلید اصلی یا خصوصیت شناسه را مشخص می‌کنید. اغلب به‌عنوان کلید اصلی با یک ستون یا یک ویژگی در کلاس موجودیت‌تان کار می‌کنید اما این می‌تواند به کلیدهای اصلی ترکیبی نیز گسترش یابد. به این ترتیب که دو یا سه ستون، کلید اصلی را بسازند و دو یا سه خصیصه، شناسه یا کلید اصلی شیء را بسازند. به این ترتیب نگاشت‌گرهای شیء به رابطه، کلید اصلی را بازتاب می‌دهند.در این زمینه، مفهومی با عنوان بررسی هویت (Identity Check) وجود دارد بعنوان مثال در زبان جاوا، برای اینکه یک کلید کسب‌وکاری (Business Key) داشته باشید، ()equals و ()hashCode را پیاده‌سازی می‌کنید. من دیده‌ام که در بسیاری از پروژه‌ها، کلید اصلی بخشی از این متدها را تشکیل می‌دهند که امر خطرناکی است زیرا کلید اصلی ممکن است در مراحل بعدی، ساخته شود. اگر یک شیء جدید مثلاً یک شیء مشتری جدید بسازید، کلید اصلی در انتهای تراکنش یا وقتی که شیء را در پایگاه داده ذخیره می‌کنید، ساخته می‌شود. بنابراین می‌توانید دو شیء مشتری داشته باشید که یکی از آنها کلید اصلی‌اش بر طبق نگاشت پیش‌فرض، به‌وسیله یک سرویس یا وب سرویس مقداردهی شده و دیگری به تازگی ساخته شده باشد. از دیدگاه منطقی دارید درمورد یک شیء صحبت می‌کنید اما اگر در متدهای ()equals و ()hashCode از کلید اصلی استفاده کرده باشید، در آن صورت بین این اشیاء تفاوت خواهید دید.نگاشت‌گرهای شیء به رابطه با این مسأله چطور برخورد می‌کنند که می‌توانیم چند شیء در زبان شیء گرا، داشته باشیم که به سطر یکسانی در پایگاه داده ارجاع دارند؟ چون این مفهوم هویت شیء (Object Identity)، در پایگاه داده وجود ندارد.از مفاهیم خیلی مهم برای برخی نگاشت‌گرهای شیء به رابطه، مفهوم هویت شیء است. این مفهوم در مورد همه نگاشت‌گرهای شیء به رابطه‌ای که به نوعی با مفهوم زمینه ثبت (Persistence Context) کار می‌کنند، وجود دارد. این مفهوم، در اغلب نگاشت‌گرهای شیء به رابطه، با عناوین واحد کاری (Unit of Work) و محتوای نهان‌گاه سطح اول (First Level Cache) نیز نامیده می‌شود. به‌عنوان مثال در یک چرخه ساده درخواست و پاسخ (Request &amp; Response) در برنامه‌های تحت وب، یک زمینه ثبت را باز می‌کنیم و مشتری‌هایی با شناسه‌های ۱ و ۲ و ۳ را بارگذاری می‌کنیم و بعداً این مشتری‌ها در زمینه ثبت، ذخیره می‌شوند. اگر در یک متد منطقی دیگر، به همین زمینه ثبت مراجعه کنیم و مشتری‌هایی با همین شناسه‌ها را دوباره بارگذاری کنیم، اشیاء یکسانی خواهیم گرفت. در این حالت هم عملگر مقایسه یعنی == برای دو شیء مورد نظر مقدار true برمی‌گرداند و هم طبعاً متدهای ()equals و ()hashCode این‌طور خواهند بود. اما اگر زمینه ثبت را ببندید یا اینکه اشیاء را از زمینه ثبت حذف کنید، دیگر تضمینی در مورد یکسان بودن اشیاء نخواهید داشت و در این حالت نمی‌توانید اطمینان داشته باشید که همچنان با اشیاء یکسانی کار می‌کنید.بسیار خوب. اساساً شما این مفهوم «واحد کاری» را دارید به این معنا که متناظر با یک تراکنش پایگاه داده و داخل یک واحد کاری، فقط یک شیء دارید که متناظر با یک سطر باشد. اما اگر چندین تراکنش داشته باشید که به‌صورت موازی در حافظه اجرا می‌شوند و تثبیت (Commit) می‌شوند، هر نوع ناسازگاری (Conflict) می‌تواند به وجود آید.بله، دقیقاً.به نظر می‌رسد فقط دو کار است که نگاشت‌گرهای شیء به رابطه انجام می‌دهند. یک مورد اساساً تغییر دادن و نوشتن اشیاء است و چیز دیگر پرس‌و‌جو گرفتن (Querying) به منظور خواندن داده‌ها است. بیایید به سراغ خواندن داده‌ها برویم. نگاشت‌گرها در این زمینه چه کاری می‌کنند؟ منظورم این است که قدرت مهم پایگاه‌های رابطه‌ای در این است که همه پرس‌وجوها در دنیا، با دستور Select زبان SQL کار می‌کنند. نگاشت‌گرها دراین‌باره چه‌کار می‌کنند؟برای بازیابی داده‌های پایگاه داده از طریق یک نگاشت‌گر شیء به رابطه، راه‌های فراوانی وجود دارد. اغلب به راه‌های دسترسی ساده فکر می‌کنید مثلاً اینکه با کلید اصلی پرس‌وجو کنید و یک شیء نماینده (Proxy) دریافت کنید که مقدارگیری تنبل (Lazy Initialization) دارد یا مثلاً می‌توانید با متد find (:all) در ActiveRecord همه داده‌های پایگاه داده را بارگذاری کنید (Active Record یک نوع فریم‌ورک نگاشت‌گر شیء به رابطه در زبان روبی است - مترجم). در کنار این‌ها، در اکثر نگاشت‌گرهای شیء به رابطه، یک زبان پرس‌وجو دارید. تفاوت بزرگ بین زبان پرس‌وجوی نگاشت‌گر و SQL این است که در زبان نگاشت‌گر شما پرس‌وجو‌ها را بر روی اشیاء و نه بر روی جداول و ستون‌ها انجام می‌دهید.اگر شما با پیش‌زمینه SQL بیایید و بخواهید کار با زبان پرس‌وجوی یک نگاشت‌گر شیء به رابطه را آغاز کنید، اولین چیزی که باید از آن آگاه باشید همین تفاوت است زیرا در اینجا با جداول سروکار ندارید. مطلب دیگر در مورد این زبان پرس‌وجو، شیء گرایی بیشتر است به‌عنوان مثال، ضابطه (Criteria) را داریم که به‌وسیله آن، زبان پرس‌وجوی مبتنی بر متن به یک زبان پرس‌وجوی مبتنی بر اشیاء انتزاع می‌یابد.بنابراین، شما API ای دارید که می‌توانید پرس‌وجو‌ها را به‌وسیله آن به هم متصل کنید.بله. شما با استفاده از API، می‌توانید قیود (Restriction)، تصویر کردن‌ها (Projection) و ترتیب‌ (Ordering) را تعریف کنید. همچنین به‌وسیله آن، نحوه واکشی داده‌ها از پایگاه داده را هم مشخص می‌کنید زیرا بعضی وقت‌ها می‌دانید که وقتی مثلاً یک مشتری را از پایگاه داده می‌خوانید، همیشه می‌خواهید که آدرس‌هایش را هم داشته باشید بنابراین می‌توانید این کار را در یک واکشی انجام دهید. استراتژی واکشی را می‌توانید هم به روش شیء گرا و با واسط ضوابط (Criteria) مشخص کنید و هم می‌توانید با روش مبتنی بر متن در زبان پرس‌وجو مشخص کنید.جنبه دیگر، پرس‌وجو با مثال (Querying By Example) است. این هم اغلب بخشی از واسط ضوابط مربوط به نگاشت‌گر است که در آنجا، به‌وسیله شیء مثالی، پرس‌وجو می‌کنید. مثلاً می‌گویید: «همه مشتری‌های با نام کوچکِ Arno». و همچنین برخی اشارات برای نگاشت‌گر فراهم می‌کنید مثلاً می‌گویید که یک تطابق کامل (Exact Match) می‌خواهید و یا می‌خواهید که به بزرگی و کوچکی حروف حساس نباشد و از این قبیل. این تسهیلات دیگری در زمینه پرس‌وجو است که برای صفحات جستجو قابل استفاده است.امروزه اغلب نگاشت‌گرهای شیء به رابطه، استفاده مستقیم از SQL را هم پشتیبانی می‌کنند. البته وقتی با یک نگاشت‌گر کار می‌کنید، این انتخاب اول نیست اما کاربردهایی وجود دارد که بخواهید برای برخی ویژگی‌‌های خاص پایگاه داده از آن استفاده کنید. مثلاً اگر بخواهید برخی تنظیم کردن‌های (Tuning) سطح پایین پایگاه داده را انجام دهید می‌توانید به استفاده مستقیم از SQL برگردید و در این‌حال، نگاشت‌گر، عملیات تبدیل مجموعه نتایج برگشتی دستور SQL به اشیاء مورد استفاده‌تان را انجام خواهد داد.امروزه نگاشت‌گرهای شیء به رابطه، خیلی رواج دارند. خیلی از محصولات خود را نگاشت‌گر شیء به رابطه می‌نامند. Hibernate و NHibernate را داریم، در Rails، آن را داریم. خیلی چیزها هست. آیا می‌توانید یک تصویر کلی به ما بدهید که چه انواعی از نگاشت‌گرهای شیء به رابطه وجود دارد و تفاوت آن‌ها چیست؟ یک مقداری آن‌ها را دسته‌بندی کنید.بسیار خوب. من ابتدا با این دسته‌بندی شروع می‌کنم که آیا یک نگاشت‌گر شیء به رابطه، مفهوم «واحد کاری» یا «زمینه ثبت» را پشتیبانی می‌کند؟ در این دسته، Hibernate قرار دارد. JDO نیز در همین دسته قرار می‌گیرد. در دنیای جاوا در مشخصات JPA نیز مفهوم «واحد کاری» بیان شده است. NHibernate نیز در همین دسته قرار می‌گیرد. دسته بعدی، نگاشت‌گرهای شیء به رابطه‌ای هستند که اطلاعات فراداده را اخذ می‌کنند اما می‌توانم بگویم همچنان خیلی دستورگرا (Statement Oriented) هستند. به‌عنوان مثال اگر به پشتیبانی که در Rails می‌شود مثلاً Active Record نگاه کنید، می‌بینید که مفهوم «زمینه ثبت» را ندارد؛ یک شیء را می‌سازید و آن را در پایگاه داده ذخیره می‌کنید و اگر بعداً همان شیء که در پایگاه داده ذخیره کرده‌اید را تغییر دهید، باید متد ()update را فراخوانی کنید بنابراین در اینجا، آن همگام‌سازی پنهانی با پایگاه داده را نخواهید داشت. در اینجا باید همواره بگویید که تغییرات من را با پایگاه داده همگام کن.از طرف دیگر LINQ را داریم که بیشتر یک زبان پرس‌وجو است. LINQ محدود به پایگاه داده رابطه‌ای نیست. وقتی از اشیاء پرس‌وجو می‌کنید لینک به اشیاء دارید و وقتی از ساختارهای XML پرس‌وجو می‌کنید، لینک به XML دارید و زمانی که با پرس‌وجو‌های پایگاه داده کار می‌کنید، لینک به SQL دارید. اما LINQ، نگاشت اشیاء به جداول پایگاه داده را هم دارد؛ می‌توانم بگویم یک نوع نگاشت خیلی مبتنی بر ابزار (Tool Driven) است اما تمرکز اصلی LINQ بر روی پرس‌وجوها است و البته ابزارهایی برای ذخیره و بروزرسانی بر روی پایگاه داده هم دارد.همچنین بحث‌های زیادی وجود دارد که آیا برخی فریم‌ورک‌های سطح پایین مربوط به دستورات هم می‌توانند فریم‌ورک نگاشت‌گر شیء به رابطه‌ تلقی بشوند یا خیر. به‌عنوان مثال در زبان جاوا، iBatis را داریم که نگاشت‌گر SQL است اما خیلی دستورگرا است. من این ابزارها را کم‌وبیش به‌عنوان اجزاء فریم‌ورک می‌بینم اما آنها را نگاشت‌گر شیء به رابطه‌ نمی‌دانم. آن‌ها جنبه‌هایی از نگاشت‌گرهای شیء به رابطه‌ را دارند اما همچنان خیلی به دستورات (Statement) اختصاص دارند. شما پرس‌وجو‌های خودتان را تعریف می‌کنید. این ابزارها، برای اشیاء شما پرس‌وجو‌ها را نمی‌سازند. آنجا شما مجبورید همه اعمال ایجاد، خواندن، حذف و بروزرسانی و ... را خودتان مشخص کنید.اینها دسته‌های اصلی هستند که در ارتباط با نگاشت‌گرهای شیء به رابطه‌ می‌توانم تشخیص دهم.شما در ارتباط با مدل‌های مختلف برنامه‌نویسی در نگاشت‌گرهای شیء به رابطه‌ مختلف صحبت کردید. فرض کنید من توسعه نرم‌افزار جدیدی را آغاز می‌کنم و به استفاده از یک نگاشت‌گر فکر می‌کنم. چطور کار را پیش ببرم؟ استفاده از یک نگاشت‌گر چه تأثیراتی بر روی طراحی و معماری نرم‌افزارم خواهد داشت؟من اول بررسی می‌کنم که آیا واقعاً برای نرم‌افزارم، به یک نگاشت‌گر شیء به رابطه‌ نیاز دارم؟ اگر یک نرم‌افزار وِب خیلی کوچک دارم و فقط دو یا سه کلاس دارم که می‌خواهم آن‌ها را در پایگاه داده قرار دهم، شاید نگاشت‌گر شیء به رابطه‌ فقط یک کتابخانه‌ای باشد که تنظیمات بیشتر و فراداده بیشتر را به‌همراه داشته باشد و با SQL خالص خیلی سریع‌تر باشم. اما بیشتر پروژه‌هایی که وجود دارند، پیچیده‌تر هستند. در این حالت، باید تشخیص دهم که کدام دسته از نگاشت‌گرهای شیء به رابطه‌ را می‌خواهم استفاده کنم. آیا می‌خواهم یک نگاشت‌گر شیء به رابطه‌ کاملاً مجهز که خیلی قدرتمند باشد، داشته باشم؟ اغلب، برای موارد کاربرد ساده، استفاده از آنها خیلی راحت است اما همچنان، یک پیچیدگی‌ هم اضافه می‌کنند زیرا توسعه‌دهنده تیم باید مثلاً آگاه باشد که تغییراتش بر روی اشیاء، پنهان از دید او، با پایگاه داده همگام می‌شوند. این ممکن است به نواحی مختلف ناسازگاری (Conflict) رهنمون شود. آیا در تیم توسعه، چنین دانشی از نگاشت‌گرهای شیء به رابطه‌ وجود دارد؟ اگر این‌چنین است، می‌توانید به راحتی جلو بروید و یکی از این نگاشت‌گرها را بکار بگیرید. اگر این‌طور نیست، شاید یک متخصص در زمینه نگاشت‌گر شیء به رابطه‌ را اضافه کنید.یک توصیه عمومی وجود دارد که تکنولوژی‌های جدید از هر نوعش را به خدمت بگیریم. اما فرض کنید که من یک نرم‌افزاری دارم که به مقدار کافی بزرگ است و محقق ارشد من، به من می‌گوید که Hibernate و NHibernate گزینه‌هایی از همان نگاشت‌گرهای شیء به رابطه‌ کاملاً مجهز هستند که انتخاب‌های خوبی هستند. (استفاده از آن‌ها) چه تأثیراتی بر روی طراحی و معماری نرم‌افزارم خواهد داشت؟اثرش این است که اول از همه باید، به نرم‌افزارتان، فراداده اضافه کنید. شما اغلب، از یک طرف کلاس‌ها و اشیاء و روابط بین آنها را دارید و از طرف دیگر پایگاه داده را دارید که باید آن‌ها را برای نگاشت‌گر، کنار هم بگذارید. بنابراین نیاز دارید که فراداده‌اش را یا از طریق DSL های خارجی یا از طریق تنظیمات یکپارچه شده، بیان کنید. مطلب دیگری که باید با برنامه‌تان یکپارچه کنید مدیریت زمینه ثبت یا واحد کاری است. این‌که چه زمانی واحد کاری‌ام آغاز می‌شود؟ و اینکه چگونه آن را پایان می‌دهم؟به نوعی طرح‌ریزی مرزهای تراکنش‌ها.دقیقاً. اینکه چگونه مدیریت تراکنش‌ها را طرح‌‌ریزی و یکپارچه می‌کنم؟ آیا در یک محیط مدیریت‌شده (Managed Environment) یا غیرمدیریت‌شده کار می‌کنم؟ و اینکه آیا پشتیبانی از محاوره‌های طولانی را نیاز دارم یعنی، زمینه ثبت را باز نگه می‌دارم و هربار، تثبیت (Commit) می‌کنم و در انتها عمل بیرون فرستادن (Flush) را انجام می دهم؟ و همین طور باید به این فکر کنید که با شیء نگاشت‌شده چه‌کار می‌کنید. در صورتی که یک برنامه تحت وب یا RPC باشم، آیا اشیاء نگاشت‌شده را مستقیماً به برنامه کلاینت، می‌دهم؟ آیا برای لایه سرویس با لایه دیگری مثلاً لایه DTO کار می‌کنم؟ این‌ها نیز باید درنظر گرفته شوند.فرض کنید من می‌خواهم توسعه یک نرم‌افزار جدید را از صفر شروع کنم که البته بهترین حالت و رؤیای هر توسعه‌دهنده‌ای است :-) آیا با ساختن مدل شیء خودم کار را آغاز می‌کنم و سپس آن را به یک روش سررراست به پایگاه داده نگاشت می‌دهم؟ یا اینکه ابتدا پایگاه داده‌ام را طراحی می‌کنم و بعد آن‌ها را بر روی اشیائم تصویر می‌کنم؟ چطور کار می‌کنم؟ اول اشیاء یا اول پایگاه داده؟البته وقتی شما به‌عنوان یک برنامه نویس شیء گرا توسعه می‌دهید معمولاً می‌گویید که اول اشیاء هستند. من هم فکر می‌کنم اشیائی که در برنامه‌تان با آن کار می‌کنید باید تا حد ممکن گویا باشند. اما من شاید هر هفته، با متخصص پایگاه داده صحبت می‌کنم و به او می‌گویم که چنین ساختار اشیائی دارم و می‌خواهم به این شکل آن‌ها را در پایگاه داده نگاشت دهم. آیا همین خوب است یا اینکه مشکل کارایی در آن می‌بینید؟ چرا که اگر یک مدل اشیاء خیلی خوب داشته باشید اما سمت پایگاه داده، خرابکاری کرده باشید، ارزش کسب و کار نرم‌افزارتان به شدت پایین می‌آید. من همواره با اشیاء آغاز می‌کنم اما جنبه‌های مربوط به استقرار در پایگاه داده را هم در ذهن دارم و به آن اهمیت می‌دهم یا می‌دهم کسی، نحوه تفکرم درباره پایگاه داده را بازبینی کند.بنابراین شما می‌گویید که اشیاء، انتزاع اصلی هستند اما مهم است که مدل پایگاه داده را هم در ذهن داشته باشیم و یک سفر رفت و برگشت داشته باشیم و بگذاریم هر دو موازی با هم جلو بروند.بله، در واقع من می‌گویم این کار بهتر است. من همواره با یک متخصص حوزه کسب و کار که دانش کاملی از آن حوزه دارد، می‌نشینم و مدل اشیائم را طراحی می‌کنم و سپس با طراح داده‌ها صحبت می‌کنم که او چطور در مورد این مدل اشیاء فکر می‌کند و چطور می‌توانیم آنها را در پایگاه داده انعکاس بدهیم. من فکر می‌کنم این تعامل بین این ۳ دیدگاه، یعنی: طرف کسب و کار، طرف توسعه دهنده شیء گرا و طرف پایگاه داده، باعث می‌شود کاراترین برنامه کاربردی ساخته شود.بسیار خوب. مطلب دیگر، کپسوله کردن خروجی نگاشت‌گر شیء به رابطه‌ است. آیا باید یک لایه DAO برای کپسوله کردن نگاشت‌گر داشته باشم یا اینکه می‌توانم هرجا خواستم از آن استفاده کنم؟من می‌دانم که بحث‌هایی دراین‌باره وجود دارد. خصوصاً در جاوا برای بیان مشخصات (Specification) برای JPA این بحث‌ها بوده است. اما من قطعاً در مورد الگوی DAO جوابم مثبت است. چند دلیل برای آن وجود دارد. دلیل اول این است که نمی‌خواهم در منطق کسب و کارم (Business Logic) با تکنولوژی‌های مختص ثبت (Persistence Specific) سروکار داشته باشم. این جزیی از منطق کسب و کار نیست و اساساً بخش‌های مربوط به منطق کسب و کار نباید از این باخبر باشد که چه زمان و چگونه داده‌ها ذخیره می‌شوند. اینها باید انتزاع یابند.مطلب بعدی این است که به این طریق می‌توانید بین تکنولوژی‌های ثبت کردن، تعویض کنید. البته معتقدم این ضعیف‌ترین استدلال است زیرا معمولاً یک استراتژی ثبت کردن را ارزیابی می‌کنید، آن را تست می‌کنید، تست فشار (Stress Test) می‌کنید و بعد آن را به محیط توسعه می‌برید. کمتر رخ می‌دهد که روش ثبت کردن خود را عوض کنید، البته رخ می‌دهد حتی می‌توانم بگویم از اینکه بخواهید پایگاه داده را عوض کنید، بیشتر رخ می‌دهد. اما مزیت اصلی لایه DAO این است که می‌توانید یک رفتار استاندارد برای نحوه کار کردن با API نگاشت‌گر شیء به رابطه تعریف کنید. به‌عنوان مثال وقتی من با شناسه، دنبال چیزها می‌گردم آیا از قبل پایگاه داده را برقرار کرده‌ام یا اینکه با نماینده‌ها (Proxy) صحبت می‌کنم؟ یا به‌عنوان مثال در Hibernate، آیا از متدهای ()save و ()update استفاده می‌کنم یا با ()merge کار می‌کنم؟ چگونه محتویات زمینه ثبت (Persistence Context) را به پایگاه داده می‌ریزم؟فکر می‌کنم شما می‌گویید که جزییات تعاملات با نگاشت‌گر شیء به رابطه باید به‌روشی انتزاع یابد تا به شکل یکنواختی انجام شود و منطق کسب و کار را به‌هم‌ریخته نکند.این یک استدلال است و استدلال دیگر این است که بتوانم یک رفتار استانداردشده در یک کلاس انتزاعی که کلاس والد DAO باشد تعریف کنم و در حالت ایده‌آل، توسعه‌گران فقط نیاز باشد که دیگر کارها را پیاده‌سازی کنند.بسیار خوب. در ارتباط با بارگذاری تنبل (Lazy Loading) چطور؟ بارگذاری تنبل ویژگی است که خیلی از نگاشت‌گرهای شیء به رابطه دارند. بارگذاری تنبل به این معناست که وقتی، بر روی نمونه‌های اشیاء جابه‌جا می‌شوید، اشیاء در پس‌زمینه واکشی می‌شوند و پرس‌وجو‌های SQL در پس‌زمینه اجرا می‌شوند. آیا این گونه رفتار به نوعی پیوند دادن (Coupling) منطق کسب ‌و کار به نحوه ثبت از طریق درِ پشتی نیست؟بله، به‌نوعی درِ پشتی است. به اعتقاد من الگوی بارگذاری تنبل، الگوی خیلی خوبی است زیرا اگر از بارگذاری تنبل استفاده نمی‌کردیم این خطر وجود داشت که با هر درخواستی، نیمی از پایگاه داده را حتی اگر نیازی به آن‌ها نداشتیم را بارگذاری کنیم. الگوی بارگذاری تنبل می‌گوید: «تنها وقتی چیزها را بارگذاری می‌کنیم که واقعاً به آن‌ها نیاز داشته باشیم». به‌عنوان مثال اگر مجموعه‌ای (Collection) داشته باشم و برخی از اعضاء آن را نیاز داشته باشم، این مجموعه بصورت تنبل بارگذاری می‌شود. البته در این حالت، برخی عملیات در منطق کسب‌ و کار، برخی دستورات SQL را راه‌اندازی می‌کند اما هیچگاه منطق کسب و کار به زمینه ثبت، نمی‌گوید که: «لطفاً این را برایم مقداردهی اولیه کنید». این‌کار پنهان از دید منطق کسب‌ و کار انجام می‌شود. من طرفدار این استدلال نیستم که از طریق بارگذاری تنبل، یک پیوستگی سخت (Tight Coupling) بین منطق کسب و کار و [روش] ثبت کردن ایجاد می‌شود.درباره سرباری که با در میان قرار دادن نگاشت‌گر مابین برنامه و پایگاه داده ایجاد می‌شود چطور؟ آیا تأثیر منفی بر روی کارایی ندارد؟بله و خیر. بله به این علت که لایه اضافی و یک کتابخانه اضافی دارید که در برنامه‌تان اجرا می‌شود و این با مقداری هزینه در کارایی (Performance) همراه خواهد بود. اما برای اغلب نگاشت‌گرهای شیء به رابطه امروزی، در بیشتر نرم‌افزارها این امر نمایان نمی‌شود مگر برنامه‌های به شدت بلادرنگ با نیازهای کارایی بالا، که چنین ملاحظاتی داشته باشند. خیلی از برنامه‌های معظم (Enterprise) که من در آنها کار کرده‌ام، سربار نگاشت‌گر را حتی حس هم نمی‌کردند زیرا از طرف دیگر، یک نگاشت‌گر خوب این حس را دارد که با توجه به لهجه‌ پایگاه داده‌ای که با آن کار می‌کنید، دستورات SQL خوبی را اجرا کند. در لهجه یک پایگاه داده خاص، این دانش هم وجود دارد که کدام دستور SQL در آن پایگاه داده کارا است و کدام دستور کارا نیست. بنابراین برنامه‌نویسان عادی که معمولاً مقداری دانش SQL دارند، نیازی ندارند که در مورد جزییات مربوط به کارایی پایگاه داده نگران باشند. این مطلب کپسوله می‌شود. من با تعدادی از مدیرسیستم‌های پایگاه داده (DBA) صحبت کرده‌ام که می‌گفته‌اند که SQL ای که نگاشت‌گرها تولید می‌کنند، کاملاً خوب است. این‌طور نیست که همه چیز در مورد آن‌ها خوب باشد اما در اکثر موارد می‌گویند که آخر سر، وقتی یک مورد کاربرد را تست می‌کنند، کارایی بهتر شده است.منظورتان این است که کارایی دسترسی به پایگاه داده از طریق یک نگاشت‌گر از کارایی دستورات دست‌نوشته SQL معمولی بهتر است؟بله، خصوصاً نسبت به یک چیز معمولی که یک توسعه‌دهنده عادی نوشته باشد. البته اگر توسعه‌دهنده‌هایی داشته باشید که خبره پایگاه داده باشند، آنها همواره می‌توانند، بر نگاشت‌گرها چیره شوند چرا که همه ریزه‌کاری‌ها را می‌دانند اما در آن صورت از پایگاه داده انتزاع نمی‌یابید و برنامه‌تان دیگر، قابل انتقال (Portable) نخواهد بود.شبیه به بحث‌هایی است که در مورد اثرات کارایی ماشین مجازی در مقابل کدهای دست‌نوشته اسمبلی داریم.بله، شبیه به آن است. همواره افرادی را می‌یابید که می‌گویند که نگاشت‌گرها خیلی کند هستند ولی من فکر می‌کنم که واقعیت این است که همه توسعه‌دهنده‌‌ها نمی‌توانند خبره پایگاه داده باشند به این معنی که بتوانند کاراترین دستورات SQL را بنویسند. فکر می‌کنم نگاشت‌گرها اگر درست استفاده شوند، حداقل، کارایی را کاهش نمی‌دهند.در ارتباط با نهان‌گاه (Cache) چطور؟ شما از «واحد کاری» گفتید و اینکه معمولاً در حوره مُجزای تراکنش‌ها، نهان‌گاه داریم. به نوعی نهان‌گاه داریم اما در حوزه دید یک تراکنش واحد است. در مورد نهان‌گاه‌‌های طولانی‌تر چطور؟ آیا می‌ارزد که این کار را بکنیم؟ نگاشت‌گرها چه سطحی از پشتیبانی را در این ارتباط دارند؟ آیا ایده خوبی است که از آن استفاده کنیم و اگر بله چه موقع خوب است که از آن استفاده کنیم و چه وقت باید از آن بپرهیزیم؟من دیدگاه خیلی محتاطانه‌ای در مورد استفاده از نهان‌گاه دارم. توصیه من این است که قبل از اینکه بخواهید نهان‌گاه سطح دوم را به نگاشت‌گر بیافزایید، ابتدا خود دسترسی به داده‌ها را تنظیم‌کاری (Tuning) نمایید. به این معنی که تنها داده‌هایی که واقعاً نیاز دارید را بارگذاری کنید؛ در پرس‌وجوهایتان به روابط تجمعی (Aggregation) و تصویر کردن‌ها (Projection) فکر کنید و پرس‌وجوهایتان را از قبل، تنظیم‌کاری نمایید. بعد از آنکه این کار انجام شد، می‌توانید بررسی کنید که کدام موجودیت یا کدام مورد کاربرد، از نهان‌گاه سود می‌برد زیرا هر نوع کلاسی از نهان‌گاه سود نمی‌برد. به‌عنوان مثال یک گزینه خیلی بد برای استفاده از نهان‌گاه، داده‌های مالی هستند زیرا اگر به‌خاطر آن به مشکلی بخورید، سازمان‌تان پول زیادی را از دست می‌دهد!من داده‌ها را دسته‌بندی می‌کنم. [گزینه کاندید برای نهان‌گاه]، برخی داده‌ها هستند که به‌ندرت تغییر می‌کنند و توسط تعداد زیادی کاربران مختلف استفاده می‌شوند و همچنین داده‌های خیلی حساسی هم نیستند. من داده‌های خیلی حساس را در نهان‌گاه نمی‌گذارم.به این خاطر که استفاده از نهان‌گاه خطر غیرمعتبر شدن مقادیر را افزایش می‌دهد.بله، در اینجا باید بین سطوح مختلف مجزاسازی (Isolation Level) مرتبط با نهان‌‌گاه تفاوت قائل شوید. در اغلب نهان‌گاه‌ها می‌توانید یک سطح مجزاسازی مشخص تعریف کنید که می‌تواند از یک نهان‌گاه‌ کاملاً تراکنشی و خوشه‌بندی شده‌‌ (Clustered) و تکرارشده (Replicated) تا یک نهان‌‌گاه ساده باشد که همچنان سطح مجزاسازی «خواندن تثبیت‌شده‌ها» (Read Committed) بر روی تراکنش‌ها را پشتیبانی می‌کند و بیشتر در زمان بیکاری کار می‌کند و بین خوشه‌ها به اشتراک گذاشته نشده است و تنها بر روی یک نمونه قرار دارد و برای آن، همگام‌سازی بین گره‌ها، وجود ندارد. از این بحث مشخص می‌شود که با استفاده از نهان‌گاه دارید پیچیدگی‌هایی به زیرساخت‌ها اضافه می‌کنید. ممکن است برای نهان‌گاه‌های کوچک‌تر خیلی پیچیده نباشد اما برای اضافه کردن یک نهان‌‌گاه که کاملاً تراکنشی و خوشه‌بندی شده تکرار شده باشد، همواره پیچیدگی‌های خیلی زیادی اضافه می‌شود. به اعتقاد من این کار نباید توسط متخصص نگاشت‌گر شیء به رابطه انجام شود و برای این کار، من از یک متخصص نهان‌گاه درخواست می‌کنم زیرا چیزهای زیادی باید در آنجا تنظیم شود.بسیار خوب، بنابراین استفاده از نهان‌گاه آخرین گزینه است و چیزی نیست که بخواهیم به کرّات از آن استفاده کنیم.نه، من می‌گویم از نهان‌گاه استفاده کنید اما وقتی که قبل از آن همه چیزهای دیگر را تنظیم‌کاری کرده باشید. نهان‌گاه برای پرس‌وجوها هم خیلی استفاده می‌شود اما به اعتقاد من، در بیشتر کاربردها، خیلی کارا نیست. شما می‌توانید موجودیت‌ها، روابط و پرس‌وجوها را در نهان‌گاه قرار دهید اما قرار دادن پرس‌وجوها در نهان‌گاه خیلی به‌ندرت توجیه دارد. اگر می‌دانید که یک پرس‌وجو با پارامترهای یکسانی بارها فراخوانی می‌شود، توجیه می‌یابد.در ارتباط با مهاجرت دادن داده‌ها (Data Migration) چطور؟ آیا وقتی برنامه‌ها به روش‌های مختلفی از طریق نگاشت‌گرهای شیء به رابطه به داده‌ها دسترسی پیدا می‌کنند، مسأله ایجاد می‌کند؟قطعاً. خصوصاً اگر در محیطی که نهان‌گاه وجود دارد کار می‌کنید. زیرا هیچ‌گاه نمی‌دانید که چه زمانی برنامه دیگری در پس‌زمینه، داده‌ها را تغییر می‌دهد. این مورد خصوصاً وقتی رخ می‌دهد که با یک پایگاه داده موجود کار می‌کنید که روال‌های ذخیره‌شده (Stored Procedure) یا برخی نرم‌افزارهای قدیمی خودش را دارد و آنگاه یک نرم‌افزار جدید با یک معماری جدید را آغاز می‌کنید که همه چیزش خوب است و در آن از تکنولوژی‌های برتر استفاده شده است. در آن صورت هیچ‌گاه دسترسی انحصاری به پایگاه داده ندارید و باید آگاه باشید که در پس‌زمینه ممکن است چیزها تغییر کنند.بنابراین بله، به‌عقیده من در محیط‌هایی که نهان‌گاه وجود دارد، این کار خطرناک است. در این‌گونه موارد من کاملاً نسبت به استفاده از نهان‌گاه محتاط هستم و برای بیشتر موجودیت‌ها آن را توصیه نمی‌کنم.شما به روال‌های ذخیره‌شده (Stored Procedure) اشاره کردید. خیلی‌ها این‌طور تصور می‌کنند که آن‌ها سریع‌ترین روش برای برنامه‌های با نیازمندی‌های کارایی بالا (High Performance) هستند. اما آن‌ها با نگاشت‌گرها خیلی خوب کار نمی‌کنند. یا می‌کنند؟!در واقع خیر. شما در نگاشت‌گرهای شیء به رابطه، پشتیبانی از روال‌های ذخیره‌شده (Stored Procedure) را دارید اما معمولاً این پشتیبانی خیلی محدود است. من به شخصه هیچ‌گاه آن‌ها را با یک نگاشت‌گر استفاده نکرده‌ام. البته درست است که آن‌ها خیلی سریع هستند و کارایی کاملاً بالایی دارند اما باید بدانید با استفاده از آنها داده‌ها را به منطق کسب‌وکار مقید می‌سازید. البته در بسته‌هایی کپسوله شده‌اند اما به‌عقیده من قابلیت نگهداری (Maintainability) یک روال ذخیره‌شده از قابلیت نگهداری یک کد شیء‌گرا که خوب نوشته شده باشد، کمتر است. البته می‌توانید کدهای شیء‌گرایی هم بنویسید که قابلیت نگهداری نداشته باشند اما علی‌الخصوص با روال‌های ذخیره‌شده، راحت نیست که بفهمید که چه جاهایی از یک سری داده‌ها استفاده شده است.به‌عقیده من روال‌های ذخیره‌شده، برای کارهای دسته‌ای (Batch Job) خیلی عالی هستند. این حوزه‌ای است که اغلب نگاشت‌گرها، در آن شکست می‌خورند زیرا یک نگاشت‌گر یک ابزار برای کارهای دسته‌ای با نیازمندی کارایی بالا نیست. به‌عقیده من، این حوزه اصلی روال‌های ذخیره‌شده است.فکر می‌کنم، مطالب را پوشش دادیم. چیزی هست که بخواهید اضافه کنید؟بله، خیلی ممنونم که گوش دادید. اگر بازخورد یا نظری دریافت کنم خوشحال می‌شوم که پاسخ دهم. در ارتباط با استفاده از نگاشت‌گرهای شیء به رابطه، تشویقتان می‌کنم که آن‌ها را حتماً مدنظر قرار دهید اما فقط زمانی آنها را اضافه کنید که ارزشی را ایجاد کنند. خصوصاً در مورد استفاده از نهان‌گاه کمی محتاط باشید. من شما را درباره آن دلسرد نمی‌کنم اما نسبت به آن‌ها حالت احتیاط داشته باشید. و همچنین هر تبلیغی که می‌گوید: «اگر از نگاشت‌گر شیء به رابطه استفاده کنید دیگر نیازی به فراگیری SQL ندارید» را باور نکنید. این یک دروغ است! :-)</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Wed, 19 Jan 2022 21:09:28 +0330</pubDate>
            </item>
                    <item>
                <title>توسعه نرم‌افزار به روش تَرکه‌ای (Lean)</title>
                <link>https://virgool.io/se-radio/%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%A8%D9%87-%D8%B1%D9%88%D8%B4-%D8%AA%D9%8E%D8%B1%DA%A9%D9%87-%D8%A7%DB%8C-lean-uj58rwlvdpib</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۱۹۰ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت، کریستوف ابرت، رییس بخش مدیریت شرکت خدمات مشاوره‌ای وکتور، با فرانسیس پالیش درباره نگرشش به بکارگیری روش ترکه‌ای در تولید محصول صحبت می‌کند. این مصاحبه حول ۵ اصل کلیدی توسعه ترکه‌‌ای یعنی این موارد است: تمرکز سر تا سری (end-to-end) در خلق ارزش برای مشتری، حذف هدررفت، بهینه‌سازی جریان‌های ارزش، قدرت بخشیدن به افراد و بهبود مستمر. این پادکست IEEE  به جای تئوری‌های مدیریت یا تولید، به مبحث توسعه ترکه‌ای نرم‌افزار می‌پردازد. در این پس‌زمینه، به دنبال آن هستیم که این سوال اصلی را طرح کنیم که کدام اصول طراحی، باعث تحویل ارزش می‌شوند و چگونه برای مدیریت بهینه تغییر بکار گرفته شده‌اند؟ بسیاری از مثال‌های عملی بیانگر نحوه بکارگیری روش ترکه‌ای بدون در تنگنا قرار دادن توسعه است. کریستف، آیا ممکن است خود را معرفی کنید.سلام. من کریستوف ابرت هستم. من یکی از مدیران شرکت خدمات مشاوره‌ای وکتور هستم. ما به مشتریان‌مان درسراسر دنیا کمک می‌کنیم که به صورت پایدار، استراتژی‌های مربوط به محصول، توسعه محصول و مدیریت تغییرات سازمانی را بهبود دهند. خدمات مشاوره‌ای وکتور بخشی از گروه وکتور است که در کل جهان، ۱۱۰۰ کارمند دارد و در همه قاره‌ها خدمات دارد. پیش از کار کنونی‌ام، من چندین سمت در مدیریت‌های جهانی داشتم.من در تعدادی از مشاوره‌های صنعتی شرکت داشته‌ام و درس‌هایی هم در دانشگاه اشتوتگارد و دیگر دانشگاه‌ها ارائه کرده‌ام. در سال‌های گذشته چند مورد کتاب پرفروش نیز داشته‌ام. آخرین کتابم، Global Software and IT است که توسط WILEY و IEEE انتشار یافته است. در این گفتگو، نگاهی به توسعه ترکه‌ای خواهیم داشت و اینکه چطور در نرم‌افزار و IT به خدمت گرفته شده است. اغلب توسعه ترکه‌ای، به تولید کارخانه نسبت داده می‌شود. ما قواعد آن و اینکه چطور در پروژه‌های نرم‌افزاری و IT بکار گرفته می‌شوند را بیان می‌کنیم. برای این منظور، به آخرین شماره مجله نرم‌افزار IEEE ارجاع می‌دهیم. در آنجا ما تعدادی مطالعه موردی درباره به خدمت گرفتن روش ترکه‌ای در نرم‌افزار و IT داشته‌ایم.بسیار خوب. من فکر می‌کنم خیلی از شنوندگان ما با موضوع چابک (Agile) در حوزه مهندسی نرم‌افزار آشنا هستند. اما شاید خیلی با موضوع توسعه نرم‌افزار با رهیافت ترکه‌ای آشنا نباشند. آیا می‌توانید خصوصاً برای کسانی که با چابک آشنا هستند، ارتباط ترکه‌ای و چابک را تصویر کنید؟ آیا خیلی مشابه هم هستند؟ تفاوت‌ها و مشترکاتشان چیست؟اخیراً توسعه ترکه‌ای، توجه زیادی را جلب کرده است زیرا به خوبی توانسته است بین نیاز به ارزش‌آفرینی و نیاز به قدرت بخشیدن به افراد و تیم‌ها و حرکت کردن در جهت یک محصول خلاقانه، تعادل برقرار کند. توسعه به روش ترکه‌ای یک اصل مهم برای کمک به شرکت‌هایی است که گهگاه در بهبود بازده خود مشکل دارند.منظورتان این است که چابک برای پروژه‌های خاص است اما ترکه‌ای بیشتر یک فلسفه و یک امر کلی است؟فکر می‌کنم خوب باشد که برخی نقاط تمایز را ببینیم. من نمی‌خواهم برای مجزا کردن این دو تکنیک، روش خیلی سیاه و سفیدی داشته باشم. این دو با هم مرتبط هستند و همدیگر را تقویت می‌کنند. قطعاً متضاد یکدیگر نیستند. این طور نیست که یا باید ترکه‌ای باشیم یا چابک. در ادامه ترکه‌ای را تعریف خواهیم کرد و به تکنیک‌های کلیدی آن نگاهی می‌اندازیم. آن زمان، ساده‌تر می‌توانیم مسأله را متوجه شویم. اما فعلاً می‌توانم بگویم که این دو تکنیک همدیگر را تقویت می‌کنند و همان طور که پیش از این گفتم، ارزش‌آفرینی، یک فصل مشترک این دو است.شما اگر بخواهید می‌توانید ارزش را به روش پایین به بالا ایجاد کنید. نگاه می‌کنید که کارها را چطور انجام می‌دهید و چطور می‌توانید آنها را بهتر انجام دهید. مثلاً اینکه چطور می‌توانید در کد زدن، کارایی بیشتری داشته باشید یا چطور می‌توانید از همان ابتدا از خطاها جلوگیری کنید. شما می‌دانید برای این منظور، چیزی با عنوان TDD داریم که یک تکنیک چابک است که قبل از آن که کد را بنویسید فکر می‌کنید که چطور آن را تست خواهید کرد. با این نوع روش فکر کردن در مورد ارزیابی قبل از نمونه‌سازی، جلوی خیلی از خطاها را می‌گیرید.همین تکنیک در سطح محصول هم استفاده می‌شود مثلاً اینکه آیا این ویژگی را در چنین بازاری نیاز داریم یا اینکه فقط یک سربار ایجاد می‌کند؟ این همان چیزی است که آن را توسعه ترکه‌ای می‌نامیم. اینجا می‌خواهم به صورت شفاف تأکید کنم که این دو تکنیک همدیگر را تقویت می‌کنند و اینطور نیست که مسأله، انتخاب یکی یا دیگری باشد.موردی که هنوز در مورد آن صحبت نکرده‌ایم، افراد و اهمیت آنها است. آیا در ارتباط با احترام به افراد، قدرت بخشیدن به افراد و کار کردن با همدیگر، مشترکاتی بین آنها وجود دارد؟ چون همان طور که می‌دانید ممکن است در برخی روش‌های توسعه، افراد به صورت منابع قابل تعویض در نظر گرفته شوند.بله. فکر می‌کنم زمان آن رسیده است که به شکل خلاصه مؤلفه‌های اصلی توسعه ترکه‌ای را معرفی کنم. آن زمان می‌بینید که هرکدام از این مؤلفه‌های اصلی، یک همزاد (برادر یا خواهر) در چابک دارند.من یکی از این موارد که IEEE، تمایز داده است را گفتم که همان ارزش‌آفرینی است و من به این علت با این مورد شروع کردم که حوزه دید درستی به ما می‌دهد. شما قطعاً درست گفتید. مورد دوم، تمرکز بر افراد است. ارزش، منظره بیرونی است؛ اینکه نیاز مشتری‌ها چیست. اما مورد دوم، افراد و تیم هستند؛ اینکه چطور می‌توانیم تیم را برای تعامل بهتر قدرت ببخشیم و افراد چگونه می‌توانند به منظور ارزش‌آفرینی با همدیگر کار کنند.مورد سوم، حذف هدررفت‌ها (Waste) است. پیشتر به این بعد اشاره کردم که می‌توانید در سطح کد با بکارگیری برخی تکنیک‌های هوشمندانه خطاها را کاهش دهید و یا در سطح محصول از ویژگی‌‌هایی که باعث پیچیدگی‌های بعدی می‌شود جلوگیری کنید که در اصطلاح Fred Books، به آن پیچیدگی‌های ناخواسته (Accidental Complexity) گفته می‌شود که چیزهایی هستند که لازم نیستند و ارزشی به همراه نمی‌آورند.مورد چهارم، بهینه‌سازی جریان ارزش (Value Stream) است که به معنای توجه به فعالیت‌‌های مرتبط و کارا کردن آنهاست. به عنوان مثال از اینکه یک طراح به علت آماده نبودن کار منتظر همکارش باشد، جلوگیری کنیم. یا اگر سئوالات خیلی زیادی وجود دارد و افراد، مشخصات کار را متوجه نشده‌اند، این وضعیت قطعاً خیلی ناکارآمد است. از همین منظر، بهینه‌سازی جریان ارزش، قاعده چهارم است.مورد پنجم و آخر از لیست من، بهبود مستمر است. این تکنیک برای هر نوع فرآیند مهندسی، کلیدی است زیرا اگر نخواهیم از جنبه‌های مختلف فناوری، فرآیند و مهارت‌ها یادگیری داشته باشیم، صنعت موفقی نخواهیم داشت. هیچ‌گاه نباید گمان کنیم که کامل هستیم. نه محصول ما، نه فناوری ما، نه فرآیندمان، نه خودمان به‌ عنوان اشخاص، هیچ‌کدام کامل نیستیم.این ۵ مورد یعنی ارزش‌آفرینی، قدرت بخشیدن به افراد، حذف هدررفت‌ها، بهینه‌سازی جریان ارزش و بهبود مستمر، قواعد اصلی توسعه ترکه‌ای هستند. منظورم توسعه به همان معنایی است که در نرم‌افزار با عنوان توسعه نرم‌افزار داریم. همانظور که گفتم هرکدام از این ۵ مورد، با تکنیک‌های چابک مرتبط هستند و از این منظر، مشترکات زیادی دارند. تمایزشان تنها در نحوه نگاه کردن به آنهاست. اگر بیشتر با یک دید جامع به آن نگاه کنید، آن را توسعه ترکه‌ای می‌نامیم اما اگر از منظر خاص خودتان که چطور می‌توانم جنبه کدنویسی خودم را به روش بهتری انجام دهم، نگاه کنید در آن صورت بیشتر با قواعد چابک مرتبط هستند.به‌صورت پیش‌فرض، وقتی از ترکه‌ای صحبت می‌کنیم مربوط به حوزه تولید و کارخانه است. در حوزه توسعه نرم‌افزار، مدیریت ترکه‌ای از چه جنبه‌هایی متفاوت است؟ فکر می‌کنم در حوزه توسعه نرم‌افزار، تغییرپذیری‌های (Variability) بیشتری در محصول وجود دارد و مؤلفه‌های غیرقطعی خیلی بیشتری وجود دارد که باعث می‌شود فرد مجبور شود ترکه‌ای را کمی متفاوت‌تر بکار بگیرد. فکر می‌کنم الیستر کوبرن، خیلی در این مورد صحبت کرده است که (در توسعه نرم‌افزار) اطلاعات و تصمیم‌ها هستند که در محصول جریان می‌یابند. شاید این یک نگاه سودمندی باشد. به نظر شما تفاوت ترکه‌ای در تولید کارخانه با ترکه‌ای در توسعه نرم‌افزار چیست؟بله، فکر می‌کنم که مهم است به این تفاوت‌ها نگاه کنیم زیرا اغلب می‌بینم که شاغلین نرم‌افزار این‌طور واکنش نشان می‌دهند که: «ما در مورد ترکه‌ای بیشتر در ارتباط با تولید خودرو تویوتا شنیده‌ایم. آیا فقط در مورد تولید خودرو نیست؟». واضح است که این دید عمومی است و از لحاظ تاریخی، ابتدا ترکه‌ای برای تولید استفاده می‌شده است و مدتی گذشت تا ارتباط آن با مهندسی ایجاد شد. می‌خواهم تأکید کنم که متدهایی که ترکه‌ای در تولید داشته به نوعی محرک بوده‌اند. قطعاً آنها چیزهایی نیستند که امروزه در توسعه نرم‌افزار به روش ترکه‌ای می‌بینیم اما موارد متناظر زیادی می‌تواند دیده شود. مثلاً اینکه باید از هدررفت مانع شد یا آن را از بین برد. این چیزی است که هم در تولید و هم در توسعه نرم‌افزار می‌بینید. قدرت بخشیدن به افراد هم نمونه دیگری است.اگر بخواهیم بیشتر از مثال‌هایی که در تولید مطرح است، استفاده کنیم باعث می‌شود افراد گیج شوند. این تله‌ای است که می‌بینم برخی افراد در آن گیر می‌افتند که بیشتر به این مشترکات می‌پردازند و کمتر به امور خاص توسعه نرم‌افزار می‌پردازند. شما قطعاً درست می‌گویید. در نرم‌افزار، تفاوت‌های زیادی وجود دارد. یکی از آنها که شما به آن اشاره کردید این است که در اینجا، جریان اطلاعات را درنظر می‌گیرید و تغییرپذیری‌ها و چرخه حیات نرم‌افزار خیلی با تولید کارخانه متفاوت است که در آن ممکن است محصولات با روبات تولید شوند. بنابراین  نباید بیش از حد به مشترکات نگاه کنیم. یک نقطه تاریخی وجود دارد که توسعه ترکه‌ای از تولید ترکه‌ای منشعب شد. اما مربوط به خیلی قبل می‌شود و امروزه هیچ کس به آن زمان بر نمی‌گردد. باید به زمان حال پرداخت.اما آنچه باید قطعاً به عنوان یک شاغل انجام دهیم این است که از آنچه در حوزه‌های دیگر مهندسی اتفاق می‌افتد آگاه باشیم. دقت کنیم که با نگاه کردن به دیگر صنعت‌ها چه می‌توانیم بیاموزیم. این نقد دیگر من به کسی است که می‌گوید: « ترکه‌ای برای من نیست. من در نرم‌افزار هستم و ترکه‌ای به کارم نمی‌آید زیرا محصول‌مان متفاوت است». من انتظار دارم که ذهن این فرد برای دریافت محرک‌های جدید باز باشد. مانند محرک‌هایی که از معماری و مهندسی عمران گرفتیم. من می‌بینم که محرک اولیه برای رشد معماری نرم‌افزار در طی ۱۵ سال گذشته، از مهندسی عمران بوده است.من اغلب علاقه‌مندم که بدانم چطور توسعه ترکه‌ای در حوزه‌های دیگر مهندسی بکار گرفته شده است و چه چیزهایی می‌توانیم از آنها بیاموزیم تا در تکامل توسعه نرم‌افزار به روش ترکه‌ای بکار بگیریم. برای اینکه بیشتر روشن شود یک مثال می‌زنم. هم در چابک و هم در ترکه‌ای مفهوم دوباره‌کاری را داریم که به چیزی گفته می‌شود که غیرضروری است. اما چطور ضروری را از غیرضروری، تمایز می‌دهیم؟ تکنیک‌های متفاوتی وجود دارد. یکی از این تکنیک‌ها، که سال‌ها پیش توسط آلن دیویس، نامگذاری شد، قاعده‌ای است که تریاژ نام دارد. از آن برای این منظور استفاده می‌شود که بتوانیم بر اساس تعداد خیلی کمی سئوال‌، این کار (تمایز موارد با اولویت و ضروری) را انجام دهیم. مثلاً این سئوال که نحوه مشارکت آن ویژگی خاص در کل محصول چیست؟ اما اگر به این نکته توجه کنید که تریاژ از کجا آمده است، متوجه می‌شوید که از پزشکی آمده است. اگر دکتر در یک وضعیت اورژانسی برسد و چندین بیمار، وجود داشته باشند. نمی‌تواند ۱۰ نفر را همزمان رسیدگی کند. در این شرایط از تریاژ استفاده می‌کند تا بفهمد در همان موقع به چه کسی باید رسیدگی کند. اگر ما چنین پیش‌زمینه‌ای از حوزه‌های دیگر نداشتیم، نمی‌توانستیم این قاعده را در حوزه IT بکار ببریم.بله، نکته خوبی بود. ما می‌توانیم برای اولویت‌بندی و مسائل این‌چنینی از آن استفاده کنیم. فکر می‌کنم این کاملاً درست باشد که بهترین استفاده را از حوزه چابک، از ترکه‌ای و حوزه‌ تولید و ... ببرید و روش خود را طوری که مناسب سازمان و نیاز‌هایتان باشد، گسترش دهید. شاید بهتر باشد به اولین نکته‌ای که اشاره کردید برگردیم. در مورد ارزش‌آفرینی که من فکر می‌کنم خیلی با مبحث مهندسی نیازها (Requirement Engineering) نیز مرتبط است و این حوزه‌ای است که شما خیلی در آن فعال هستید. نقطه تعادل مناسب کدامست؟ برخی مواقع گفته می‌شود که برای اینکه بتوانید اطمینان یابید که از ابتدا کار را درست انجام می‌دهید باید مقداری زیادی طراحی‌های از قبل داشته باشید. این را در خارج از فضای ترکه‌ای گاهی می‌شنوید. از طرف دیگر، می‌شنویم که گفته می‌شود طراحی را در آخرین زمان ممکن انجام دهید. شما آن را چگونه و چه زمان انجام می‌دهید؟ چه مقدارش را از پیش انجام می‌دهید و چه مقدارش را به تأخیر می‌اندازید؟هر دو درست هستند. باید هر دو قاعده را متوجه شویم. آنها با هم در تضاد نیستند و همدیگر را تکمیل می‌کنند. آنچه باید قطعاً از آن پرهیز کنیم این است که در بخش تحلیل زیاده‌روی کنیم. این چیزی است که فلج‌ شدن با تحلیل (Paralysis By Analysis) خوانده می‌شود زیرا خیلی کند می‌کند. باید بدانیم که هیچ‌گاه نمی‌توانیم ریز جزییات را شناسایی کنیم. تفاوت اصلی در اینجا این است که نحوه آغاز کار را درست بشناسیم. اینکه چه ویژگی‌‌هایی بیشترین ارزش را برای کاربر یا مشتری (در هر کجای بازار که باشد) ایجاد می‌کنند و یا مواردی که در یک محصول جدید می‌تواند یک ویژگی جدید متمایزکننده باشد. و در همین حین از طرف دیگر، باید انعطاف را برای محصولات مجزا حفظ کنیم زیرا برخی از نیازمندی‌ها، غیرقطعی هستند. خصوصاً در پروژه‌های نرم‌افزاری و IT این یک قاعده است که از امکان تغییرپذیری‌ها برای امکان تکامل محصول‌مان حفاظت کنیم. ممکن است بخواهیم به بازارهای دیگری وارد شویم. ممکن است بخواهیم به سمت یک نسخه گران‌قیمت از محصول‌مان برویم. به‌عبارت دیگر، وقتی ما استخراج نیازها را آغاز می‌کنیم، سئوال اصلی در ابتدای کار این است که آیا این نیازمندی‌ها ارزش‌آفرین هستند؟ این باید با هوشمندی ارزیابی شود، از دیدگاه‌های مختلف و پروفایل‌های مختلف به آن نگاه کنید. اینها همه تکنیک‌های نیازسنجی هستند که امروزه خیلی استفاده می‌شود.برای اینکه بخواهید تکنیک تریاژ که پیش از این به آن اشاره کردم را انجام دهید و نیازمندی را بیابید که بیشترین ارزش را دارد یعنی چیزی که برایش کسی بیشترین پرداخت را می‌کند، یک مثالی برای‌تان می‌زنم. این مثال مربوط به شرایطی است که افراد می‌گویند همه نیازمندی‌ها اولویت بالا دارند و همه آنها را همین حالا می‌خواهیم. در این شرایط شما ۱۰۰ تا نیازمندی‌ دارید و روبروی مشتریان می‌نشینید. به هر کدامشان ۱۰۰ دلار می‌دهید و از آنها می‌خواهید که حالا شما ویژگی‌های موردنظر خود را بخرید. آنها می‌دانند که چند نفر دیگر هم در اتاق هستند که آنها نیز ویژگی‌ها را می‌خرند. به این ترتیب آنها، سرمایه‌شان را هوشمندانه تقسیم می‌کنند. این یک بازی است که مشخص شده است که خیلی کارآمد است. چون آن‌ها بر اساس یک راهبرد پول‌هایشان را روی ویژگی دلخواه سرمایه‌گذاری می‌کنند، و تقریباً در تمامی موارد به دو دسته از نیازمندی‌ها می‌رسیم که مشخص می‌کند که کدام‌یک از نیازمندی‌ها دارای ارزش واقعی هستند و کدام‌یک جنبه‌ی تزئینی دارند. این یکی از اصل‌های (تعیینِ) ارزش است.مورد دیگری که با موضوعی که ما «حذف هدررفت‌ها» نامیدیم ارتباط دارد، درک این مطلب است که چه نیازمندی‌ها و ویژگی‌هایی تأثیر زیادی بر روی معماری دارد. و روشن است که این موارد باید در ابتدای کار، درک شوند زیرا اگر چیزی تأثیر زیادی بر روی معماری دارد بهتر است که آن را در ابتدا انجام دهیم. مثال خوب آن، ویژگی‌های کیفی مانند امنیت (Security) و قابلیت استفاده (Usability) و ... است که باید از همان ابتدا ارزیابی شود زیرا دیر انجام دادن آن، به معنای از دست دادن زمان زیاد و دوباره‌کاری است.من خیلی این روش شما را تقدیر می‌کنم که اغلب تأکید می‌کنید که مسأله، فقط چیزی نیست که مشتری می‌گوید که می‌خواهد بلکه باید عمیقاً متوجه شوید که مشتری واقعاً چه چیزی را می‌خواهد. لازم است آن‌قدر عمیق شوید تا بفهمید مشتری واقعاً این موارد از قبیل کارآیی (Performance)، مقیاس‌پذیری (Scalability) و ... را نیاز دارد.درباره موضوع تصمیم‌گیری در ابتدای کار و اینکه چه کاری را انجام دهیم و اینکه آن کار چقدر مناسب است، نیاز به مقدار زیادی مهارت‌های نرم (Soft Skills) است. این کار یک مذاکره سرراستی نیست. زیرا به این شکل نیست که (به مشتری) بگویید: «به من آن نیازمندی را بده و اگر این کار را سریع انجام بدهی من به نیازمندی‌های دیگر نیاز ندارم.» این‌طور نیست. درعوض، به همراه مشتری، نیازمندی، تکامل و توسعه داده می‌شود.و خیلی جالب است که در مهندسی نیازمندی‌ها و در ارزش آفرینی، یک سیر تکامل داشته‌ایم. ۱۰ سال پیش ما در مورد جمع‌آوری نیازمندی‌ها صحبت می‌کردیم تا اینکه جامعه متوجه شد چیزی برای جمع‌آوری وجود ندارد. به محض اینکه جمع‌آوری نیازمندی‌ها را آغاز کنید در مسیر اشتباهی افتاده‌اید. آنچه مهمتر است این است که نیازمندی‌ها را توسعه دهید. آنها را استخراج کنید. آنها را به همراه مشتری، به همراه کسی که واقعاً بازار را می‌شناسد، کسی که نیازهای آینده را می‌شناسد، کشف کنید. اگر چیزها را فقط به این خاطر که دیگران آن را در محصولاتشان قرار داده‌اند، جمع‌آوری کنید، همواره عقب خواهید بود. این مطلب کلیدی است که در طول دهه گذشته فراگرفته شده است. این چیزی است که هم‌ارز هم، هم در توسعه چابک و هم در توسعه ترکه‌ای بوجود آمده است، فقط از منظرهای مختلفی ارائه شده است.جنبه دیگر مرتبط با ارزش‌آفرینی، این است که ممکن است فردی، دانش را هم در حوزه ارزش قرار دهد. من می‌دانم موضوعی با عنوان تصمیم‌گیری مبتنی بر مجموعه (Set Based Decision Making) وجود دارد که فکر می‌کنم از فرهنگ تولید ترکه‌ای کارخانه‌ای می‌آید. در آنجا، انتخاب‌های خود را باز نگه می‌دارید. اجازه می‌دهید که روش‌های جایگزین برای مدت زمان بیشتری، زنده بمانند. این گاهی مواقع برای مدیران، آزاردهنده است زیرا به مدیران نشان نمی‌دهد که چه بگویند. مدیران دوست دارند که روی میز بزنند و بگویند که: « فقط انجامش دهید. تصمیم بگیرید که کدام مسیر را می‌خواهید بروید و انجامش دهید و پروژه را به پایان برسانید.» اما شاید یکی از چیزهایی که ما می‌خواهیم در ترکه‌ای انجام دهیم این است که سعی کنیم گزینه‌ها را باز نگه داریم. زیرا اگر حتی در آینده یکی از آنها را دور بیاندازید، این هدررفت نبوده است زیرا برایتان ارزش آورده است. نه به معنای یک مصنوع (Artifact) بلکه خود دانشی که داشته است فکر می‌کنم ارزشمند بوده است.این قطعاً درست است. در واقع شما دو نکته خیلی درست را اشاره کردید. یکی اینکه، ما به‌ صورت پیوسته در حال یادگیری هستیم و حتی در ارزیابی طراحی‌های مختلف یا در تصمیم‌گیری‌های صریح هم در حال یادگیری هستیم مثلاً اینکه کدام بخش سیستم را کامل‌تر از دیگر بخش‌ها، تست کنیم. همان طور که گفتید به‌صورت پیوسته چیزی را دور می‌اندازیم و بقیه را نگه می‌داریم. من به خاطر می‌آورم که یکی از آموخته‌های مهمی که در ۱۵-۱۰ سال گذشته داشته‌ایم مربوط به تصمیم‌های زیادی بوده است که در شرایط غیرقطعی داشته‌ایم، (که البته در همه زمینه‌های مهندسی این‌طور است اما ما در مورد نرم‌افزار و IT صحبت می‌کنیم) بنابراین به تکنیک‌هایی نیاز داریم که امکان چنین تصمیم‌گیری‌هایی را فراهم کند. و البته باید آن تصمیم‌ها را به‌صورت کارآیی اجرا کنیم که داستان دیگری است.اما نکته مهمی که معمولاً نادیده گرفته می‌شود این است که برای اینکه بتوانیم تصمیم بگیریم نیاز به انتخاب‌های جایگزین داریم تا با مقایسه و ارزیابی کردن این انتخاب‌های جایگزین بر اساس یک معیار تصمیم بگیریم. حتی امروزه هم، اغلب این کار انجام نمی‌شود. معمولاً به‌صورت حسی یکی را انتخاب می‌کنیم. شاید ۳ انتخاب جایگزین را در کنار هم بگذاریم اما در انتها، بدون سنجش با هیچ معیار ارزیابی، خیلی سریع به سراغ یکی از آنها می‌رویم. این بد است زیرا ما همواره، اهداف ناسازگار داریم. مثلاً در تصمیماتی که در مورد معماری نرم‌افزار دارید، می‌خواهید که یک سیستم خیلی کارا و همزمان با یک سطح امنیتی خیلی بالا داشته باشید و می‌خواهید تصمیم بگیرید که تا چه میزان صحت‌سنجی داشته باشید. مثلاً می‌خواهید هرکدام از بسته‌های مجزا را ارزیابی کنید یا اینکه می‌خواهید آنها را با یک مقیاس بزرگتر، خوشه‌بندی کنید. در آن صورت کارایی بهتر خواهد بود اما شکنندگی بیشتری هم خواهد داشت. این‌ها همه انتخاب‌های ممکن هستند و در ارزیابی این انتخاب‌های ممکن، ما یاد می‌گیریم. یادگیری، به‌وضوح یک ارزش‌آفرینی است حتی اگر در انتهای کار، یک ویژگی را تحویل ندهیم.جنبه دیگری که به نظر من به همان میزان مرتبط است این است که وقتی ما انتخاب‌هایی برای تصمیم‌گیری داریم باید این تصمیم را هم بگیریم که چه زمانی انتخاب کنیم. همان‌طور که پیش از این گفتم، گاهی خوب است که این کار را زود انجام دهیم زیرا اگر اشتباه بکنیم، تأثیرات جانبی (Side Effect) زیادی دارد و دوباره‌کاری زیادی ایجاد می‌کند و گاهی مواقع بهتر است که آن را دیر انجام دهیم یا حتی مناسب است آن را برای همیشه باز نگه داریم همانطوری که ما امروزه از طراحی متغیر (Variant Design) استفاده می‌کنیم به این ترتیب که تعدادی نقاط تغییرپذیری (Variation Point) نگاه می‌داریم که می‌توانیم در آن نقاط، به روش کارایی پیاده‌سازی‌های مختلف را تعویض کنیم. این کار را همان‌طور که پیش از این گفتم وقتی که به سمت تولید یک نسخه گران‌قیمت از برنامه می‌رویم انجام می‌دهیم تا اطمینان حاصل کنیم که بتوانیم سیستم‌ را از راه دور، بروزرسانی کنیم و نیاز نباشد برای آن کدهای مختلف داشته باشیم. وقتی در ارتباط با حذف هدررفت‌ها فکر می‌کنیم، این پیش‌بینی و طرح‌ریزی برای‌ تصمیم‌ها در زمان درست، آموخته مهم دوم است.بسیار خوب. شاید خوب باشد که به سراغ دومین قاعده برویم: «تمرکز بر افراد». زیرا فکر می‌کنم همان‌طور که همین حالا گفتید، تمرکز با یادگیری و تجربه مرتبط است. اگر شما نتوانید آن روش منطقی تصمیم‌گیری بین انتخاب‌های ممکن را داشته باشید، مجبورید به تجربه افراد اعتماد کنید. منطقی است که افراد را به شکل یک سری منابع که در زمان دلخواه، قابل تعویض هستند نبینیم. بنابراین فکر می‌کنم در حوزه ترکه‌ای، سعی می‌شود که تیم تا حد ممکن قدرت داده شود. و ارزش زیادی به این گذاشته شود که آنها به خوبی آموزش دیده‌اند. شما در تیم‌ها بیشتر یک هوش توزیع‌شده و تصمیم‌گیری توزیع شده دارید. فکر می‌کنم این بخش خیلی مهمی از توسعه ترکه‌ای است. آیا شما در این زمینه تجربه‌ یا نظری دارید؟بله. از نظر من «قدرت بخشیدن» یکی از فاکتورهای مهم موفقیت است. همچنین قاعده‌ای است که ما آن را در توسعه ترکه‌ای آموزش می‌بینیم، آن را در چابک آموزش می‌بینیم و همین‌طور آن را در خیلی تئوری‌های دیگر مدیریت نیز می‌یابید. بعنوان مثال، اگر روند تکامل از سطح سازمانی به سطح افراد را در نظر بگیرید می‌بینید که این تأثیر یادگیری، خیلی زودتر از آنکه کسی در نرم‌افزار آن را تجربه کند، وجود داشته است.اما شما گفتید که هنوز در ابتدای کار اغلب یک روش تصمیم‌گیری خیلی سلسله‌مراتبی را می‌بینیم. منظور توسعه ترکه‌ای، از قدرت بخشیدن به افراد این است که برای اینکه تیم بتواند تصمیم‌گیری کند و تصمیمات درستی بگیرد، باید به آنها دانش داده شود. باید مهارت داده شود تا پس‌زمینه‌های کار را درک کنند. این چیزی است که ما اغلب در مورد پیاده‌سازی واقعی آن مردد هستیم. زیرا در این صورت، از دید بیرونی تیم به اموری خواهد پرداخت که کار آنها نیست. به‌عنوان مثال باید کسب‌وکار مشتریان را بشناسند. باید ارتباطات با اجزاء و مؤلفه‌های دیگر را بشناسند. آنها باید تعامل بین ویژگی‌ها را بشناسند. باید نقشه راه (Roadmap) را بشناسند. در اینجا هر مدیر معمولی می‌گوید که چرا تیم باید همه این چیزها را بداند؟فکر می‌کنم مدیران از نظر روانشناسی هم نمی‌خواهند اجازه دهند کار به این شکل پیش برود.بله. دقیقاً. این یک دلیل است. دلیل دیگر زحمات اضافه‌ای است که باید صرف شود. از طرف دیگر، وقتی شما در یک سازمان رشدیافته، می‌روید متوجه می‌شوید که تیم‌ها، به مقدار کافی کوچک هستند که نخواهند انرژی‌شان را صرف چیزی کنند که به‌کلی بی‌نتیجه باشد بلکه سئوالاتی می‌پرسند که اگر متوجهش شوند، تأثیرگذار خواهد بود. و اغلب با تیم‌ها در یک سیر تکاملی کار می‌کنند. ابتدای کار، تیم‌ها خیلی هدایت‌شده هستند که می‌توانید نمونه آنها را در سیستم‌های نظامی ببینید، در کارخانه هم این روش تا حدی معنی می‌دهد اما در تولید نرم‌افزار که کلی امور غیرقطعی و قیود دیده نشده دارید، واقعاً این روش کارآمد نیست.به خاطر وجود این همه امور غیرقطعی و قیود دیده نشده خوب است که تیم پیش‌زمینه لازم برای تصمیم‌گیری را داشته باشد. این انتقال هم برای مدیر خط (Line Manager) و هم برای تیم، چالش بزرگی است. شما قطعاً درست گفتید که وقتی یک تیم این نوع مهارت‌ها را فرا می‌گیرد، به‌وضوح رشد می‌یابد. در عین حال مدیر خط، از این می‌هراسد که کار زیادی برای انجام ندارد.بگذارید شفاف بیان کنیم که شرکت‌هایی که سریعترین نرخ رشد در رقابت‌ها و در ارزش‌آفرینی با یک محصول را داشته‌اند، عموماً شرکت‌های Startup هستند. علتش این است که هرفردی در تیم، درک عمیقی از شرایط زمینه‌ای، محیط و کسب‌و‌کار دارد. به همین دلیل است که در تولید چیزهای جدید این‌قدر سریع هستند. ما نیاز داریم که این قواعد را رشد دهیم. این کار مستقل از اینکه شرکت کوچک باشد یا یک شرکت خیلی بزرگ چندملیتی باشد، جواب می‌دهد. من روند انتقال به توسعه ترکه‌ای و قدرت‌بخشی به تیم را در شرکت‌های خیلی بزرگ دیده‌ام؛ شرکت‌هایی که چندین هزار کارمند در سراسر جهان دارند. وقتی که تیم را قدرت می‌بخشید و می‌گذارید در حوزه‌های خاصی حرکت داشته باشند، می‌بینید که روی‌هم‌رفته، انگیزه‌ها به‌سرعت رشد می‌یابد.طبق تجربیات شما، آیا این خیلی سریع رخ می‌دهد؟ در شرایطی که مدیر خط (Line Manager) می‌ترسد که تیم نتواند تصمیمات را به‌درستی و به‌صورت مؤثر بگیرد.این وابسته به ۳ عامل است. اول اینکه، آنها از کجا شروع می‌کنند. اگر قواعد مدیریت خط خیلی سفتی داشته باشند، قطعاً زمان بیشتری می‌برد زیرا همه مدیران و تیم‌ها، روش دیگری داشته‌اند. مورد دوم، زمینه کاری است. در پروژه‌های کوچکی که از همدیگر مستقل هستند در مقایسه با پروژه‌ای که دویست نفر بر روی یک هدف مشترک کار می‌کنند (مثلاً در صنعت اتومبیل یا پزشکی یا پروژه‌های IT بزرگ)، مسئولیت دادن به تیم خیلی ساده‌تر است. مورد سوم، و آخر این است که افراد تا چه حد برای این کار آماده‌اند. ممکن است تیم به این دلیل که مسئولیت‌هایش افزایش می‌یابد برای این کار مردد باشد. شما با چنین چیزهایی برخورد می‌کنید زیرا قدرت بخشیدن چیزی نیست که تنها به‌عنوان هدیه دریافت کنید. در عین حال باید بر روی تحویل دادن تمرکز داشته باشید. اگر تیم یا گروهی از افراد واقعاً علاقه‌ای به پذیرفتن چنین مسئولیتی، نداشته باشند، این کار هیچ‌گاه موفق نمی‌شود. من چنین موقعیت‌هایی را دیده‌ام که با وجود اینکه پروژه مجزا و مستقل بوده، تیم به این تفکر گرایش داشته‌اند که ما به‌عنوان مهندس استخدام شده‌ایم بنابراین نباید تصمیمات مربوط به کسب ‌و کار را بگیریم. این می‌تواند یک عامل بازدارنده باشد.فکر می‌کنم باید این از طرف مدیریت ارشد روشن باشد که آنها واقعاً می‌خواهند این ریسک را بکنند و چنین کاری را تشویق کنند و روشن کنند که این یک تغییر در فرهنگ است.دستورالعمل موفقیت در این کار این است که با تغییرات کوچک و تدریجی در مسئولیت‌ها، بگذاریم به تدریج، مسئولیت‌ها رشد یابند. این روش که با درنظر گرفتن ۳ عاملی که پیش از این اشاره کردم به تدریج رشد یابید، عموماً جواب می‌دهد.یکی از موضوعاتی که خیلی با موضوع توسعه ترکه‌ای مرتبط است، هدررفت (Waste) است. مورد سوم از اصول ترکه‌ای که شما معرفی کردید، حذف هدررفت‌ها بود. می‌توانید در مورد سطوح مختلف آن صحبت کنید؟ مثلاً اینکه می‌تواند در یک پروژه مجزا باشد یا در کل سازمان باشد. فکر می‌کنم می‌توان این‌طور گفت که چیزی که از نظر فردی هدررفت است ممکن است از نظر دیگری ارزشمند باشد. آیا واقعاً افراد برداشت مشابهی از هدررفت دارند؟فکر می‌کنم برای اینکه بتوانیم هدررفت را بفهمیم لازم است ابتدا به فعالیت‌ها و در نهایت محصولمان، نگاه کنیم. به همین علت است که من فهرست خودم را با «ارزش‌آفرینی» آغاز کردم. هنگامی که شما متوجه شوید که «ارزش» چیست، آنگاه آسان‌تر خواهد بود که به جنبه منفی آن فکر کنید که «هدررفت» چیست. شما پیش از این عنوان کردید که این یک دیدگاه تنگ‌نظرانه‌ای است که بخواهیم هرچیزی را که مستقیماً تولیدکننده یک ویژگی نباشد که بتوانید فردا آن را بفروشید را هدررفت در نظر بگیریم. همان‌طور که قبلاً توضیح دادیم، یادگیری می‌تواند خیلی مفید باشد.حذف هدررفت‌ها هم، همان‌طور که در مورد قدرت بخشیدن به تیم گفتیم چیزی است که به‌تدریج فرا می‌گیرید. بعضی از انواع هدررفت که من پیش از این عنوان کردم، به‌سادگی قابل تشخیص است. مثلاً خطایی که خیلی دیر تشخیص داده می‌شود به‌وضوح هدررفت است یا مثلاً نیازمندی که بعداً هیچ کس آن را نمی‌خواهد، به‌وضوح هدررفت است.اما چه کسی می‌تواند یک معیار و روش ارزیابی به شما بدهد که بتوانید همه خطاها را بیابید؟ اگر این‌قدر ساده بود، احتمالاً این تعداد متدولوژی نداشتیم. یافتن معنای هدررفت (برطبق محصول و شناختی که از کسب‌وکار دارید) در کاری که هم‌اکنون انجام می‌دهید، یک کار چالشی است. شاید چیزی باشد که برای نسخه جاری، هدر دادن زمان باشد اما برای نسخه‌های بعدی، ارزش داشته باشد. در این مورد، یک مثال کلیدی که ما اغلب در صنعت استفاده می‌کنیم این است که: «کاری که می‌کنم را تا چه مقداری باید مستند کنم؟» در تکنیک‌های توسعه چابک تأکید می‌شود که کد همان مستند است. این ممکن است صحیح باشد اما نرم‌افزارهای صنعتی حرفه‌ای شاید استانداردهایی را پیروی کنند که الزام کند محصول به‌خوبی مستند شود. در این صورت به چه شکل باید کد یا معماری یا استراتژی تست، مستند شود؟ این چیزی نیست که در دانشگاه تدریس شود. منظورم این است که این مهارت‌ها به صورت گام به گام، ساخته می‌شود تا به شناخت درستی از آن برسید. خیلی افراد هستند که کار نگهداری و توسعه جدید می‌کنند و می‌دانند که چه مقدار از مستندات اضافه‌کاری است و چه مقدارش برای اصلاح خطاهای نسخه‌های قبلی مفید است و چه مقدارش، در مرزها قرار می‌گیرد و بیشتر باعث سربار در محصول جاری‌تان می‌شود. این همان چیزی است که به آن قاعده‌ به مقدار کافی خوب (Good Enough Principle) می‌گوییم. باید خیلی مراقب باشید که در صنایع حساس مثلاً پزشکی یا اتومبیل، کارهایی نکنید که بعداً مشخص شود که برای رسیدن به سطوح امنیت و اطمینان موردنظر کافی نبوده است اما در عین‌ حال روشن است که باید در درک این مطالب که چه مقدار لازمست و چه مقدار کافیست نیز تجربه کسب کنیم. این چیزی است که از ما به‌عنوان یک مهندس حرفه‌ای انتظار می‌رود. این امر به صنعت وابسته است، به انتظارات کاربران وابسته است و برای آن نیاز به درک کسب و کار و همچنین درک عمیق مهندسی هست. این چیزی است که تیم طی زمان، وقتی به سمت توسعه به روش ترکه‌ای می‌رود آن را فراخواهد گرفت.ما در مورد هدررفت در مورد مهندسی نیازمندی‌ها صحبت کردیم. مسائلی از قبیل تولید بیش از حد، توسعه محصول غلط، داشتن ویژگی‌هایی که مشتریان آنها را واقعاً نمی‌خواهند، اینها می‌توانند نمونه‌های روشنی از هدررفت باشند. اما فکر می‌کنم اگر در حیطه مهندسی، این عنوان (هدررفت) را برای خیلی چیزهای دیگر هم بکار ببریم معنی می‌دهد. بعنوان مثال اگر به روش ترکه‌ای در تولید کارخانه‌ای نگاه بیاندازید، برخی دستگاه‌ها و ابزارها هستند که تعویض بین آنها، هزینه دارد. فکر می‌کنم به این نوع هزینه‌های مرتبط با ابزارهای سخت‌افزاری، هدررفت از نوع حرکتی (Motion) گفته می‌شود. در نرم‌افزار هم نوع مشابهی از هدررفت داریم یعنی هدررفت مرتبط با تعویض محتوا (Context Switch). مثلاً یک فرد خبره در ۵ پروژه متفاوت درگیر می‌شود و مدیر اغلب، تعویض محتوایی که در ذهن این فرد رخ می‌دهد را نادیده می‌گیرد. اینکار می‌تواند هزینه معادل ۲۰٪ زمان فرد یا چیزی شبیه به این را داشته باشد. این مفید است که توجه مدیران را به این شرایط ناخوش جلب کنیم.بله، کاملاً درست است که گاهی مواقع به سمت چنین شرایطی حرکت می‌کنیم. باید مراقب فعالیت‌های توسعه‌ای که انجام می‌دهیم باشیم یعنی در ارتباط با فعالیت‌های برای فهمیدن ویژگی‌ها، فهمیدن هدررفت‌ها یا برای اینکه چه چیزی از لحاظ نیازمندی لازم است یا لازم نیست.از لحاظ تاریخی مثال‌های فراوانی وجود دارد. بعنوان مثال اگر Netscape را درنظر بگیرید، در ابتدا سهم بزرگی از بازار در حد ۹۰٪ را داشت. اما در عرض چند سال نسبت به Microsoft Explorer اُفت کرد. این چیزی بود که یقیناً کسی انتظارش را نداشت. اما ناکارآمدی اصلی در محصول Netscape، رشد غیرقابل کنترل پیچیدگی (بدون اینکه هیچ‌گونه معماری یا مستندات محصول یا حتی مدیریت پروژه وجود داشته باشد) بود. و این فاکتورها با هم، می‌توانند هر محصولی را (حتی اگر سهم ۹۰٪ از بازار را داشته باشد) با سرعت خیلی زیادی نابود کنند. این‌ها داستان‌هایی است که باید همواره به خاطر داشته باشیم. برای اینکه تاریخ تکرار نشود باید از آن درس بگیریم.و اما در مورد تعویض محتوا (Context Switch) که شما گفتید، ما از پیش‌زمینه‌ای که از علم سیستم‌عامل داریم می‌دانیم که برای هر تعویض محتوا مجبوریم چیزهایی را ذخیره کنیم و متغیرهای جدیدی بگیریم که واضح است که زمان می‌برد. ما چندین مطالعه انجام داده‌ایم، همچنین مطالعاتی خصوصاً در زمینه روانشناسی وجود دارد که نشان می‌دهد که تعویض محتوای خیلی زیاد و وجود فعالیت‌های شبه‌موازی خیلی زیاد، کارایی فرد و تیم را به‌شدت کاهش می‌دهد.برای اینکه بتوانید دوره انتظار که ناشی از یک فعالیت است را کاهش دهید، باید دو یا سه کار را به صورت موازی انجام دهید. از طرف دیگر اگر بصورت موازی ۵ یا ۶ پروژه کدنویسی داشته باشید و دائماً فردی از طرف پروژه‌های دیگر شما را برای دادن اطلاعات در مورد واسط‌ها (Interface) یا ارائه توضیحات فرابخواند، در این صورت این تعویض محتوایی که خواهید داشت نه تنها کارایی شما را از بین می‌برد بلکه باعث ایجاد تعداد زیادی خطا می‌شود. ما پروژه‌های نزدیک به تحویلی دیده‌ایم که وقتی در شرایط فشار زمانی، این فعالیت‌های موازی در جریان بود، نرخ خطا سه برابر یا خیلی بیشتر از نرخ خطای اولیه می‌شد. بر این شرایط استرس بالا تقریباً هیچ بشری نمی‌تواند فائق آید.باید اینجا روشن کنم، وقتی من از فعالیت‌های موازی صحبت می‌کنم منظورم فعالیت‌های مهندسی است. اگر شما فرد خبره‌ای دارید که فعالیت‌های مربوط به مهندسی معماری‌تان را انجام می‌دهد ممکن است چنین فرد ارشدی، بتواند همزمان از پس ۴ یا ۵ محصول برآید ولی از دیدگاه فردی، تجربه‌های گسترده نشان می‌دهد که باید کارها را به ۲ یا ۳ عدد محدود کنیم و نباید کارهای زیادی را بصورت موازی انجام دهیم. این آموخته‌هایی است که من در صنعت با آن روبرو می‌شوم. آنها می‌گویند: «من به آن متخصص در ۵ پروژه مختلف نیاز دارم. چه کار باید بکنم؟ من نمی‌توانم از این مهارت یکی دیگر بسازم!» من به آنها می‌گویم: «یکی دیگر بسازید!» این را فقط از دیدگاه فردی به این خاطر که مهندس‌ها حس خوبی پیدا می‌کنند، نمی‌گویم. آنها (مهندسان) به من می‌گویند اگر بتوانند در زمینه کاری‌شان یادگیری بیشتری داشته باشند، تقویت می‌شوند. اما مدیریت فکر می‌کند که من این متخصص را دارم. چرا باید هزینه دو یا سه تای دیگر را بپردازم؟ یک رویه خوب چابک در اینجا این است که بصورت جفت (Pair) کار کنیم. اگر یکی مریض باشد یا نباشد، دیگری دانشش را دارد که همتایش چه کار می‌کرده است. این کاملاً منطقی است که دانش‌مان را به اشتراک بگذاریم و تنها آن یک متخصص را نداشته باشیم که نتوانیم واقعاً جایگزینش کنیم. وقتی این درک شود، پیشرفت در جهت بهبود آسان‌تر می‌شود.به سراغ چهارمین موضوعی که در ابتدا عنوان کردید، برویم: «بهینه‌سازی زنجیره ارزش یا بهینه‌سازی جریان». این موضوعی است که فکر می‌کنم خیلی مهم است. دونالد رینسترن که در زمینه موضوع جریان (Flow) و مدیریت محصول به روش ترکه‌ای متخصص است، حدود یک سال پیش، برای تعدادی از همکاران‌مان در حوزه ترکه‌ای و مدیریت محصول یک سخنرانی در زیمنس داشت. او تمرکز خیلی زیادی بر روی تئوری صف (Queuing Theory) دارد. اینکه در یک فرآیند، در عوض استفاده از ظرفیت منابع افراد، بر روی جریان کار و بر روی توان عملیاتی (Throughput) کل سیستم تمرکز کنیم. این موضوع به نوعی، با مبحث مدیریت ترافیک مرتبط است. مثلاً در اتوبان‌های آلمان، اگر بخواهیم ظرفیت تک‌تک تعداد زیادی افراد را بالا ببریم، با یک ترافیک عظیم روبرو می‌شویم و کسی نمی‌تواند جایی برود. فکر می‌کنم بهینه‌سازی جریان، حتی نسبت به بودجه و زمانبندی، ساده‌تر قابل کنترل باشد. احتمالاً منطقی است که دانش بیشتری در این موضوع تئوری صف داشته باشیم. فکر می‌کنم این موضوع در حوزه تولید ترکه‌ای کارخانه‌ای کاملاً شناخته‌شده باشد اما به نظر می‌رسد نرم‌افزاری‌ها خیلی آن را نشناسند.به اختصار، ما تکه‌کارهایی داریم. فردی کاری می‌کند و آن را جلو می‌فرستد. در این جریان، به‌غیر از موضوع تعویض محتوا که شما پیش از این اشاره کردید، مقدار زیادی، منتظر شدن رخ می‌دهد. مقدار زیادی فعالیت‌ها هستند که جایی انباشته می‌شوند. یعنی موقعیت‌های گلوگاهی (Bottleneck) مانند نیاز به آن متخصص‌ها که قبلاً اشاره کردیم را داریم. یا گلوگاه‌هایی به‌علت آماده نبودن زیرساخت‌ها یا محیط تست، خواهیم داشت. من اخیراً برای یک مشتری کار می‌کردم که به زیرساخت‌ها و محیط تست زیادی نیاز داشت و یکی از گلوگاه‌های اصلی‌شان، در اختیار گرفتن محیط تست و تست کردن بود. اگر می‌خواستند تعداد Build ها و نسخه‌های خیلی زیادی داشته باشند جواب نمی‌داد زیرا هزینه تستش خیلی زیاد می‌شد. آنها تلاش کردند که برای استفاده بهینه از زیرساخت‌های تست از صف‌ (Queuing) استفاده کنند. بنابراین در این شرایط، استفاده از صف (Queuing) و تحلیل ارزش (Value Analysis) خیلی اهمیت می‌یابد. از لحاظ تاریخی، در تحلیل ترافیک و در زمینه مخابرات، این‌ها را داشته‌ایم.یک تمرین خوب این است که همه با عملکردهای مختلفی که در پروژه یا توسعه محصول دارند بنشینند و ببینند که تعاملاتشان چگونه است و هر از چندوقت کارها برگشت داده می‌شوند؟ تصویر اولیه خیلی شلوغ خواهد بود و شامل فعالیت‌های کوچک خیلی زیادی خواهد بود. بنابراین باید بیاموزید که: «چگونه فعالیت‌ها را در دسته‌هایی خوشه‌بندی کنید؟ چگونه می‌توانید واسطه‌ها را کاهش دهید؟ چگونه می‌توان گلوگاه‌ها را با مکانیزم‌هایی از قبیل اضافه کردن زیرساخت‌ها یا برون‌سپاری برخی فعالیت‌ها یا هر راه دیگری، کم کرد؟»یک مورد درباره تحلیل زنجیره ارزش (Value Stream Analysis) این است که اولین بار که این تصویر را آماده می‌کنیم، (اغلب با قرار دادن یادداشت‌هایی بر روی تخته وایت‌برد این کار را می‌کنیم)، وقتی که تیم این کار را به پایان رساند (زیرا آنها کسانی هستند که محیط را می‌شناسند) آنها خواهند گفت با اینکه همیشه با آن مواجه بوده‌ایم اما واقعاً هیچ‌گاه این‌طوری آن را ندیده بودیم. در این حال، با حذف برخی واسطه‌ها و با نگاه کردن به کارهایی که در پروژه اخیر انجام داده‌ایم و نگاه به مقدار زیادی از فعالیت‌ها که برگشت خورده‌اند (به‌عنوان مثال نیازمندی‌های ناکافی که موجب ۵ یا ۱۰ بار دوباره‌کاری شده است) حتی با عمیق‌تر شدن و تمرکز روی این موضوع که چه محصولی را ارائه می‌کنیم، بحث‌های خیلی مفیدی داخل تیم شکل می‌گیرد. مثلاً اینکه چطور می‌توان این زنجیره فعالیت‌ها را ساده کرد؟ و این تمرین خیلی سودمندی است.آیا فکر می‌کنید که این یکی از منافع این رهیافت است؟ اینکه افراد را دورهم در یک اتاق روبروی یک تخته بزرگ که مقدار زیادی یادداشت بر روی آن زده شده است، جمع کنیم و آنها را برایشان توضیح دهیم. فقط از این لحاظ که همدیگر را ملاقات کنند و همدیگر را بشناسند. مثلاً ممکن است قبل از آن مهندسان نیازسنجی، تست‌کننده‌ها را تا به حال ملاقات نکرده باشند.درست است. این کمک می‌کند که شما به تصویر درست برسید. چیزی که قطعاً معنی نمی‌دهد این است که یک تیم بزرگ داشته باشید و بخواهید که خودشان تصویر (Value Stream) را بکشند زیرا اولاً معمولاً تکنولوژی اینکار را ندارند و دوماً آنها فقط بر روی چیزی که می‌دانند تمرکز می‌کنند و بقیه چیزها را حدس می‌زنند. آنچه ما اغلب انجام می‌دهیم این است که در کنار تیم‌های کوچک‌تر یا برخی مواقع با تک‌تک‌ افراد، می‌نشینیم و گام به گام آن تصویر را می‌سازیم. بعد تیم‌ها را جمع می‌کنیم و از آن‌ها می‌خواهیم که به تصویر تولید شده نگاه کنند و در مورد آن بحث کنند و تجربیات خود را به اشتراک بگذارند و بعد اگر بخواهید می‌توانید دور برخی نقاط مشکل‌زا را با قرمز خط بکشید. و بعد مثلاً به تیم‌های مهندسی نیازمندی‌ و تیم تست، آن را نشان دهید و بگویید که: «در اینجا ما، مقدار دوره‌های طولانی داریم که پرهزینه است زیرا در زمان تست متوجه می‌شویم که بیان مشخصات (Specification) اشتباه بوده است و برخی چیزها فراموش شده است. چرا نیازمندی‌ها را از لحاظ تست‌پذیری، بازبینی نمی‌کنید؟» این یکی از تکنیک‌های خاص و بازبینی بسیار مؤثر است که من در کل چرخه تولید نرم‌افزار می‌شناسم. با این کار، بهتر فرا گرفته می‌شود که چطور باید بیان مشخصات نیازمندی‌ها را مستند کرد در عین حال تست‌کننده‌ها هم زودتر متوجه هدف واقعی سیستم می‌شوند. مطمئناً با بهبود دادن این نقاط مشکل‌زا، پیشرفت خواهید کرد.آیا مثال‌هایی می‌شناسید که توانسته باشند این رویه‌ای که در موردش صحبت می‌کنیم را به‌سادگی پشت سر گذاشته باشند؟ آیا برای افراد علاقه‌مند، در مورد اولین گام‌هایی که باید داشته باشند، توصیه‌هایی دارید؟در مورد همه این ۵ قاعده صحبت می‌کنید یا فقط در مورد زنجیره ارزش صحبت می‌کنید؟در مورد همه‌اش.مثال‌های مختلفی داریم. باید هوشیار باشیم که ترکه‌ای یک چیزی نیست که مثلاً ۱۰ قاعده داشته باشد و یک تکنیکی باشد که کاملاً واضح، تعریف شده باشد. مثلاً ممکن است یک شرکت وقتی بر روی آن کار می‌کند بیشتر بر روی صف‌ها متمرکز شود و این کار را تا سطح خیلی تئوری یعنی معادلات تئوری صف، انجام دهد. البته این کار بی‌فایده است زیرا نمی‌تواند مشخص سازد که چه کاری باید به روش متفاوتی انجام شود. به‌همین خاطر است که من گفتم آسانتر است که تصویر را بکشید و دور نقاط مشکل‌زا خط بکشید و آنها را بهبود دهید.مثال‌هایی وجود دارد که شرکت‌هایی که کمبود زمان داشتند، روش ترکه‌ای را به خدمت گرفتند. همان‌طور که پیش از این اشاره کردم مواردی از این دست در مجله IEEE منتشر شده است. خوب است که به نسخه مربوط به ۱۰ اکتبر سال ۲۰۱۲ نگاهی بیاندازید. در آن، تعدادی از این مطالعات موردی ارائه شده است. یکی از آن مواردی که من در آنجا خوشم آمد، یک موردی بود که مربوط به توسعه ابزارهای پزشکی در شرکت زیمنس بود. در آنجا گروهی به تعدادی از قواعد ترکه‌ای و چابک مانند اولویت‌بندی ویژگی‌ها و توسعه افزایشی (Incremental Development) توجه کرده بودند و نشان داده بودند که فقط از دیدگاه مهندسی نیازمندی‌ها، انتخاب هوشمندانه مجموعه‌ای از این قواعد که با آموزش و مهارت‌آموزی صحیح همراه باشد، منجر به بهبود ۳۰٪ در کارایی (در حوزه و محیط خاص خودشان) می‌شود.مورد دیگر، یک مطالعه تجربی درباره بکارگیری کانبن و اسکرام در شرکت‌های با ابعاد کوچک و متوسط بود. در آنجا نیز نشان داده شده بود که مستقل از حوزه صنعتی شرکت‌ها، به‌طور خاص قواعد حذف هدررفت‌ها و زنجیره ارزش (که ما در اینجا در مورد آنها توضیح دادیم)، سودمندی بسیار زیادی در شرکتی که آن را به خدمت گرفته است داشته است. به‌عبارت دیگر، هر روزه نمونه‌های خوبی ارائه می‌شود که می‌توانیم از آنها یاد بگیریم. به خاطر دارم که برای آن نسخه خاص IEEE Software ما ۲۳ مقاله دریافت کردیم. بنابراین می‌بینید که دانش زیادی دراین‌باره وجود دارد. اما من از پیش‌زمینه تجربیات خودم می‌دانم که به همین تعداد شرکت هم بوده‌اند که تلاش کرده‌اند اما شکست خورده‌اند. آنها میزان تأکیدی که باید بر روی مدیریت تغییرات وجود داشته باشد را دست‌کم گرفته‌اند. ما در مورد تغییراتی که در این چرخه‌های بکارگیری دارید، خیلی صحبت کردیم. اگر تغییرات بیش از اندازه بدهید، شکست خواهید خورد. مثلاً اگر به تیم بگویید که: «از همین فردا شما قدرت داده می‌شوید.» به همین علت است که مدیریت تغییرات، یکی از فاکتورهای اصلی موفقیت است.یکی از مزایای روش ترکه‌ای احتمالاً این است که این چرخه‌ها را خیلی کوتاه می‌کند. این شانس را دارید که چرخه بازخورد کوتاهی داشته باشید و خیلی خیلی سریع یاد بگیرید. قبلاً این روش آبشاری توسعه را داشتیم که برای دو سال کار می‌کردید و وقتی می‌خواستید از آن درس بگیرید، شرایط کسب و کار به‌کلی عوض شده بود. بعد از آن چابک را داریم که توسعه به روش تکراری انجام می‌شود و چرخه‌های بازخورد کوچک‌تر است. فکر می‌کنم یکی از دلایل محبوبیت ترکه‌ای، این امکان بیشتر برای یادگیری سریع و تطابق برای بقاء (همانطور که در تئوری داروین داریم :-))، است. هم از موفقیت و هم از شکست، قابلیت یادگیری دارید.درست است. اصل اساسی در بهبود مستمر این است که آن را واقعاً به‌صورت مستمر بکار ببرید. اگر به اسکرام نگاه کنید، اگر آنجا این جلسات سرپایی روزانه (Daily Standup Meeting)، را دارید، یکی از دلایل اصلی‌اش این است که بتوانید تجربیات را به اشتراک بگذارید. این کار را می‌توانید در زمینه‌های کوچک‌تر یا بزرگ‌تر هم انجام دهید. فکر می‌کنم خوب است که هر روز عصر، یا مثلاً هرجمعه، جمع شویم و بگوییم: «چه می‌توانیم بیاموزیم؟ ما به‌عنوان یک تیم، از ماحصل کار که ممکن است به‌خوبیِ مورد انتظار نباشد، چه می‌توانیم بیاموزیم؟»بسیار خوب. گفتگوی خیلی جذابی بود. من دیدگاه‌های شما نسبت به این موضوع را تقدیر می‌کنم. امیدوارم شنوندگان نیز چیزهایی یافته باشند که بتوانند درکارهای عملی خود بکار ببرند.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Sat, 01 Jan 2022 22:18:25 +0330</pubDate>
            </item>
                    <item>
                <title>کانبَن</title>
                <link>https://virgool.io/se-radio/%DA%A9%D8%A7%D9%86%D8%A8%D9%8E%D9%86-kf22pu2fiiq0</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۱۵۶ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ یکی از موضوعات حوزه‌ مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت با دیوید اندرسون، فردی که کانبن را فراتر از تویوتا و به دنیای نرم‌افزار آورد، صحبت می‌کنیم. کانبن یک متد چابک است که با اغلب دیگر متدهای چابک موجود متفاوت است. ما در مورد ایده‌های پشت کانبن، تفاوت کانبن با اسکرام و این که چه زمان و چرا پروژه‌ها از بکارگیری کانبن سود خواهند برد، صحبت می‌کنیم. این قسمت با همکاری مجله آلمانی ObjektSpektrum فراهم شده است که مصاحبه را با ما به اشتراک گذاشت. سلام دیوید. خوشحالم که شما را اینجا در آلمان دارم. لطفاً خودتان را معرفی کنید و به ما بگویید که چه طور شد که به سراغ کانبن آمدید و الان چگونه با آن مشغولید؟خیلی ممنون که من را دعوت کردید. خوشحالم که اینجا در فرانکفورت هستم. در واقع اولین بار است که به فرانکفورت می‌آیم البته خیلی به آلمان آمده‌ام.چطور شد که به سراغ کانبن رفتم؟ سئوال خیلی خوبی است. این روندی است که در مجموع، در طی حدود ۱۰ سال شکل گرفته است. ابتدا با توسعه مبتنی بر ویژگی‌ها (Feature Driven Development) که یک متد چابک است کار می‌کردم حتی قبل از آنکه بدانم متدهای چابک چه هستند. و با زمینه آن تجربه، و با خدمت گرفتن برخی ایده‌های Lean و برخی ایده‌های مربوط به تئوری قیود (Theory of Constraints)، آن متد را تکامل دادم و کتاب مدیریت چابک برای مهندسی نرم‌افزار را در سال ۲۰۰۳ منتشر کردم. نسبت به آن موقع، چیزهایی آموختم. توانستم که FDD را دوبار با موفقیت در پروژه‌هایی بکار بگیرم. در تیم‌هایی که مستقیماً به من گزارش می‌دادند. پس از آن موفقیت، از من خواسته شد که استفاده از FDD را در تمام بخش‌های واحد تجاری، گسترش دهم. یکبار با Sprint PCS که یک اپراتور تلفن همراه در آمریکاست و یکبار با Motorola که یک تولید کننده تلفن همراه در آنجاست. در هر دو مورد وقتی سعی می‌کردم که متد را برای چندین تیم گسترش دهم، مقاومت زیادی ایجاد می‌شد و کار، سازمانی نشد. در این موقع به این فکر افتادم که چرا افراد مزایای روشن انجام دادن کار صحیح را نمی‌بینند؟ چرا مقاومت می‌کنند؟ چرا کشمکش داریم؟به این نتیجه رسیدم که وقتی یک تعریف در مورد یک پروسس جدید تجویر می‌کنید به و به افراد می‌گویید که باید با آن مطابقت یابند و احتمالاً باید تعریف شغلی و تکنیک‌هایی که استفاده می‌کرده‌اند، را عوض کنند، مقاومت می‌کنند. بنابراین شاید بهتر باشد که تکنیکی را بیازماییم که در عوض «انقلاب»، اجازه می‌دهد تا «تکامل» یابید. براساس یکسری مشاهدات، متوجه شدم که به جای یک متد تجویزشده، با پیاده‌سازی یک سیستم کانبن می‌توان آن تغییرات تکاملی را ایجاد کرد. طی سال‌های ۲۰۰۴ تا ۲۰۰۷ با چندین تیم در مکان‌های مختلف این را آزمودم تا اینکه اعتماد پیدا کردم که درست کار می‌کند. و شروع کردم به اینکه آموخته‌‌هایم را به معرض عموم بگذارم تا آنها نیز آن را بیازمایند. الان دو سال دیگر گذشته است و واقعاً تیم‌های زیادی درجاهای مختلف دنیا دارند آن را امتحان می‌کنند. یعنی این که از کانبن استفاده می‌کنند و بجای یک انقلاب چابک، تغییرات تکاملی را امتحان می‌کنند.آیا ممکن است کانبن را در ۲ جمله توضیح دهید.در مورد ۲ جمله مطمئن نیستم اما خیلی خلاصه این که کانبن، یک ایده خیلی ساده است. این که تصمیم بگیرید که حجم کارهای در حال انجام خود را محدود کنید. و این  که کارهای در حال انجام خود را با استفاده از مکانیزم‌هایی از قبیل یادداشت‌های چسبانده شده بر روی وایت‌برد، تصویرسازی کنید. و این که تنها زمانی کار جدیدی را آغاز می‌کنید که یک کار جاری را تمام کرده باشید. بنابراین یک مکانیزم آگاه‌سازی وجود دارد که نشان می‌دهد که ما چیزی را تمام کرده‌ایم و می‌توانیم آیتم جدیدی را شروع کنیم. همین است: مکانیزم تصویرسازی، محدودیت کارهای درحال انجام و مکانیزم آگاه‌سازی برای برداشتن کار جدید وقتی کاری تمام شده است.الان، همه در مورد اسکرام صحبت می‌کنند. بیش از ۶۱۰۰۰،  استاد اسکرام (Scrum Master) در جهان وجود دارد. همه شرکت‌ها یا همین حالا، از اسکرام استفاده می‌کنند یا مشتاقند که آن را به خدمت بگیرند. بنابراین چرا همچنان به کانبن نیازمندیم؟فکر می‌کنم این خوب است که می‌بینیم اسکرام به صورت چشمگیری موفق بوده است. شما نمی‌توانید این را نادیده بگیرید. اگر ۳۰۰ یا ۴۰۰ هزار نفر در جهان هستند که مدرک حرفه‌‌ای مدیریت پروژه دارند، برای اسکرام رسیدن به رقم ۶۱۰۰۰ استاد اسکرام، تنها در عرض چند سال، یک موفقیت بسیار بزرگ است. فقط من نیستم که فکر می‌کنم که اسکرام نسخه‌ای است که در شرایط خاصی کار می‌کند. در واقع، مربوط به هسته فلسفه اسکرام است که: اسکرام نسخه‌ای است که کار می‌کند اما آنچه باید انجام دهید این است که شرایطتان را تغییر دهید تا با آن مطابقت یابد.اسکرام قواعد خوبی دارد که واقعاً کمک می‌کند که موفق باشد. ما اسپرینت‌های با طول ثابت را داریم. در روزهای اولیه  یعنی ۱۰ سال پیش، ۴ هفته، متداول بود. در ابتدای این ۴ هفته در مورد حوزه کارمان، یعنی صورت کار اسپرینت (Sprint Backlog) توافق می‌کنیم و بعد ۴ هفته کار می‌‌کنیم و اجازه دخالت مشتریان در آن کارها داده نمی‌شود که روش جالبی برای حذف کردن امورتصادفی و تغییرپذیری‌‌ها است. مشتری برای ۴ هفته اجازه تغییر چیزی را ندارد که چیز واقعاً خوبی است. و مکانیزم‌هایی مانند جلسات سرپایی روزانه (Daily Stand-up Meeting)  را داریم و در مورد کار صحبت می‌کنیم که باعث انتشار خوب کار در تیم می‌شود و فشارهایی از جانب همتایان برای پذیرش مسئولیت توسط همه افراد را داریم. همه تیم، تعهد اسپرینت، یعنی صورت کارها (Backlog) را در ابتدای کار می‌پذیرند و همه کار را با همدیگر انجام می‌دهند تا در پایان، تمام شود و بعد یک چیزی که کار می‌کند را برای مشتری دمو می‌کنند. و جلسات گذشته‌کاوی (Retrospective) را داریم. همگی اینها، چیزهای واقعاً خوبی هستند.مشکلی که وجود دارد این است که ۴ هفته خیلی خوب نیست. ممکن است ۲ هفته خوب باشد. من طرفدار این ایده نیستم که اسکرام برای همه شرایطی کار می‌کند. در واقع مطمئنم که امروز من و شما افرادی را ملاقات خواهیم کرد که به طور خاص به این علت به کلاس امروز می‌آیند که شرایطی دارند که اسکرام خیلی به کارشان نمی‌آید (دیوید به کارگاه آموزشی اشاره می‌کند که قرار بوده در همان روز مصاحبه برگزار شود - مترجم). مثلاً در شرایط مأموریت‌های IT و نگهداری سیستم‌ها، این مفهوم که چیزهای مربوط به کارهای ۲ یا ۴ هفته را در یک صورت کار گردآورند، کاملاً برایشان غریبه است.فکر می‌کنم کاملاً قابل درک است که چرا اسکرام چنین موفقیت چشمگیری را به دست آورده است. من طرفدار این ایده نیستم که همه جا کار می‌کند. فکر می‌کنم در شرایطی که بکار می‌آید، کاملاً موفق است زیرا قواعدش بادقت انتخاب شده است و در تجربیاتی که افراد در حین کار بدست می‌‌آورند مداخله نمی‌کند. به آنها اجازه می‌دهد که در حیطه محدوده اسپرینت و تیم، خودسازماندهی (Self Organization) داشته باشند. قواعد خیلی خوب انتخاب شده‌اند و برای موفقیت طراحی شده‌اند. و اگر یک روز و نیم یا دو روز آموزش داشته باشید، این قواعد کاملاً ساده هستند. بنابراین مایه شگفتی من نیست که به این شکل موفق بوده است. مطمئنم که پیشرفت بزرگی در مقایسه با برخی روش‌های دیگر مدیریت پروژه است ولی همچنان برایم روشن است که همه مشکلات را حل نمی‌کند. صرف اینکه افراد را بیشتر و بیشتر بترسانیم که کار را درست انجام نمی‌دهند، راه صحیح نیست. فکر می‌کنم که ارزشش را دارد که ذهن بازی داشته باشیم و به دیگر روش‌‌‌ها هم فکر کنیم.آیا اسکرام و کانبن، رقیب هم هستند یا اینکه مکمل هم هستند؟من آنها را رقیب هم نمی‌بینم زیرا کان‍بن یک متدولوژی توسعه یا یک متدولوژی مدیریت پروژه نیست. همچنان که اخیراً می‌بینیم که جامعه اسکرام در صدد تعریف کردن مجدد آن هستند، بازتعریف‌هایی از آن بوجود آمده است که رقیب هم هستند. اگر اولین کتاب‌ها را نگاه کنید، یک متدولوژی مدیریت پروژه بود و هیچ محتوای مهندسی در آن نبود. در واقع، خیلی از کسانی که اسکرام استفاده می‌کنند می‌گویند که در کنار اسکرام به XP نیاز دارید. به این ترتیب هم مهندسی و هم مدیریت پروژه خواهید داشت. کانبن هیچکدام این دو، نه متد مهندسی و نه متد مدیریت پروژه، نیست بلکه یک متد مدیریت تغییرات (Change Management) است.ما تغییرات را تحریک می‌کنیم و تحریک کردن تغییرات، منجر به یک سازمان Lean می‌شود که به شکل مستمر، فرهنگش را بهبود می‌دهد. روشی برای تحریک مستمر تغییرات تکاملی به جای انقلاب در نحوه کار کردن در یک سازمان است. شما کان‍بن را به تنهایی استفاده نمی‌کنید. مردم به سراغم می‌آیند یا از طریق اینترنت می‌پرسند که: ما یک تیم جدید داریم و هنوز یک متدولوژی انتخاب نکرده‌ایم. کان‍بن را استفاده کنیم یا اسکرام را؟ از نظر من، این یک سئوال صحیح به حساب نمی‌آید زیرا شما می‌بایست کان‍بن را بر روی چیز دیگری اجرا کنید. اولین تیمی که با آنها کان‍بن را اجرا کردیم، یک تیم PSP-TSP بود که در هند برای مایکروسافت کار می‌کردند و ما کان‍بن را بر روی PSP-TSP اضافه کردیم. ما PSP-TSP را تغییر ندادیم و توانستیم بهره‌وری تیم را حفظ کرده و زمان دوره‌ها را به ۹۰٪ کاهش دهیم. تیم دیگری که با آنها کان‍بن را اجرا کردیم یک تیم با متد از مدافتاده آبشاری بود. متدولوژی که از دهه ۱۹۷۰ می‌آید. از آن موقع، تیم‌های زیادی را دیده‌ایم که کان‍بن را در شرایط مختلفی به خدمت گرفته‌اند.تیم‌هایی هم بوده‌اند که کان‍بن را به اسکرام اضافه کرده‌اند. مشکل اینجاست که وقتی کان‍بن را به اسکرام اضافه می‌کنید، خیلی سریع، شروع می‌کنید که اسکرام را تغییر دهید. تیم شروع می‌کند به پرسیدن سئوالاتی از این قبیل که چرا ما دوره‌های ۲ هفته‌ای داریم. کان‍بن کمکشان می‌کند که پیوستگی برخی چیزها را از بین ببرند. مثلاً وابستگی بین ورودی (اولویت‌ها در برنامه‌ریزی) را از خروجی (مکانیزم نسخه جدید دادن). اما در اسکرام این ۳ مورد بهم‌ متصل و پیوسته هستند. یعنی اگر اسپرینت‌های دوهفته‌ای داشته باشید، هر دو هفته یک بار برنامه‌ریزی می‌کنید؛ طول دوره‌تان دو هفته است و هر دو هفته یک بار هم نسخه جدید بیرون می‌دهید. برای برخی سازمان‌ها، این، بهترین انتخاب نیست.اما اگر دیگر اسپرینت‌های با طول ثابت ۲ یا ۴ هفته‌ای نداشته باشید، آن دیگر اسکرام نخواهد بود. این یکی از چالش‌هاست زیرا جامعه اسکرام، این استاندارد را کنار نگذاشته‌اند. مثلاً، آزمون Nokia برای ارزیابی کیفیت اجرای اسکرام را داریم و می‌توان نتیجه گرفت که اگر نتوانید آزمون را قبول شوید، به نوعی، اسکرام ندارید.شما اسکرام را اجرا می‌کنید و آن شما را تشویق می‌کند که شروع به بهبود دادن بکنید و وقتی شروع به بهبود دادن می‌کنید، باید تغییر دهید. تیمی که اسکرام را به خوبی انجام می‌دهد بعد از یکسال، باید به روش منحصربفرد و متفاوت خودش کار کند که ممکن است لزوماً شبیه اسکرام نباشد! من می‌بینم که جامعه اسکرام این مشکل را دارند. برخی با من تماس می‌گیرند و می‌گویند: چطور می‌توانی بهبود مستمر داشته باشی در حالیکه باید بر طبق آزمون‌ها، ثابت کنی که داری اسکرام انجام می‌دهی؟ما تیم‌هایی دیده‌ایم که کانبن را بر روی اسکرام اجرا می‌کرده‌اند. در واقع، دوست من، کورِی لاداس، یک کتاب کامل با عنوان Scrumban درباره این موضوع نوشته است. این کتاب در این باره است که چطور می‌توان کانبن را بر روی اسکرام اجرا کرد و در این مورد صحبت می‌کند که چگونه تیم‌های اسکرام تکامل می‌یابند و در نهایت به چیزی تکامل می‌یابند که دیگر شبیه اسکرام نیست.آیا درست است که اسکرام بیشتر انسان‌محور است در حالیکه کانبن بیشتر در مورد منافع کسب و کار است؟فکر نمی‌کنم. بیایید در مورد منافع کسب‌ و کار بعداً صحبت کنیم. من این نقد که عموماً از طرف XP یا اسکرام‌کارها از جامعه چابک می‌آید را شنیده‌ام. افرادی که عموماً کانبن را امتحان نکرده‌اند و مواردی مانند این را می‌گویند که کانبن به افراد احترام نمی‌گذارد. در واقع فکر می‌کنم که قضیه کاملاً برعکس است. سیاستی که در پیاده‌سازی سیستم کانبن وجود دارد، احترام فوق‌العاده به افراد است. به طرز شگفت‌آوری، افراد را برای خودسازماندهی، قدرت می‌بخشد و مکانیزم این کار را کاملاً واضح می‌کند تا مدیران به خوبی بفمهند که خودسازماندهی چگونه کار می‌کند. و همین طور بفهمند که قواعد خودسازماندهی چطور با سیاست‌های مدیریت ریسک سازمان، هم‌راستا می‌شود. بنابراین مدیران، اعتماد بیشتری به تیم و خودسازماندهی پیدا می‌کنند. جامعه چابک از عنوان خودسازماندهی زیاد استفاده می‌کنند اما این امر، مدیران سازمان‌های بزرگ را تا حد مرگ می‌ترساند. من می‌بینم که برخی رهبران جامعه اسکرام می‌گویند که: مدیران، بی‌فایده هستند یا نیازی به آنها نیست؛ اگر یک تیم واقعاً خوبِ اسکرام داشته باشید، نیازی به مدیر ندارید.اگر شما مدیر باشید، اینها خیلی تهدیدکننده هستند. اینها باعث می‌شوند احساس ترس داشته باشید. اگر این اعتقاد که دیگر نیازی به شما نیست به شما گفته شود، چرا می‌بایست بکارگرفتن اسکرام را تشویق کنید؟ بنابراین فکر می‌کنم این پیغام خیلی بدی است که مدیران بد هستند یا مدیریت، غیرضروری است. آنچه باید بگوییم این است که: مدیریت بد وجود دارد اما مدیریت بد می‌تواند، خوب شود. و مدیران خوب، به افراد، قدرت می‌دهند. با سیاست‌هایی از قبیل اجازه خودسازماندهی و اینکه افراد خودشان انتخاب داشته باشند، می‌توان به افراد قدرت داد. کانبن در این زمینه خیلی خوب است.همچنین، محدود کردن کارهای در حال انجام در کانبن، تأثیر شگرفی در ممانعت از استفاده نابجا از تیم دارد. اگر بر روی کمیت کارهای در حال انجام، توافق داشته باشید و آن کمیت را به درستی اختیار کرده باشید، نباید کسی بیش از حد کار کند. اگر بر روی کمیت کارهای درحال انجام توافق داشته باشید، اصل دستیابی به مقدار قابل تحمل از کارها در بیانیه چابک، به راحتی حاصل می‌شود. برای من کانبن یک روش عالی و ساده و سرراست برای رسیدن به آن مقدار قابل تحمل و کمک به افراد تیم برای تعادل برقرار کردن بین کار و بقیه زندگی‌شان است. و چه احترامی بالاتر از این است که به افراد کمک کنیم که به چنین تعادلی برسند.همانند اسکرام، کانبن هم رویه‌های خاصی را برای توسعه بیان نمی‌کند. آیا رویه‌ای وجود دارد که ترجیح دهید داخل سیستم کانبن باشد؟فکر می‌کنم برخی رویه‌ها وجود دارند که برای موفقیت کانبن نیاز است. بطور خاص اگر کانبن را برای توسعه نرم‌افزار بکار برید، باید بتوانید نرم‌افزار را منتشر کنید. اگر یک برنامه اینترنتی یا یک سیستم IT داشته باشید، باید بتوانید آن را منتشر کنید. اگر مانند شرکت‌های بازی‌سازی، محصولاتی دارید که نیاز به تولید فیزیکی دارد، باید CD ها را تولید کنید و آن‌ها را تا قفسه مغازه‌ها، پخش کنید. اگر بخواهید این قابلیت انتشار را پشتیبانی کنید باید یک هسته مدیریت پیکربندی (Configuration Management) داشته باشید. لازم است بتوانید نیازمندی‌ها را شناسایی و دنبال کنید. لازم‌است که بر روی نسخه‌های نرم‌افزار، کنترل داشته باشید و بتوانید انشعاب‌ها (Branch) را مدیریت کنید. لازم است بتوانید انشعاب‌ها را به خوبی با هم ادغام (Merge) کنید. باید برای نسخه‌ها اسم بگذارید و اطمینان یابید که چیز درستی منتشر می‌شود و چیزهایی که هنوز تمام نشده‌اند تصادفی، منتشر نشوند. بنابراین مدیریت پیکربندی، قابلیت بنیادی برای قابل اجرا کردن کانبن است.لازم نیست خیلی پیچیده باشد. فکر می‌کنم اغلب تیم‌های چابک، اغلب تیم‌هایی که XP کار می‌کنند، این قابلیت را از پیش دارند. آنها می‌دانند که چطور داستان‌های کاربری (User Story)  را دنبال کنند. آنها می‌دانند که چطور نسخه‌ها را کنترل کنند. می‌دانند چطور انشعاب بگیرند و چطور یکپارچه‌سازی مستمر (Continuous Integration) داشته باشند. آنها می‌دانند چطور نسخه اجرایی نرم‌افزار را برای انتشار، آماده کنند. بنابراین با وجود این که این قابلیت، ضروری است، اما غیرمعمول نیست.من تیمی را داشته‌ام که واقعاً در اسکرام، بد بوده‌اند. متد را با کانبن جایگزین کردیم اما همچنان بد بودند. آنها به این علت بد بودند که نمی‌توانستند نسخه منتشر کنند. چرا نمی‌توانستند منتشر کنند؟ چون نمی‌توانستند نرم‌افزار را Build کنند. چرا نمی‌توانستند Build کنند؟ چون مدیریت پیکربندی خوبی نداشتند. بنابراین فکر می‌کنم این یک قابلیت بنیادی برای کار کردن کانبن است.در ارتباط با TDD چطور؟فکر می‌کنم اگر تمایل دارید، خیلی خوب است که آن را انجام دهید اما اگر آن را انجام ندهید، کانبن اهمیت نمی‌دهد. اگر تیمی TDD انجام ندهد و شما از راه برسید و بگویید که من از شما می‌خواهم TDD انجام دهید. آنها ممکن است بپرسند چرا؟ و شما مفصل برایشان بحث می‌کنید که چرا این ایده خوبی است. آنچه تلاش می‌کنید انجام دهید این است که افراد را با بحث‌های هیجانی، متقاعد کنید. اما آنچه کانبن تلاش می‌کند انجام دهد این است که اجازه دهد مشکلات، به تصویر درآیند. مثلاً اگر نرخ خطاهای کد، یک مشکل شده است یعنی اینکه کمیت چیزهایی که به اتمام می‌رسند را محدود کرده است، طول دوره را افزایش داده است و تاریخ تحویل را نامطمئن ساخته است؛ در چنین شرایطی، نیاز به بهبود کیفیت است. و وقتی تیم این موضوع تأثیر خطاها را می‌بیند، ممکن است تصمیم بگیرد که اولویت اول را به استفاده از تست‌های واحد (Unit) بدهد. اگر چیزهایی که به تست سیستمی می‌رسند، مردود شوند و برگردند، ممکن است بحثی دربگیرد که آیا بهتر نیست که تست را از پیش تعریف کنیم؟ به این شکل درباره مشکلات زودتر فکر کرده‌ایم و اگر کد طوری طراحی شده باشد، که تست را برآورده کند، از همان اول، آن را برآورده می‌کند و همه چیز بهتر جریان می‌یابد...بنابراین کانبن مشکلات را در معرض دید قرار می‌دهد و اجازه می‌دهد که تیم در مورد چگونگی برطرف کردن آنها بحث کنند. و اگر لازمه بهبود، به خدمت گرفتن TDD باشد، به این جمع‌بندی خواهند رسید. تیم مجبور به کاری نمی‌شود. خودشان مالک تغییرات هستند. اگر در عوض اینکه کسی آنها را مجبور کند، خودشان به این نتیجه برسند، سریعتر و بهتر آن را انجام خواهند داد.در کانبن چه مفهوم چابکی وجود دارد؟خصوصاً بخاطر دو بررسی موردی که در ابتدا منتشر شدند، همیشه این سؤال در مورد چابک بودن در کانبن مطرح بوده است، اولین مورد، بر اساس یک تیم PSP-TSP بود. بحث‌های زیادی در مورد PSP-TSP وجود دارد. بَری بوهم و ریچارد تِرنر یک کتاب با عنوان تعادل بین چابکی و انضباط نوشته‌اند. آنها، PSP-TSP را واقعاً به عنوان یک متد شناخته شده چابک، تعریف کرده‌اند. با این وجود مؤسسه مهندسی نرم‌افزار (SEI)، همچنان این را انکار می‌کند و می‌گوید که PSP یک متد چابک نیست. فکر می‌کنم، اعتقاد فراگیر این است که PSP، متد چابک نیست. دومین بررسی موردی که ما داشتیم در مورد یک تیم بود که کانبن را بر روی یک متد آبشاری (Waterfall) انجام می‌داد که آن هم به وضوح چابک نبود. بنابراین [سوال پیش می‌آید] وقتی که کانبن سیاست‌های سختی در مورد محدودیت کارهای در حال انجام و موارد این چنینی دارد چرا باید چابک باشد؟من سعی دارم به ایده‌های اصلی که در پس بیانیه چابک قرار دارد، نگاهی بیاندازم. چابک بر این پایه است که به جای اینکه به دنبال اطلاعات کامل بگردیم تا براساس آن مستندات حجیم و کامل را بسازیم و کلی تحلیل انجام دهیم، بدون این اطلاعات کامل، پیشرفت داشته باشیم. چابک می‌گوید: بگذارید کمی وقت برای فهم چیزها صرف کنیم و سریعتر کد زدن را آغاز کنیم و اگر، بعداً بیشتر آموختیم، بازسازی (Refactoring) می‌کنیم زیرا به این شکل ارزانتر است. چابک می پندارد که جلو رفتن بدون اطلاعات کامل، پی‌آمد اقتصادی بهتری دارد. و اگر به جای تلاش برای از ابتدا کامل بودن، بازسازی (Refactoring) داشته باشیم، هزینه و طول دوره کمتر خواهد بود. اگر به همین مفهوم در کانبن توجه کنید، تناقضی وجود ندارد. کانبن اجازه می‌دهد کارها را بدون اطلاعات کامل جلو ببرید. کانبن در این زمینه که باید اطلاعات کامل داشته باشید یا خیر، نظری ندارد. هر سیاستی که برای آغاز کردن فعالیت‌ها داشته باشید، قابل قبول است. اگر با داشتن ۸۰٪ از اطلاعات اجازه دارید از تحلیل به توسعه بروید، قابل قبول است.ایده دوم که در پس بیانیه چابک قرار دارد، فرهنگ اعتماد بالا در فضای کار است. این که به افراد قدرت داده شوند. به آنها اعتماد کنیم. احترام زیادی به آنها بگذاریم. کانبن واقعاً این چیزها را اجبار می‌کند. و آن را به عنوان یک مکانیزم و به عنوان یک کاتالیزور فرهنگ سازمانی Lean، قاعده‌مند می‌کند. کانبن الزام می‌کند که به صورت منظم نسخه منتشر کنید و این نسخه‌ها باید کیفیت بالایی داشته باشند و لازمه آن تعامل بین افراد تیم و تعامل بین همه افراد سازمان و بازاریاب‌ها است. به حجم زیادی از تعاملات، اعتماد می‌شود.محدود بودن کارهای در حال پیشرفت باعث می‌شود که وقتی کاری، متوقف می‌شود، کارها گیر کند. در این حالت افراد دیگر بیکار می‌شوند زیرا محدودیت کارها، جلوی آغاز کار جدید را می‌گیرد. این بیکاری باعث ایجاد رفتار ازدحامی (Swarming Behavior)، می‌شود. افراد با خود می‌گویند اگر الان نمی‌توانم کاری کنم، چطور می‌توانم کمک کنم که کارها راه بیافتد. هنری نیبرگ سوئدی یک داستان مصور جالب در مورد کانبن دارد. آنجا می‌بینید که چطور افراد حول مشکلی که پیش می آید ازدحام می‌کنند و با همدیگر تعامل می‌کنند. در واقع، کانبن، تعاملات را تشویق می‌کند و سطح اعتماد را در سازمان بالا می‌برد. شاید به نظر برسد این خودبه‌خود رخ داده است زیرا ذاتاً فکر می‌کنیم که فرهنگ اعتماد بالا، قواعد خیلی کمی دارد. اما این لزوماً درست نیست. قواعد زیادی وجود دارد که مرزها را تعریف می‌کند و در این مرزهاست که افراد خودسازماندهی دارند و به صورت مستمر روابط نزدیک پیدا می‌کنند و حول مشکلات، ازدحام پیدا می‌کنند و آنها را برطرف می‌کنند.سومین مفهوم موجود در بیانیه، این است که طول دوره واقعاً مهم است. محدودیت کارهای درحال انجام، به بهترین شکل، این امر را ارج می‌نهد. بازار در حال تغییر است. ما برداشتی از محصول، ویژگی‌ها و سرویس‌ها داریم اما این برداشت‌ها طول عمر دارند و در آینده، زمانی می‌رسد که دیگر ارزشی نخواهند داشت یا ارزش کمتری پیدا خواهند کرد. بنابراین اگر، برداشتی از یک ویژگی خیلی جالب در محصولمان داشته باشیم و ۶ ماه طول بکشد که آن را توسعه داده و به بازار برسانیم، اما ۳ ماه بعد، رقیبانمان آن ویژگی را ارائه کنند، در آن صورت ارزش کار به شدت کاهش می‌یابد. بنابراین باید هر چقدر که می‌توانید سریعتر ویژگی‌ها را پیاده‌سازی کرده و آنها را راهی بازار کنید تا سود را بیشینه کنید. بهترین روش ارج نهادن به نیازمندی‌ها، داستان‌های کاربری (User Story)، ویژگی‌ها یا هر چیز دیگری که اسمش را بگذارید این است که به جای این که آنها را به صورت سرمایه ببینید آنها را به عنوان بدهی‌های خود درنظر بگیرید و بگذارید خیلی سریع، جابجا شوند. اگر شما چیزی را به عنوان بدهی بدانید، باعث می‌شود تمایل داشته باشید که مقدار آن را کم نگه دارید. وقتی جامعه چابک این را فهمیدند، شروع به کوتاه کردن طول دوره‌ها کردند. ۴ هفته به خوبی ۲ هفته نیست و ۱ هفته بهتر از حتی ۲ هفته است. گروه‌های کوچک‌تر، طول دوره کوچک‌تر، کم نگه داشتن کارهای در حال انجام، درجهت این نوع نگاه بدهی است. کانبن با تنظیم کردن محدودیت کمیت کارها، شما را به این کار تشویق می‌کند. همچنین تشویقتان می‌کند که در طی زمان این کمیت را کوچکتر کنید و به طول دوره بعنوان یک مقیاس، توجه کنید.بنابراین فکر می‌کنم که کانبن همه ضوابط را برآورده می‌کند. اجازه می‌دهد که بدون اطلاعات کامل، جلو بروید. فرهنگ اعتماد بالا، را تشویق می‌کند و تشویق می‌کند که کارهای در حال انجام را کاهش دهید و آنها را به جای سرمایه، به عنوان بدهی ببینید. بنابراین کاملاً همخوان با ارزش‌های چابک است.شما قبلاً مشتاق FDD بودید. آیا کانبن رهیافتی برای توسعه بدون سربار همان ویژگی‌های FDD است؟من این مزیت فوق‌العاده را داشته‌ام که در زندگی شغلی‌ام، با یک تیم و گروه عالی، مشغول FDD بوده‌ام. من فکر می‌کنم که کانبن در زمینه‌هایی خارج از FDD، رشد پیدا کرد. به این شکل نیست که تلاش کرده باشیم FDD را با کانبن بهبود دهم اما اگر هیچ گاه FDD را انجام نداده بودم و پیش‌زمینه آن را نداشتم و اگر تفکراتی از Lean را تکامل نمی‌دادم، در انتها به کانبن نمی‌رسیدم. پیش‌زمینه‌هایی مانند نمودار جریان تجمعی (Accumulative Flow Diagram) و فکر کردن در مورد تمام مشکل را داشتم و از آنجا بود که در مورد تئوری قیود (Theory of Constraints) و فهمیدن گلوگاه‌ها (Bottleneck) و نحوه تخفیف دادن آنها فکر کردم. اگر این مجموعه پیش‌زمینه‌ها را نداشتم در پایان به کانبن نمی‌رسیدم. من نظراتی در اینترنت می‌بینم که کانبن، بهینه‌سازی FDD بود اما من مستقیماً آنها را به هم مربوط نمی‌کنم هرچند این تکامل تفکرات خودم در طی سال‌ها را درک می‌کنم.آیا کانبن یک رهیافت مناسب برای سازمانی است که بخواهد چابک شود یا اینکه یک رهیافت پیشرفته است؟در این باره هم صحبت‌های زیادی در اینترنت، در بلاگ‌ها، در توییتر و در کنفرانس‌ها می‌بینم. گفته می‌شود که کانبن یک رهیافت پیشرفته است و باید قبل از آنکه کانبن را امتحان کنید، در اسکرام خوب شوید. مشاهدات من نشان می‌دهد افرادی این صحبت را می‌کنند که اولاً کانبن را امتحان نکرده‌اند و دوماً علاقه زیادی دارند که ابتدا در اسکرام خوب شوند. من فکر می‌کنم که این مطلب به وضوح درست نیست زیرا اولین تیمی که کانبن را اجرا کرد یک تیم PSP-TSP بود. تیم دوم، یک تیم آبشاری بود. و غالب مطالعات موردی منتشر شده در ۲ کنفرانسی که ما برگزار کرده‌ایم، نیز اینگونه بوده‌اند. مثلاً در سایت Developer.com، یک مطالعه موردی از رابی بوش وجود دارد. مطالعه موردی دیگر که در اینترنت منتشر شده است، مربوط به شرکت گاماسوترا است که یک شرکت بازی‌سازی با تمرکز خاص بر روی تولید بازی است. (اخیرا این شرکت به GameDeveloper تغییر نام داده است -مترجم) در هیچ کدامشان، تیم‌ها قبل از آن که در کانبن خوب بشوند در اسکرام خوب نشده بودند. بنابراین هیچ کسی که در کانبن موفقیت داشته است، چنین چیزی را نمی‌گوید.و این سئوال را داریم که آیا کانبن تکنیک پیشرفته‌تری است؟ از تجربیات آشکار است که تیم‌هایی که کانبن را اجرا می‌کنند، خیلی سریع، بالغ می‌شوند. اگر با مقیاس CMMI بسنجید، ما به وضوح تیم‌هایی داشتیم که واقعاً در مدت زمان اندکی (۹ ماه، ۱۲ ماه، ۱۵ ماه و ...) از سطوح به نسبت نابالغ و بی‌نظم به سطح واقعاً بالغ مدیریت‌شده کمی (Quantitatively Managed) یعنی سطح چهارم CMMI رسیده‌اند. و به عقیده من، تنها پیش‌نیاز آن، همان طور که پیش از این اشاره کردم، قابلیت مدیریت پیکربندی است. اگر به مدل CMMI نگاه کنید، مدیریت پیکربندی، یک رفتار در سطح ۲ است و یکی از اولین قابلیت‌هایی است که برای تیم‌هایی که بی‌نظمی دارند، توصیه می‌شود. اگر نتوانند پیکربندی را ردیابی و مدیریت کنند نمی‌توانند جلوتر بروند. فکر می‌کنم کاملاً واضح است که تیم‌ها حتی اگر خیلی نابالغ هم باشند، از کانبن سود می‌برند. حتی اگر چابک هم نباشند از کانبن سود می‌برند. اما این سودمندی در مقایسه با آنچه در مورد دیگر متدهای چابک می‌بینیم بیشتر و سریعتر است. علتی که همچنان به کانبن می‌پردازم و آن را تبلیغ می‌کنم این است که تیم‌هایی را دیده‌ام که به چیزهایی رسیده‌اند که من پیش از این در زندگی حرفه‌ای ام نتوانسته بودم به آنها فائق آیم. این را یک نکته خیلی مثبت می‌بینم.برای سال‌ها، جامعه چابک می‌گفت که نیاز به قاب‌های زمانی (Time box) داریم تا بتوانیم بصورت واقع‌بینانه پیشرفت کار پروژه را اندازه‌گیری کنیم. اما شما خواستار پایان دادن به حکمرانی قاب‌های زمانی شدید. چرا؟در پس این موضوع چندین ایده وجود دارد. اول اینکه بیانیه چابک، اظهار نمی‌کند که دوره‌های با قاب‌زمانی، لازم است. آنچه واقعاً می‌گوید این است که باید هر ۲ الی ۸ هفته، نسخه نرم‌افزار منتشر کنیم (با ترجیح زمان‌های کمتر). این نسخه‌دادن است که مهم است نه قاب زمانی. فکر می‌کنم بیانیه درست می‌گوید. اما اگر به سال ۲۰۰۱ یا قبل از آن برگردیم، اگر در آن زمان به کسی می‌گفتید که هدف این است که هر دو هفته یکبار نسخه منتشر کنید، تنها ابزار در دسترس، دوره‌های با قاب‌زمانی بود. یک قاب زمانی ۱ هفته‌ای یا ۲ هفته‌ای یا ۴ هفته‌ای.همانطور که پیش‌از این اشاره کردم، این قاب زمانی ۳ چیز واقعاً متفاوت را به هم وابسته می‌کند. مورد اول این است که هر از چند وقت می‌توانیم با نمایندگان کسب‌وکار، جلسه داشته باشیم تا برای کارهایی که باید انجام دهیم اولویت‌بندی و برنامه‌ریزی کنیم. مورد دوم این است که چقدر طول می‌کشد که یک نیازمندی عملکردی یا ویژگی یا داستان کاربری (User Story)  یا هر اسمی که در سازمانتان به آن می‌دهید را تحلیل، طراحی، پیاده‌سازی و تست کنیم. و مورد سوم این است که هر از چند وقت می‌توانیم یک نسخه منتشر کنیم. اینها، هر کدام، مؤلفه‌های متفاوت خودشان را دارند.این که هر ازچند وقت جلسات کسب‌وکار داریم وابسته به هزینه هماهنگی این جلسات است. دفعات بیشتر بهتر از کمتر است. بهتر است دفعات بیشتری باشد که اطلاعات مربوط به اولویت‌بندی را بدست بیاوریم. این می‌تواند خروجی بهینه‌تری بدهد. این که چقدر طول می‌کشد تا یک داستان کاربری را کد بزنیم، کاملاً بی ربط با این موضوع است که هر از چند وقت با صاحبان کسب‌وکار یا دپارتمان بازاریابی، جلسه داریم. بنابراین چرا باید اینها را با هم، همبسته کنیم؟ چرا باید جلسات برنامه‌ریزی دوهفته یکبار را به منظور دوره دوهفته‌ای پیاده‌سازی داستان‌های کاربری اجبار کنیم؟ باید اجازه داده شود که همبستگی این چیزها از بین برود. وقتی ناهمبستگی (Decoupling) یک اصل خوب در مهندسی نرم‌افزار است چرا آن را در مهندسی فرآیند بکار نبریم؟ همین مطلب در مورد این که هر از چندوقت نسخه بدهیم نیز صادق است.آخرین بار که یک کلاس کانبن در هامبورگ داشتیم، یک مثال خیلی جالب داشتیم. یکی از شرکت‌کنندگان از یک شرکت تولید فولاد در آلمان می‌آمد. او می‌گفت که می‌توانند جلسات کسب‌وکار را برای اولویت‌بندی، یک بار در هفته داشته باشند که کاملاً معقول است. و زمان دوره مورد نیاز برای این که تحلیل، طراحی، توسعه و تست داشته باشند برای اغلب کارها، حدود ۶ هفته طول می‌کشد اما آنها نرم‌افزاری را توسعه می‌دادند که کنترل بخش حساس خط تولید را به عهده داشت و هزینه از کار انداختن آن برای بروزرسانی نرم‌افزار، خیلی زیاد بود. ارزش فولادهایی که در هرساعت تولید می‌شوند، خیلی زیاد بود. بنابراین می‌خواستند این کار را فقط هر ۶ ماه یک بار انجام دهند زیرا هزینه بسیاری زیادی داشت و ریسک بالایی داشت و زمان زیادی لازم بود تا اطمینان یابند که کدی که مستقر می‌کنند، بدون خطا است. آنها نمی‌توانستند تحمل کنند که خط را راه بیاندازند و به هم بریزد. این یک مثال از جایی است که یک ریتم یک‌هفته‌ای برای اولویت‌بندی، ۶ هفته طول زمان دوره برای توسعه و یک ریتم ۶ ماهه برای استقرار، داشتند. از این مثال کاملاً روشن است که هر متد چابکی که بخواهد طول دوره‌های ۲ هفته‌ای داشته باشد، به چنین فضایی، نمی‌خورد. بنابراین با ناهمبسته‌ کردن این چیزها و این که به آنها امکان دهیم آزادانه حرکت کنند، سازمان‌ها را از حکمرانی قاب‌ زمانی، آزاد می‌کنیم.خیلی از افراد می‌گویند که گذشته‌کاوی (Retrospective)، قلب رهیافت‌های چابک است. گذشته‌کاوی در کانبن چطور است؟خیلی روشن است که اگر توقف نکنید و عکس‌العمل نشان ندهید نمی‌توانید چیزی یاد بگیرید. با کانبن من تیم‌ها را تشویق کرده‌ام که برای توقف و عکس‌العمل نشان دادن، فعالیتی داشته باشند که بیشتر در سطح سازمان باشد. من به این کارها، بازبینی عملیات (Operation Review) می‌گویم. این چیز جدیدی نیست. من مفهوم بازبینی عملیات را اختراع نکرده‌ام. آنچه که بین بازبینی عملیات و گذشته‌کاوی مرسوم چابک، تفاوت دارد، میزان عینی بودن آن است. مرسوم است که در بازبینی عملیات مدیران حضور یابند تا داده‌ها را بیاورند. داده‌ها از سیستم جریان کار و سیستم خطاها و این قبیل چیزها می‌آید. این داده‌ها، واقعیت‌های عینی از طول دوره، بازدهی، سرعت، نرخ خطاها و شاید کارایی و زمان هدررفته و ... هستند. تا به این ترتیب به نمودارهای یکپارچه شده جریان کار نگاه کنیم، به تعداد موارد مسدودشده و مقدار زمان برطرف کردن آنها نگاه کنیم. یعنی از واقعیت‌ها و داده‌های عینی استفاده می‌شود. اما گذشته‌کاوی مرسوم در چابک، بیشتر به جنبه‌های شخصی تمایل دارد. اینکه چه احساسی در مورد دوره (Sprint) گذشته داریم؟ از چه چیزی خوشمان می‌آید؟ از چه خوشمان نمی‌آید؟ چه چیز را به همان صورت قبلی انجام خواهیم داد و چه چیز را متفاوت انجام خواهیم داد؟ این‌ها تمایل به جنبه‌های شخصی دارد. وقتی تیم بالغ می‌شود بیشتر عینی می‌شود. من با کانبن تلاش می‌کنم که از همان ابتدا، عینی بودن را تشویق کنم.در اینجا نیز دوباره این سئوال را داریم که این جلسات هر چند وقت یک بار باشد؟ این نیز یک سئوال ناهمبستگی دیگر است. متدهای چابک، جلسات گذشته‌کاوی را به انتشار نسخه‌ها، همبسته می‌کنند. یعنی اگر دوره‌های دوهفته‌ای داشته باشید، جلسات گذشته‌کاوی دوهفته‌ای هم خواهید داشت. این می‌تواند خوب باشد اما اگر بخواهید که یک ماه یکبار یا هفته‌ای یکبار داشته باشید چطور؟ بنابراین من افراد را تشویق می‌کنم که این بازبینی عملیات را داشته باشند و خودشان ریتم آن را انتخاب کنند تا آن را از زمان انتشار نسخه یا دوره برنامه‌ریزی شده ناهمبسته کنند. و این که آن را در سطح سازمان و نه در سطح یک پروژه مجزا انجام دهند. و این که همه دپارتمان را دور هم جمع کنند و به همه گزارش دهند که بر روی چه چیزی باید کار شود. این کار به این علت خوب است که اجازه می‌دهد چرخش ایده‌ها از یک پروژه به پروژه دیگر فراهم شود و توسعه و بلوغ سازمانی را تشویق می‌کند. به همین خاطر است که درتیم‌هایی که کانبن را اجرا می‌کنند، می‌بینیم بلوغ سازمان تسریع می‌شود.در همین حین من تیم‌های کانبنی دیده‌ام که جلسات گذشته‌کاوی در سطح پروژه یا در سطح دوره دارند. اغلب وقتی کار به خوبی پیش نمی‌رود مثلاً نسخه‌ای داده‌اند که مشکلاتی داشته است در این مورد جلسه می‌گذارند که چطور از رخداد مجدد آن در آینده جلوگیری کنیم. همچنین من می‌شنوم که افراد می‌گویند که تیم ما جلسات گذشته‌کاوی را متوقف کرده‌اند. البته آنها جلسات بازبینی عملیات را دارند اما جلسات گذشته‌‌کاوی مربوط به دوره‌ها را ندارند. البته این چیزی نیست که افراد خبره در زمینه کانبن به آن حکم کرده باشند و بیشتر چیزهایی است که گزارش می‌شود. وقتی شما چرایی آن را تحلیل می‌کنید مشخص می‌شود که اکثر کارهایی که به صورت عادی در جلسه گذشته‌کاوی انجام می‌شود به جلسات سرپایی روزانه منتقل شده است. و چون درباره بهبود فرآیند، هرروزه صحبت می‌کنند، در پایان دوره یا وقتی که نسخه می‌دهند، نیازی به انجام آن ندارند. این کار به جای رفتار ماهی یک بار یا دو هفته‌ یک بار به رفتار هرروزه تبدیل می‌‌شود. بنابراین تیم‌های خوب کانبنی که فرهنگ بهبود مستمر دارند، جلسات گذشته‌کاوی را هرروزه انجام می‌دهند. در کانبن به علت وجود ترکیب جلسات سرپایی روزانه و جلسات بازبینی عملیات، تأکید بر روی جلسات گذشته‌کاوی برداشته شده است.نکته جالب دیگر، «تخمین» است. آیا درست است که کانبن، نسبت به هزینه‌های تخمین زدن کاملاً محتاط است؟سئوال خوبی است زیرا در اولین مثالمان، تخمین نزدیم. مشخص می‌شود که تخمین زدن یک انتخاب است. اگر بخواهید می‌توانید آن را انجام دهید. اغلب افراد چیزی را تخمین می‌زنند تا بتوانند تاریخ تحویل را وعده کنند. مشکل اینجاست که همه کارهایی که می‌کنید نیاز به تاریخ تحویل سفت و سخت ندارد. می‌شنوم که گفته می‌شود که اگر تاریخی را تعهد نکنید، نمی‌توانید افراد را مسئولیت پذیر نگاه دارید. اما من احساس می‌کنم وقتی شما، یک هدف رسمی تعیین می‌کنید و افراد را مجبور می‌کنید که آن را برآورده کنند، باعث برانگیخته شدن رفتار بی‌باکانه می‌شود. در حوزه بهبود فرآیند، در حوزه تضمین کیفیت و هم در آموزش‌های رهبران اسکرام و ... حقایق فراوانی وجود دارد که اگر این گونه هدف‌گذاری‌هایی داشته باشید و بگویید این انتظاری است که باید تحقق یابد، در آن صورت افراد با رفتار بی‌باکانه پاسخ می‌دهند. وقتی بی‌باکانه رفتار می‌کنند، بهبود را متوقف می‌کنند و فقط رفتارهای بی‌باکانه را دوباره و دوباره تکرار می‌کنند. و یادگیری را متوقف می‌کنند. بنابراین توصیه‌هایی از دمینگ و گود رَپ  و افراد دیگر مثلاً جان سِیدن از انگلستان برای حذف این هدف‌گذاری‌ها داریم. از طرف دیگر، برخی مواقع است که واقعاً به یک تاریخ تحویل نیاز دارید. ممکن است که یک نیازمندی برای یک مؤسسه سرمایه‌گذاری داشته باشید و دولت مقررات را تغییر داده باشد و مقررات جدید از اول اکتبر امسال اجرا شود. اگر نرم‌افزار را برای مطابقت با مقررات جدید، تغییر ندهید، اجازه معامله محصول خاصی را نخواهید داشت. در این صورت اگر این نیازمندی را به موقع، تحویل ندهید، هزینه زیادی برای کسب‌وکارتان خواهد داشت. روشن است که در اینجا این که بدانیم می‌توانیم در زمان مقرر کار را تحویل دهیم، ارزش دارد. برای این نیازمندی خاص، ارزشش را دارد که هزینه تخمین زدن را بپردازیم. اگر فکر می‌کنیم که این کار ۶ هفته زمان می‌برد و آن را برای اول اکتبر نیاز داریم، منطقی است که در اوایل آگوست آن را آغاز کنیم. منطقی نیست که آن را در ماه مِی آغاز کنیم زیرا تحویل زودتر، ارزشی ندارد اما اگر با تأخیر در نوامبر، تحویل دهید، یک ماه کسب را از دست خواهید داد. بنابراین آنچه کانبن می‌گوید این است که تخمین را به صورت مناسب استفاده کنید. به این فکر کنید که چه زمانی برای تخمین زدن مناسب است و هوشمندانه این کار را بکنید. بنابراین تخمین زدن یک انتخاب می‌شود. به جای تخمین زدن همه چیز، تنها چیزهایی که واقعاً مهم هستند و نیاز به تخمین دارند، را تخمین می‌زنید.ایده کانبن از صنعت اتومبیل آمده است. جایی که ما با یک رویه تکراری یکنواخت سروکار داریم. اما پروژه‌های نرم‌افزار بیشتر وابسته به منش توسعه‌دهندگان خود هستند. به همین علت خیلی خلاقانه است و هربار رویه خاص خود را دارد. آیا اساساً کانبن برای پروژه‌های نرم‌افزاری مناسب است؟ یا این که قدرت واقعی کانبن بیشتر در تعمیر و نگهداری است؟این سئوال خوبی است. کانبن به روشنی برای انجام دادن پروژه‌های نرم‌افزاری مناسب است. افراد خیلی زیادی را در نقاط مختلف دنیا داریم که الان دارند آن را انجام می‌دهند. اما سئوالات جالبی هم وجود دارد. وقتی توسعه نرم‌افزار، نسبت به تولید کارخانه، تغییرپذیری‌های بسیار بیشتری دارد چرا همچنان کانبن کار می‌کند؟ این منجر می‌شود به تحلیل این که چگونه کانبن با محیط‌های مختلف مانند محیط توسعه نرم‌افزار تطبیق یافته است.با این که موافقم که توسعه نرم‌افزار خیلی خلاقانه است اما فکر نمی‌کنم که فرآیند آن، تغییرات خیلی گسترده‌ای داشته باشد. به عنوان مثال اگر به صنعت بازی‌سازی توجه کنید، هرچند، بسیار خلاقانه است اما آن هم، این گونه است. مشخص شده است که تعداد زیادی از بکارگیری‌های کانبن با شرکت‌های بازی‌سازی بوده است زیرا مؤلفه‌های زیادی در بازی‌سازی وجود دارد که از رویه‌های مشخصی پیروی می‌کند. در تولید بازی (منظورم تنها برنامه‌نویسی نیست)، تولید گرافیک‌ها، تهیه داده‌های مربوط به سطح‌های داخل بازی، تولید صداها و شاید انیمیشن را داریم. بازی‌های امروزی، واقعاً انیمیشن‌های خوبی دارند. به آدم‌های واقعی، نشانگرهایی می‌چسبانند و از آنها فیلم می‌گیرند و نحوه حرکت سر و دست و پاها، خم شدن بدن و ... را مشاهده می‌کنند.همه این داده‌ها را می‌گیرند و وارد موتورهای گرافیکی ۳ بعدی می‌کنند تا بتوانند حرکتی مشابه حرکت آدم‌های واقعی داشته باشند. این نحوه تولید بازی است. در این کار تعدادی مؤلفه‌های فرآیندی وجود دارد. برخی کارها قبل از کارهای دیگر باید انجام شود. قبل از آنکه متحرک‌سازی و render کردن را آغاز کنید، لازم است که داده‌ها را جمع‌آوری کنید. و تخصص‌های مختلفی وجود دارد. برخی متخصص جمع‌آوری داده هستند. برخی متخصص دستکاری‌های بعدی آن داده‌ها به منظور تهیه یک قیافه و پخش درست هستند. کانبن خود را به خوبی با این فضا وفق داده است زیرا کمک می‌کند که این فرآیند را تعریف کرده و نحوه پیشرفت کار در آن را نظارت کنید. اما همچنان توسعه نرم‌افزار نسبت به تولید کارخانه، تغییر‌پذیری‌های بییشتری دارد. ممکن است بپرسید انجام دادن یک داستان کاربری (User Story) چه قدر زمان می‌گیرد. پاسخ می‌تواند هرچیزی بین نصف روز تا ۱۰ روز باشد. روشن است که مفهوم زمان تاکت (Takt Time)  که در تولید کارخانه‌ای داریم را در اینجا نمی‌توانید داشته باشید. اگر به چیزی مانند خط تولید تویوتای کورولا نگاه کنید، زمان تاکت ممکن است ۱۹۷ ثانیه باشد. این به آن معناست که هر ۱۹۷ ثانیه یک خودروی تویوتا در آخر خط، کامل شده است. چطور به ۱۹۷ ثانیه رسیده‌اند؟ این خیلی راحت پاسخ داده می‌شود. ۱۹۷ ثانیه از محاسبه سه‌سیگمای مربوط به UCL (Upper Control Limit) طولانی‌ترین فعالیت در خط تولید حاصل می‌شود. ممکن است به عنوان مثال فعالیتی مانند چسباندن شیشه جلو باشد که بطور متوسط ۸۰ ثانیه طول بکشد و UCL آن ۹۷ ثانیه باشد و LCL آن ۷۳ ثانیه باشد و برای آن بازه ۷۳ تا ۹۷ ثانیه را داشته باشیم و این فعالیت، کندترین فعالیت خط تولید باشد. در این صورت اگر زمان تاکت را برابر با ۹۷ ثانیه قرار دهیم، برای این که همه چیز روان کار کند، باید هیچ گاه خط تولید متوقف نشود. در توسعه نرم‌افزار نمی‌توانید مفهوم  زمان تاکت را داشته باشید. اینکه UCL در دوره توسعه و تست یک داستان کاربری (User Story)  چقدر است به نوعی یک سئوال بی‌معنی است.از طرف دیگر، ما برای مقابله با تغییر‌پذیری‌ها و شرایط مختلف ریسک، تعدادی تکنیک در کانبن نرم‌افزاری توسعه داده‌ایم که واقعاً سیستم را خیلی منعطف کرده است و قابلیت مقابله و به نوعی بهره‌مند شدن از تغییر‌پذیری‌ها را فراهم می‌کند. مثلاً با استفاده از مفهوم‌هایی مانند رده‌های سرویس (Classes of Service) این کار را می‌کنیم. در تولید کارخانه‌ای، تنها دو رده سرویس داریم: صف استاندارد وروداول-خروج اول (First in - First Out) و موارد تسریع شده مربوط به امور واقعاً فوری (در خیلی از سیستم‌های کانبن حتی آن موارد تسریع شده را هم نداریم و فقط همان صف استاندارد FIFO را داریم). علتی که آنجا این روش کار می‌کند این است که چیزهایی که وارد خط می‌شوند یک جور هستند. اگر شما ماشینی را مونتاژ کنید که نیاز به جعبه‌دنده دارد، جعبه‌دنده‌ بعدی با جعبه‌دنده پشت سرش با جعبه دنده پشت سر آن، همگی یکسان هستند. بنابراین هزینه تأخیر برای یک جعبه دنده با هزینه تأخیر جعبه‌دنده بعدی و بعد از آن همگی برابر است.اما در توسعه نرم‌افزار ارزش هر داستان کاربری (User Story)، منحصربفرد و متفاوت است. بنابراین هزینه تأخیر یک داستان کاربری با هزینه تأخیر داستان کاربری بعد از آن متفاوت است. از این اطلاعات می‌توانید برای مدیریت بهتر ریسک و رسیدن به یک خروجی بهینه‌تر ریسک استفاده نمایید. این که بیشترین ارزش را در کمترین زمان و با کمترین هزینه، تحویل دهید. روش این کار، استفاده از رده‌‌های سرویس است. یعنی کارهای متفاوتی تعریف کنید و رده‌های مختلفی از سرویس با سطوح مختلف پذیرش سرویس را به آنها منتسب کنید و این که اهداف متفاوتی برای طول دوره و زمان تحویل مورد انتظار داشته باشید. با محدودکردن مجموع کارهای در حال انجام، (مثلاً اینکه می‌توانید در مجموع ۲۰ کار در حال پیشرفت داشته باشید) و با تفکیک کردن آنها به رده‌های مختلف سرویس، اجازه می‌دهید که سیستم منعطف باشد. انعطاف نسبت به این موارد که: برخی چیزها بزرگ هستند، برخی کوچکتر هستند، برخی می‌توانند سریعتر انجام شوند، برخی باید کندتر انجام شوند و هرکدام، هزینه‌های تأخیر متفاوتی دارند.بنابراین کانبن برای توسعه نرم‌افزار با همان اصول تولید در کارخانه آغاز شد ولی مجموعه رویه‌های متفاوتی را تکامل داد. ما سعی نکردیم که رویه‌های مربوط به تولید در کارخانه را به همان شکل، کپی کنیم. در واقع اصلاً سعی نکردیم آنها را کپی کنیم. ما به قواعد نگاه کردیم و آنها را برای حل مشکلات توسعه نرم‌افزار به کار گرفتیم و مجموعه رویه‌های خودمان را تکامل دادیم. بنابراین واقعاً از تولید کارخانه نیامده است.آیا صنایع یا انواعی از سازمان‌ها هستند که کانبن را برایشان توصیه نکنید؟سخت است که نکات منفی را بگوییم. ما صنایعی را می‌بینیم که کانبن را به خدمت گرفته‌اند. موارد کاربرد زیادی در امور نگهداری IT در برطرف کردن خطاهای محصول و در بروزرسانی‌های کوچک داشته است. به نظر می‌رسد ذاتاً خیلی مناسب آن است. ما بکار گرفتن کانبن در کمپانی‌های بازی‌سازی را دیده‌ایم. فکر می‌کنم بیشتر به خاطر این است که تخصص‌های زیادی در بازی‌سازی وجود دارد و این ایده چابک که یک نوع نیروی کار کلی داریم برای بازی‌سازی خیلی خوب کار نمی‌کند. تخصص‌ها و مهارت‌های فراوانی وجود دارد و کانبن کمک می‌کند که این مسأله را بهینه کنید. ما دیده‌ایم که کانبن در شرکت‌های سرمایه‌گذاری به خدمت گرفته شده است زیرا شرکت‌های سرمایه‌گذرای، مفاهیم مدیریت ریسک که در کانبن نرم‌افزاری وجود دارد را درک می‌کنند. همچنین کانبن را دیده‌ایم که در دپارتمان‌های IT صنایع سنتی‌تر، بکار گرفته شده است. کارخانجات مربوط به خودروسازی مثلاً رابرت بوش. آنها کانبن را از جنبه تولیدی کسب و کار می‌شناسند. و می‌دانند که بخشی از Lean است. این که توانسته‌اند در بهینه‌سازی تولید از آن استفاده کنند آنها را کنجکاو کرده است که بفهمند چطور می‌توان آن را در دپارتمان IT بکار برد. همین که می‌بینند افراد آن را استفاده می‌کنند و در مورد آن صحبت می‌کنند، برایشان جالب می‌شود و می‌پرسند که آیا واقعاً کار می‌کند؟ ما تا به حال فکر نکرده بودیم که در بخش IT از آن استفاده کنیم. برایمان بیشتر بگویید. بنابراین ما دیده‌ایم که در آنجا کانبن را بکار گرفته‌اند. اگر حمایت‌های سازمانی نبود، خوب جا نمی‌افتاد.با وجود این که مطمئنم که این‌ها درست است اما فکر نمی‌کنم که به مقدار کافی می‌دانیم. ما چه به صورت سراسری و چه در یک صنعت خاص هنوز نمونه‌های کافی ندیده‌ایم و غالب موارد، گزارش همگانی نشده است. هرچند تعداد خوبی، مطالعه موردی منتشرشده در گزارش‌ها و برخی مقالات مجلات و تعدادی از کتاب‌ها بیرون آمده است، اما همچنان برای این که دسته موارد منفی را شناسایی کنیم، کافی نیست. بسیار خوب دیوید. برای مصاحبه متشکرم. کلام آخر در مورد کانبن؟از دعوت شما متشکرم. امیدوارم پاسخ‌ها مفید بوده باشد و برای مسائلی که ممکن است افراد داشته باشند روشنگر بوده باشد. توصیه من به هر فرد علاقه‌مندی این است که آن را امتحان کند. آن را در گوگل، جستجو کنید. سایت limitedwipsociety.org را که صفحه خانگی کانبن نرم‌افزاری است را ببینید. به اطلاعات آنجا که به تعداد زیادی صفحات اطلاعاتی و مقاله خارجی ارجاع دارد، نگاهی بیاندازید. البته مطالعات زیاد، غیرحسی می‌شود. تنها راه درک آن این است که امتحانش کنید.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Sat, 18 Dec 2021 22:06:19 +0330</pubDate>
            </item>
                    <item>
                <title>درک مکانیکی</title>
                <link>https://virgool.io/se-radio/se-radio-mechanical-sympathy-a53nmrnekotw</link>
                <description>مطلبی که می‌خوانید ترجمه‌ی قسمت ۲۰۱ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت رابرت بلومن با مارتین تامسون که یکی از متخصصان پیش‌رو در تنظیم و بهبود کارایی سیستم‌های کامپیوتری است مصاحبه می‌کند. در این قسمت بحث می‌شود که چطور داشتن پیش‌زمینه و درک از عملکرد سخت‌افزاری و مکانیک کامپیوتر می‌تواند شما را در طراحی و توسعه‌ی مؤثرتر سیستم‌های نرم‌افزاری یاری دهد. مارتین یک سخنران در کنفرانس‌های فناوری، بنیان‌گذار شرکت LMAX، یکی از بنیانگذاران پروژه متن بازِ Disruptor، و صاحب بلاگی به نام درک مکانیکی (Mechanical Sympathy) است. او در حال حاضر صاحب Real Logic Ltd. است که یک شرکت مشاوره در زمینه‌ی سیستم‌های کامپیوتری در لندن است.مارتین لطفاً کمی در مورد سوابق خود به شنوندگان ما بگویید. چطور به مبحث کارایی علاقه‌مند شدید؟[این موضوع] خیلی جالب است. من کارهای زیادی در طول دهه‌های اخیر انجام دادم. اما همیشه به سمتی کشیده می‌شدم که کارایی کامپیوتر افزایش پیدا می‌کرد. در آنجا فرصت‌هایی ایجاد می‌شد که قبلاً وجود نداشت. فکر می‌کنم اولین کاری که در این زمینه انجام دادم به سال ٩٢ بر می‌گردد که اطلاعات فرابورس را می‌گرفتم. در آن زمان مجبور بودیم همه چیز را روی Main Frame های IBM پردازش کنیم. این اطلاعات روی دو هارد دیسک که روی یک کامپیوتر نصب شده بودند، جا می‌شد. آن موقع اندازه‌ی هارد دیسک‌ها حدود 250 مگابایت بود. اما امروز ما نهان‌گاه‌ها (Cache) را برای نگه‌داری این [حجم] اطلاعات داریم و این فرصت‌هایی را در کسب و کار ایجاد می‌کند که قبلاً امکان‌پذیر نبود.فعالیت‌های حرفه‌ای من شامل چیزهای متفاوتی بوده است: مدل‌سازی وسایل نقلیه، کار با فهرست‌های بزرگ، کار با سیستم‌های تجاری. سیستم‌هایی که واقعاً با هم متفاوتند، اما تنظیم کارایی و دستیابی به توان عملیاتی (Throughput) بالا بخشی از اکثر این کارها بوده است.اسم بلاگ شما درک مکانیکی است، منظورتان از آن چیست؟درک مکانیکی اصطلاح جالبی است. من از طرفداران مسابقات موتورسواری هستم؛ این اصطلاح از آن‌جا نشأت گرفت. Jackie Stewart نام موتورسواری در دهه‌های 60 و 70 است که موتورسوار فوق‌العاده موفقی بود و در زمین‌های مرطوب خیلی خوب عمل می‌کرد. او در مورد داشتن حس درک مکانیکی با موتوری که سوارش بود صحبت می‌کرد. زمانی که آن وسیله را درک می‌کرد، نسبت به بقیه‌ی موتور سوارها بهتر عمل می‌کرد و این در زمین‌های مرطوب به خوبی نشان داده می‌شد. در یک جمله درک مکانیکی یعنی به کارگیری قابلیت‌ها تا مرز توانایی آن و نه فراتر از آن، تا بهترین نتیجه حاصل شود. برای او درک مکانیکی به معنی هماهنگی در کار کردن با موتورش بود و برای من هم چیزی شبیه به این در سخت‌افزار و نرم‌افزار است. هر زمان که نرم‌افزار نحوه‌ی کارکرد سخت‌افزار و بستر سخت‌افزاری را درک کند، با آن هماهنگ می‌شود و بهترین نتیجه حاصل می‌شود.امروزه تعداد زیادی از نرم‌افزارها را می‌بینیم که بر خلاف سخت‌افزار عمل می‌کنند و درک خیلی محدودی از آن دارند. در نتیجه نه تنها کارایی پایینی دارند، بلکه ممکن است دچار مشکلات دیگری هم بشوند: چون ابزارها به درستی استفاده نشده‌اند، در شرایط مرزی مشکلات بروز می‌کنند. این به آن معنی نیست که شما باید تمام جزئیات را مانند یک فرد خبره بفهمید، تنها دانستن موارد مهم کافی است. مثلاً در مسابقات موتورسواری لازم نیست بدانم که موتور چطور ساخته شده است، فقط لازم است بدانم چطور کار می‌کند. بنابراین لازم است مفاهیم اساسی نحوه‌ی کارکرد جعبه دنده و سیستم تعلیق را بفهمم. با دانستن این موارد در سطح پایه‌ای می‌توان بهترین نتیجه را گرفت. در نرم‌افزار هم همین‌طور است.می‌شود یک نمای کلی از مواردی که به نظرتان توسعه‌دهندگان نرم‌افزار به آن آگاهی ندارند، به ما بگویید؟بله، مثال‌های خوب زیادی در این زمینه وجود دارد. بسیاری از آن‌ها در حقیقت نام‌گذاری‌هایی هستند که استفاده می‌کنیم و ما را در جهت اشتباه هدایت می‌کنند. نام‌هایی که برای چیزهای خیلی مهم در برنامه‌ها به کار می‌بریم. مثلاً در مورد حافظه با دسترسی تصادفی (Random Access Memory) صحبت می‌کنیم، در حالی که دسترسی به حافظه به هیچ وجه تصادفی نیست. تفاوت قابل توجهی میان دسترسی خطی با دسترسی تصادفی به حافظه وجود دارد. به علت نحوه‌ی عملکرد سخت‌افزار برخی اطلاعات با تأخیر کمتری به حافظه‌ انتقال پیدا می‌کنند.اگر دسترسی به خانه‌های پشت سر هم در حافظه باشد، سخت‌افزار می‌تواند تقریباً تأخیرها را به کلی پنهان کند و دسترسی در زمانی کوتاه در حد چند نانو ثانیه صورت خواهد گرفت. در صورتی که اگر به صورت تصادفی به آن دسترسی پیدا کنم این زمان به چیزی حدود ٧٠ تا ١٠٠ نانو ثانیه افزایش پیدا می‌کند (همان کامپیوتر و همان قابلیت‌های سخت‌افزاری که با الگوی متفاوتی به حافظه دسترسی پیدا کرده است). بنابراین اجازه دهید که بگویم حافظه خیلی شبیه به یک دستگاه خطی مثل نوار عمل می‌کند تا یک دستگاه با دسترسی تصادفی. هارد دیسک‌ها هم ویژگی‌های مشابهی دارند، حتی SSD ها هم برخی از این ویژگی‌ها را دارند، اما بیشتر افراد از این مسائل آگاهی ندارند و بدون اینکه بدانند حافظه چگونه کار می‌کند به آن دسترسی پیدا می‌کنند و در نتیجه دچار مشکلات کارایی می‌شوند.حین خواندن قسمت‌هایی از بلاگ شما یک مسئله به صورت پررنگ دیده می‌شود و آن این است که بخش عمده‌ای از کارایی برنامه تحت تأثیر رابطه‌ی میان هسته‌های CPU و لایه‌های نهان‌گاه (Cache) آن است. کمی در مورد اهمیت این موضوع توضیح دهید.این چیزی است که زمانی که یک نرم‌افزار مدرن را پروفایل می‌کنید زیاد به آن بر می‌خورید. ما حافظه‌ی خیلی کوچکی در نهان‌گاه داریم که در سلسله مراتبی از نهان‌گاه‌ها سازمان‌دهی شده است. در هر سطح میزان حافظه افزایش پیدا کرده و در مقابل تأخیر دسترسی هم افزایش پیدا می‌کند. CPU هیچ وقت روی حافظه کار نمی‌کند، بلکه محتویات آن را در ثبات‌های داخلی ذخیره کرده، عملیات را روی ثبات‌ها انجام داده و نتیجه را به دست می‌آورد. حتی این نتیجه را به صورت مستقیم در حافظه قرار نمی‌دهد، بلکه آن را در زیرسیستم نهان‌گاه ذخیره می‌کند.در تمامی سیستم‌های کامپیوتری مدرن زیر سیستم نهان‌گاه منبع اطلاعات است و هنگامی که به نقطه‌ی تخلیه (Point of Exhaustion) برسیم، محتویات نهان‌گاه در حافظه ذخیره می‌شود. نهان‌گاه‌ها از الگوریتمِ «اخیراً کمتر استفاده شده» (Least Recently Used) برای تبادل داده‌ها استفاده می‌کنند و این خوب است. داده‌هایی که اخیراً مورد استفاده قرار گرفته‌اند، احتمالاً در نهان‌گاه باقی می‌مانند. علاوه بر این نهان‌گاه حافظه را تکه تکه دریافت می‌کند و نه بایت به بایت. این تکه‌ها ممکن است با توجه به اینکه در چه سطحی از نهان‌گاه هستیم، به اندازه خط نهان‌گاه (Cache Line) یا صفحات (Page) باشند. بنابراین حافظه‌های نزدیک به هم، با هم وارد نهان‌گاه می‌شوند. مسئله‌ی دیگر پیش‌واکشی‌های سخت‌افزاری (Hardware Pre-fetcher) هستند که با بررسی الگوهای دسترسی در کد و بر اساس آن، قسمتی از حافظه را پیش از دسترسی به آن، واکشی می‌کنند.دسترسی به نهان‌گاه سطح ١ که پردازنده‌ها مستقیماً با آن کار می‌کنند تنها ٣ تا ٤ چرخه طول می‌کشد. بعد از آن سطح ٢ است که نهان‌گاه بزرگ‌تری است و در پردازنده‌های امروزی حدود ٢٥٦ کیلوبایت حافظه دارد که به مراتب بیشتر از ٣٢ کیلوبایت در سطح قبلی است. بعد از آن سطح ٣ است که چیزی بین ٢ تا ٣ مگابایت حافظه دارد. همین‌طور که حافظه افزایش پیدا می‌کند تأخیر هم افزایش پیدا می‌کند.همه‌ی این‌ها زمانی اهمیت پیدا می‌کند که می‌خواهیم الگوریتمی را انتخاب کنیم. در دانشگاه‌ها به ما در مورد پیچیدگی الگوریتم‌ها آموزش داده شده است، اما در محاسبه‌ی این مرتبه‌ی پیچیدگی، سخت‌افزار در نظر گرفته نشده است. یک مثال خوب در این مورد، لیست پیوندی است. اگر یک لیست پیوندی را پیمایش کنیم، مرتبه‌ی آن می‌بایست با پیمایش یک آرایه یکسان باشد. اگر به مرتبه‌ی الگوریتم آن نگاه کنم متوجه نمی‌شوم دسترسی به آن چند برابر بیشتر از آرایه است، اما می‌بینم که دسترسی تصادفی به آرایه به مراتب سریع‌تر از لیست پیوندی است.مسئله‌ی مهم‌تر این است که زمانی که یک لیست پیوندی را پیمایش می‌کنیم، گره‌ی بعدی ممکن است در هر جایی از حافظه قرار گرفته باشد. در نتیجه یک دسترسی تصادفی به حافظه خواهیم داشت و پیش‌واکشی‌های سخت‌افزاری نمی‌توانند کمکی کنند. دریافت حافظه‌های نزدیک به هم، هم کمکی نمی‌کند. نگه‌داشتن آخرین اطلاعات استفاده شده هم کمکی نمی‌کند. بنابراین دسترسی به یک لیست پیوندی بزرگ در مقایسه با یک آرایه‌ی بزرگ می‌تواند به مراتب زمان‌گیرتر باشد. چنین الگوهایی در نگاشت‌ها (Map) و درخت‌ها (Tree) و سایر ساختارها نیز دیده می‌شوند.فکر می‌کنم منظور شما این است که معماری سخت‌افزار، برخی فرض‌ها را در مورد نحوه‌ی دسترسی برنامه به حافظه در نظر می‌گیرد که در صورتی درست از آب در می‌آید که برنامه نویس‌ها هم آن‌ها را در نظر بگیرند.بله، درست است. فرضیات زیادی وجود دارد، یکی از آن‌ها را گفتم. مطلب دیگر این است که تعداد ترانزیستور‌ها و هوشمندی پردازنده‌ها همواره در حال افزایش است، ولی این رشد اساساً محدود است. اگر به طور کاملاً تصادفی به حافظه دسترسی پیدا کنید، بدترین کارایی حاصل می‌شود چون سخت‌افزار نمی‌تواند به شما کمکی کند. در حقیقت مسئله فراتر از این است؛ فقط داده‌ها نیستند که بر کارایی تأثیرگذارند، بلکه جریان دستورالعمل‌ها نیز در آن مؤثر است. پردازنده‌ها اطلاعاتی آماری در مورد انشعاب‌های برنامه را نگه‌داری کرده و بر اساس آن پیش‌بینی‌هایی از مسیر انشعاب‌های بعدی انجام می‌دهند. پردازنده‌های مدرن مسیر انشعاب‌ها را پیش‌بینی می‌کنند، چون ممکن است داده‌های (لازم برای انجام محاسبات) آن هنوز آماده نباشند. بنابراین در حالی که منتظر دریافت اطلاعات هستند، فرضی را در مورد انشعاب (درست یا غلط بودن آن) در نظر گرفته و اجرای دستورالعمل‌های بعدی را ادامه می‌دهند. در صورتی که بعداً معلوم شود که فرض اشتباه بوده، می‌بایست نتایج این محاسبات دور ریخته شود. در صورتی که فرض درست باشد، کار از پیش در حال اجرا بوده و کد سریع‌تر شده است. بنابراین با توجه به این‌که این اطلاعات آماری نگه‌داری می‌شود، برنامه باید رفتاری قابل پیش‌بینی داشته باشد و از الگوهای مشابهی پیروی کند. در صورتی که رفتار تصادفی باشد، مزیت ذکر شده از دست می‌رود. مسئله‌ی جالب این است که در صورتی که در مورد الگوریتم‌ها و کاربرد آن فکر شود، بسیاری از انشعاب‌ها در برنامه می‌توانند با محاسبات ریاضی جایگزین شوند یا این‌که می‌شود مدل تمیزتر و ساده‌تری از مسئله ارائه کرد.اطلاعات زیادی در مورد نحوه‌ی عملکرد پردازنده‌های مدرن و سیستم‌های زمان اجرا وجود دارد و اگر واقعاً می‌خواهید به کارایی بالا دست پیدا کنید، به توابع کوچک، ساده، خطی، و با قابلیت ترکیب بالا نیاز دارید. بهبود کارایی توابع بزرگ با انشعاب‌ها و حلقه‌های زیاد، در سطح پردازنده و سیستم‌های زمان اجرا (Runtime System) کار فوق‌العاده دشواری است. در مقابل، کد تمیز و قابل پیش‌بینی بسیار سریع اجرا می‌شود، علاوه بر این خواندن و درک آن برای انسان‌ها هم ساده‌تر است؛ این‌ها با یکدیگر مغایر نیستند. من زیاد می‌شنوم که افراد می‌گویند: اگر من کدم را برای کارایی بالاتر بهبود دهم، خوانایی آن از دست می‌رود. به نظر من این درست نیست. در واقع کاملاً برعکس است. مجموعه‌ای از توابع موزون و زیبا، با وظایف تفکیک شده، دارای همبستگی بالا، ساده و قابل ترکیب با هم، در بیش از ٩٠% موارد کاربرد، عملکرد فوق‌العاده چشم‌گیری دارند. شرایط خاصی نیز وجود دارد که نیاز به کارهای خاص دارد، اما آن‌ها استثناء هستند.چند دقیقه پیش در مورد آرایه‌ها و لیست‌ها صحبت می‌کردید. من به یکی از مطالب بلاگ شما برخوردم که گفتید بسیاری از کتابخانه‌های استاندارد مربوط به ساختمان داده‌های پایه که در زبان‌های برنامه‌نویسی متداول وجود دارند، خیلی مناسب سخت‌افزار (Machine Friendly) نیستند. آیا این درست است؟بله، کاملاً درست است. برای مثال، در محبوب‌ترین زبان برنامه‌نویسی دنیا، جاوا، اگر بخواهم چینشی به صورت ساختار آرایه‌ای داشته باشم -یک علت خوب برای این کار پیاده‌سازی بهتری از HashMap است- می‌بایست آرایه‌ای از ارجاع‌ها (Reference) داشته باشم. هر کدام از این ارجاع‌ها به گره‌هایی اشاره می‌کنند که ابتدای یک زنجیره را نشان می‌دهند. هرکدام از این زنجیره‌ها، مربوط به یک Bucket در داخل HashMap هستند. اگر می‌توانستم از مکان شروع هر کدام از Bucketها، یک ساختار آرایه‌ پیوسته داشته باشم، کارایی خیلی بهتر بود.این‌ها چیزهایی هستند که در JDK استاندارد وجود ندارند. در واقع JDK کاملاً برای تولید مداوم خطاهای نهان‌گاه (Cache Miss) طراحی شده است. در مقابل ساختار Dictionary در #C با یک چینش (Layout) بسیار مناسب در حافظه پیاده‌سازی شده است. من کارایی را برای مجموعه داده‌هایی بیش از 2 گیگابایت در .NET و جاوا اندازه گرفته‌ام و .NET حداقل 10 برابر سریع‌تر است.مثال‌های زیادی دیگری هم وجود دارد. ما به تغییرات زیاد دیگری هم در جاوا نیاز داریم. بیشتر اوقات ما از انواع اولیه (Primitive) به عنوان کلید استفاده می‌کنیم، مثلاً long یا integer. اگر از آدرس‌دهی باز (Open Addressing) و کاوش خطی (Linear Probing) در HashMap ها استفاده کنیم، کارایی به مراتب بیشتری خواهیم داشت، چون با hash کردن، مستقیماً به یک مکان رفته و به صورت خطی در حافظه حرکت می‌کنیم. این فقط یک مورد است، می‌توانم در مورد درخت‌ها هم بگویم.افراد عمدتاً درخت‌های دودویی طراحی می‌کنند. در صورتی که باید درخت‌های nتایی طراحی کنیم که به بلاک‌هایی اشاره می‌کنند که تعدادی گره دارند و هر گره چند فرزند دارد. می‌بایست روش‌هایی مشابه آن‌چه در دیسک‌ها برای توسعه‌ی پایگاه‌های داده به کار می‌روند را در ذخیره‌سازی ساختارهای خود در حافظه نیز به کار ببریم. بسیاری از ساختارهایی که در زبان‌های متداول از آن‌ها استفاده می‌کنیم با این طرز فکر طراحی نشده‌اند.مسئله از این هم فراتر می‌رود. کسانی که کتابخانه‌ی مجموعه‌ها (Collection) را در جاوا توسعه می‌دهند، در جاهایی که ثوابت و ضرایبی وجود دارد توضیحاتی در کد قرار داده‌اند که می‌توانید آن را بخوانید. این توضیحات می‌گویند که این مقادیر می‌بایست به طور مرتب بر اساس اندازه‌گیری‌ها بازبینی شوند. کدها خیلی سال‌ پیش نوشته شده‌اند و طبق اطلاعاتی که من دارم، این مقادیر هرگز به روز رسانی نشده‌اند.یک سؤال دیگر در رابطه با کتابخانه‌ها دارم. در یکی از کنفرانس‌های سانفرانسیسکو در مورد تنظیم کارایی صحبت می‌کردید و بر هزینه‌ی بالای کپی کردن اطلاعات تأکید داشتید و اینکه کارایی برنامه‌ها عمدتاً تحت تأثیر یک کتابخانه‌ی خارجی (Third Party) قرار می‌گیرد. مثلاً یک پیاده‌سازی از JDBC یا Message Queuing که در آن نسخه‌های غیرضروری از اطلاعات نگه‌داری می‌شود. زمانی که سیستمی را توسعه می‌دهید و گلوگاه شما در یک کتابخانه‌ی خارجی است چه کار می‌کنید؟این یک چالش جالب است. در بهترین حالت می‌توانید از کتابخانه‌ی دیگری استفاده کنید، اما همیشه نمی‌شود این کار را کرد. فکر می‌کنم اکثر کتابخانه‌ها بعداً به کتابخانه تبدیل شده‌اند (از ابتدا تصمیم به توسعه‌ی کتابخانه نبوده است). JDBC مثال خیلی خوبی است که در طول زمان بهبود پیدا کرده اما هنوز مشکلاتی دارد. مثلاً هنوز کتابخانه‌های JDBC که Non-blocking و ناهمگام (Asynchronous) باشند، وجود ندارند در حالی که باید چنین کتابخانه‌هایی وجود داشته باشد. این مسئله در طراحی‌های فعلی لحاظ نشده است. اگر به گذشته نگاه کنیم می‌بینیم که کد همیشه توسط چند تیم نوشته شده است و بافرها بین لایه‌های مختلف و متعدد جابجا می‌شوند و به همین علت کارایی پایینی دارند. گاهی اوقات این الگوها از C گرفته شده است که تبادل اطلاعات توسط اشاره‌گرها انجام می‌شود، اما در جاوا عمدتاً این‌طور نیست. چون قسمت‌های زیادی از کد برای کار با بخشی از یک آرایه طراحی نشده است، از کپی کردن استفاده شده است. خیلی زیاد به این موارد بر می‌خورید. در جاوا حتی اگر به کد برنامه‌ها دسترسی نداشته باشید می‌توانید بایت کد را به کد تبدیل کرده و کارایی آن را بررسی کنید و این مشکلات را ببینید. در برخی موارد من مجبور شدم کتابخانه‌ها را Decompile کرده، مشکلات را در برخی نقاط حل کنم و مشکل را به اطلاع تولید کننده برسانم. یا در برخی موارد دیگر پیاده‌سازی مشتری را به طور کامل تغییر دهم.دوست دارم کمی در مورد پردازش چندهسته‌ای صحبت کنیم. یک مقاله یا نقل قول هست که می‌گوید: &quot;دیگر از ناهار مجانی خبری نیست&quot; (The free lunch is over). منظور گوینده از این جمله چیست؟فکر می‌کنم شما به مقاله‌ی معروف هرب ساتر اشاره می‌کنید. من حوالی سال ٢٠٠٧-٢٠٠٨ آن را خواندم. منظور هِرب این بود که ما در فرایند کوچک‌تر کردن اندازه‌ی پردازنده‌ها به نقطه‌ای رسیده‌ایم که دما آن‌قدر زیاد شده که دیگر نمی‌توان سرعت ساعت (Clock Speed) را افزایش داد. گویی در طول سال‌های اخیر از یک وعده‌ی ناهار مجانی استفاده می‌کردیم که در آن هر ١٨ ماه، سرعت پردازنده‌هایمان در نتیجه‌ی افزایش سرعت ساعت و بهبود فرآیند تولید، دو برابر می‌شد.ادامه‌ی این روند و افزایش سرعت پردازنده‌ها به بیش از ٤ گیگاهرتز، با توجه به میزان گرمای تولید شده، خیلی مشکل است. بنابراین پردازنده‌ها سریع‌تر نمی‌شوند، در حقیقت سریع‌تر می‌شوند اما رشد آن به شدت کاهش پیدا کرده است. چون سرعت ساعت تقریباً تغییر نکرده و در عوض پردازنده‌ها هوشمندتر می‌شوند، سیستم‌های نهان‌گاه هوشمندتر می‌شوند.پردازنده‌ها به خودی خود محدودیت‌های سیستم ما نیستند. اگر اکثر سیستم‌ها را بررسی و اندازه‌گیری کنید متوجه می‌شوید که پردازنده‌ها در اکثر مواقع بیکار هستند و اطلاعات با سرعت کافی به آن‌ها نمی‌رسد. مسئله‌ی اصلی اینجاست: «چطور داده‌ها و دستورالعمل‌ها را به پردازنده با سرعت کافی برسانیم؟» در اینجاست که نقش زیر سیستم‌های حافظه، شناخت ساختار سلسله مراتبی آن‌ها، غیر یکنواخت شدن (Non uniform) و نحوه‌ی کار کردن آن اهمیت پیدا می‌کند.ممکن است به اصطلاح NUMA (یا Non-Uniform Memory Architecture) برخورد کرده باشید. من به بسیاری از افراد بر می‌خورم که یک سرور دارای چند گره خریداری می‌کنند و متوجه نیستند که حافظه به هر کدام از آن گره‌ها متصل شده است. فرض کنید یک سرور با دو گره دارید. یک سوکت وجود دارد که حافظه به آن متصل شده است. سوکت دیگری نیز در کامپیوتری که حافظه به آن متصل شده است وجود دارد. این دو سوکت توسط یک مدار اتصال با سرعت بالا به یکدیگر متصل شده‌اند. زمان پیمایش از یک طرف به طرف دیگر این مدار اتصال ٢٠ نانو ثانیه است، بنابراین رفت و برگشت حدود ٤٠ نانو ثانیه است. اگر من از سوکت یک پردازنده به حافظه‌ی پردازنده‌ی دیگر دسترسی پیدا کنم، ٤٠ نانوثانیه زمان صرف خواهم کرد و مهم نیست اطلاعات در نهان‌گاه است یا در حافظه یا جای دیگر. خیلی مواقع با در نظر گرفتن چنین مواردی می‌توان به افزایش چشم‌گیر در سرعت دست یافت. اگر برنامه‌ی من که ممکن است یک برنامه‌ی C یا جاوا یا هر چیز دیگر باشد، منابع کافی از قبیل حافظه و تعداد کافی هسته‌های پردازنده را برای اجرا در اختیار داشته باشد، می‌تواند تا سه برابر سریع‌تر عمل کند اما این در صورتی است که برنامه این منابع را روی یک گره در اختیار داشته باشد، نه اینکه روی چند سیستم پخش شده باشد (که رفتار پیش‌فرض سیستم عامل است).در گذشته اگر می‌خواستید یک سیستم بزرگ، با حافظه یا تعداد هسته‌های زیاد بخرید به شرکت‌های بزرگ مثل IBM، Sun یا HP مراجعه می‌کردید و آن‌ها در مورد نرم‌افزارها، سخت‌افزارها و کاربردهای مورد نیاز شما از شما سوال می‌کردند تا شما محصول درست را خریداری کنید. اما امروز شما خودتان این کارها را انجام می‌دهید. با مراجعه به سایت شرکت فروشنده و چند کلیک، محصول به شما تحویل می‌شود. مشکل اینجاست که افراد فکر می‌کنند هر چه بیشتر، بهتر: سوکت‌های بیشتر، حافظه‌ی بیشتر، چیزهای بیشتر روی کامپیوتر. در صورتی که زمانی که تعداد سوکت‌های یک کامپیوتر بیشتر می‌شود به این معنی است که هزینه‌ی رفت و آمد میان گره‌ها افزایش پیدا می‌کند و تأخیر زیادی به دسترسی‌های حافظه تحمیل می‌شود. در نتیجه با اینکه شما هزینه‌ی بیشتری کردید سرعت برنامه کاهش پیدا می‌کند. علت این مسئله کمبود درک مکانیکی از سخت‌افزاری است که استفاده می‌کنیم.آیا درست است که بگوییم سرعت برنامه با استفاده از n هسته‌ی پردازنده، n برابر نمی‌شود؟به نظرم خیلی درست است. اگر اکثر سیستم‌ها را بررسی کنید متوجه می‌شوید که بیشتر اوقات هسته‌های پردازنده بیکار هستند. در واقع یک یا دو هسته ١٠٠% مشغول هستند و مابقی بیکارند. علت این است که طراحی برنامه دارای نقاط ازدحام (Contention Point) است. نقطه‌ی ازدحام به این معنی است که گلوگاهی وجود دارد و همه چیز می‌بایست از آن عبور کند. این مشکل ممکن است فراتر از نرم‌افزار باشد، ممکن است مربوط به سیستم زمان اجرا باشد.مثلاً اگر در حال استفاده از سیستم زمان اجرای جاوا مقدار زیادی حافظه بگیرید و لازم شود Garbage Collector احضار شود، باید وضعیت تمامی نخ‌ها (Thread) ذخیره شده و متوقف شود تا Garbage Collector بتواند کارش را انجام دهد. ذخیره کردن وضعیت نخ‌ها به معنی عدم پیشرفت برنامه و بیکار ماندن هسته‌هاست. زمانی که می‌خواهید برای متوقف کردن تمامی نخ‌ها، وضعیت آن‌ها را ذخیره کنید، ممکن است یک نخ به سرعت ذخیره شده و ذخیره‌سازی نخ دیگر به دلایلی مثل نگه‌داری آرایه‌ها یا کپی کردن مقادیر حافظه، زمان زیادی بگیرد. در این وضعیت، تا کارها بصورت ١٠٠% به پایان نرسد، برنامه‌ی شما پیشرفتی نخواهد نداشت یعنی تا متوقف شدن همه نخ‌ها و ادامه کارهای JVM از قبیل Garbage Collection، بارگذاری کلاس‌ها، بهینه‌سازی‌ها و خیلی کارهای دیگر. این فقط در مورد جاوا نیست، هر محیط مدیریت شده‌ در زمان اجرای (Managed Runtime) دیگری مثل PHP یا Python هم چنین است. علت این است که از پیش در مورد این مشکلات فکر نشده است. در نتیجه محدودیت‌ها و گلوگاه‌هایی در سیستم زمان اجرا داریم و برنامه‌ها در آن نقاط خطی اجرا می‌شوند و کارمان پیشرفتی نخواهد داشت.بحث JVM را مطرح کردید، دوست دارم که در مورد آن صحبت کنیم. اما می‌خواهم اول در مورد دو مفهوم اصلی در توان عملیاتی سیستم‌ها صحبت کنید: قانون Amdahl و قانون Little.بله، فکر می‌کنم همه افرادی که در ارتباط با سیستم‌های بزرگ با نیازمندی‌های پیشرفته کارایی کار می‌کنند، می‌بایست همواره درک روشنی از این دو قانون داشته باشند.قانون Amdahl محدودیت مقیاس‌پذیری هر الگوریتمی را با اضافه کردن تعداد هسته‌های بیشتر به زیبایی توضیح می‌دهد. برای مثال اگر الگوریتم من ٩٥% موازی باشد، اما ٥% آن می‌بایست به صورت پشت‌سرهم اجرا شود، نمی‌توان بیش از ٢٠ هسته در اختیار آن قرار داد. هر چه تعداد بیشتری هسته در اختیار آن قرار دهید، اثر آن ٥% از کد بیشتر می‌شود، تا جایی که برنامه دیگر سریع‌تر نخواهد شد. تا زمانی که از پردازنده‌های ٢ یا ٤ هسته‌ای استفاده می‌کنید، این موارد در بیشتر مواقع از شما پنهان است، اما زمانی که تعداد هسته‌ها به ١٦، ٣٢ یا ٦٤ هسته افزایش پیدا کند، خیلی سریع این مسئله نمود پیدا می‌کند. اگر در الگوریتم‌هایتان، چنین نقاطی (کدی که قابل موازی سازی نباشد) وجود داشته باشد، از قانون Amdahl گریزی نیست و مقیاس‌پذیری الگوریتم شما اساساً محدود است، حتی اگر درصد ناچیزی از کد باشد. ممکن است افراد برخی جاها این مسئله را فراموش کنند یا متوجه آن نشوند، مثلاً اگر در نرم‌افزارتان یک نهان‌گاه (Cache) داشته باشید که دسترسی به آن، [نیاز به] قفل (Lock) داشته باشد همه‌ی دسترسی‌ها به این نها‌ن‌گاه نوبتی خواهد بود. ممکن است فکر کنید که اضافه کردن این نهان‌گاه کارایی را بهبود داده است اما در حقیقت آن را بدتر کرده است.این توصیف قانون Amdahl و تأثیر مؤلفه‌های غیرموازی در ظرفیت بالقوه‌ی افزایش کارایی یک برنامه است. قانون Amdahl در کنار قانون Little قرار می‌گیرد. قانون Little نظریه صف‌ها را شرح می‌دهد که در نقاط غیرموازی کد رخ می‌دهد. زمانی که چنین نقاطی در کد داشته باشید، تنها یک نفر در آن واحد قادر به استفاده از آن خواهد بود و در نتیجه یک صف تشکیل می‌شود. زمانی که صف در سیستم شما تشکیل شود، تأثیر آن را در تأخیر عملیات می‌بینید: تشکیل صف برابر است با افزایش تأخیر. چون صف‌های شما محدود نیستند، این تأخیر می‌تواند به صورت نامحدود افزایش پیدا کند و حتی بدتر از آن باعث مصرف زیاد حافظه شود.صف‌ها در همه جا حضور دارند، چه افراد متوجه باشند، چه نباشند. هر جا که Semaphore، قفل یا چیزی شبیه به این‌ها وجود دارد، صف هم وجود دارد. این صف‌ها نامحدودند، و ممکن است تا جایی رشد کنند که در سیستم نهان‌گاه جا نشوند و به اجبار در حافظه ذخیره شوند. در نتیجه الگوریتم نهان‌گاه که سعی داشت اقلامی که اخیراً استفاده شده بودند را در نهان‌گاه نگه‌دارد، از این به بعد دچار خطاهای مکرر نهان‌گاه می‌شود و سیستم به سرعت از بین می‌رود. بنابراین اگر صف‌های نامحدود در سیستم شما وجود دارد، دیر یا زود شاهد یک حادثه خواهید بود.یکی از چیزهایی که شما درباره‌ی آن می‌نویسید، مسئله‌ی تحت تأثیر قرار گرفتن کارایی برنامه‌های چند نخی (Multithread) به علت هزینه‌ی هماهنگ‌سازی و تعویض میان نخ‌ها به جای انجام دادن کار مفید است. چرا این‌طور می‌شود؟فکر می‌کنم این به‌خاطر تغییراتی باشد که در سخت‌افزار و توسعه‌ی آن رخ داده است. ما برای مدتی طولانی با سیستم‌های تک‌پردازنده‌ کار می‌کردیم و اکنون پردازنده‌های چند هسته‌ای را داریم. برای مثال اگر من یک سیستم تک‌پردازنده داشتم و یک کد جاوا را روی آن اجرا می‌کردم ماشین مجازی جاوا تمامی قفل‌ها را حذف می‌کرد. چرا که در سیستم‌های تک‌پردازنده‌ای نیازی به آن نداشت (می‌شد با تغییر زمانبندی‌ها از استفاده از قفل صرف نظر کرد). اما در دنیای چند‌هسته‌ای امروز مجبوریم که قفل‌ها را به کار ببریم.یکی از مشکلات در چنین کارهایی خبر دادن اتمام یک کار به سایر نخ‌هاست. یک مثال ساده، قرار دادن و برداشتن اطلاعات در یک صف است. اگر بخواهم از یک صف، اطلاعاتی را بردارم و صف خالی باشد، و اگر عملیات خواندن به صورت مسدود کننده (Blocking) باشد، باید صبر کنم. یعنی درخواستی به سیستم عامل بفرستم تا مرا به حالت تعلیق در آورد. زمانی که می‌خواهم اطلاعاتی را در صف قرار دهم نیز می‌بایست به سیستم عامل خبر دهم که چیزی در صف قرار گرفته است تا نخِ دیگر بتواند کارش را ادامه دهد. تمامی این کارها (فراخوانی‌های سیستم عاملی برای خبر دادن به سایر نخ‌ها) هزینه‌ی بسیار بالایی دارد.در یک سیستم عامل امروزی زمان این عملیات می‌تواند چیزی بین ٣ الی ١٦ میلی ثانیه باشد و اغلب این زمان بسیار بیشتر از کاری است که سعی در انجام آن داریم. بنابراین طراحی برنامه‌ها به شکل چند نخی و به این شکل استفاده از قفل‌ها و متغیرهای شرطی می‌تواند به شدت کارایی برنامه را تحت تأثیر قرار دهد و بهتر است که برنامه را به صورت تک نخی بنویسیم.یکی از چیزهایی که من افراد را به آن تشویق می‌کنم این است که ببینند آیا می‌توان منطق کسب و کار را با یک نخ به انجام رساند؟ و اغلب اوقات این امکان‌پذیر است. تنها مشکل این است که نمی‌توانید از فراخوانی‌های مسدود کننده استفاده کنید. خیلی از افراد نرم‌افزار را به گونه‌ای طراحی می‌کنند که به صورت همگام (Synchronous) و با تکیه به فراخوانی‌های مسدود کننده کار می‌کنند. در نتیجه نمی‌توان آن را روی یک نخ اجرا کرد و مقیاس‌پذیر نیست. در اینجا لازم است الگوی برنامه را تغییر داده و از فراخوانی‌های ناهمگام استفاده شود. پس از آن می‌توان برنامه را بدون نیاز به درنظر گرفتن مسائل همزمانی بر روی یک نخ اجرا کرد.شما یکی از کسانی هستید که در پروژه‌ی متن‌باز Disruptor که برخی از مفاهیمی که در مورد آن صحبت کردید را در بر می‌گیرد، همکاری می‌کنید. کمی در مورد طرز فکر پشت این پروژه و این که چگونه مشکلاتی که در مورد آن صحبت کردیم را حل می‌کند به ما می‌گویید؟بخشی از کارهایی که من در گذشته انجام داده‌ام شامل توسعه نرم‌افزارهای با کارایی بالا و قابلیت مقیاس‌پذیری و سیستم‌های مبادلات مالی است. یکی از چالش‌ها در چنین محیط‌هایی توان عملیاتی بالا است: ده‌ها یا صدها هزار عملیات که می‌بایست در یک ثانیه انجام شوند و در کنار آن نیاز به تأخیر خیلی پایین و قابل پیش‌بینی داریم. برای انجام این کار به طراحی‌های زیادی نگاه کردیم. Disruptor در نتیجه‌ی فشار برخی از عوامل که طراحی را به سمت آن می‌کشاندند، به شکل کنونی درآمد. این‌طور نبود که در یک گوشه بنشینیم و Disruptor را تصور کنیم بلکه با توجه به نیازمندی‌ها و محدودیت‌های ذاتی مسئله که به ما تحمیل می‌شد به آن رسیدیم.در طراحی هر سیستم مبادله‌ای یکی از کارهایی که سعی در انجام آن دارید داشتن میزان بالای قابلیت جبران خطا (Resilient) است. برای جبران خطا، می‌بایست داده‌ها را روی دیسک ذخیره کنید و آن را روی سایر گره‌ها تکرار (Replicate) کنید. باید داده‌های دریافتی از شبکه را رمزگشایی و آماده‌سازی کنید. در عین حال منطق کسب و کار برنامه می‌بایست ادامه یابد. کارهای زیادی وجود دارد که می‌تواند در صورت همگام‌سازی، کاملاً مستقل از هم انجام شود. البته منظورم همگام‌سازی با قفل نیست بلکه منظور همگام‌سازی از طریق زمانبندی اجرای هر کار در طول زمان است.بعنوان مثال، فرض کنید من اطلاعات را در دیسک می‌نویسم و آن را در یک یا چند گره‌ی دیگر تکرار می‌کنم، و همزمان آن داده‌ها را برای انجام عملیات مربوط به کسب و کار نیز آماده می‌کنم. مانند سایر مسائل پردازشی، می‌خواهم که این کار را در حداقل زمان، با حداقل سربار انجام دهم. طراحی Disruptor بر اساس درک مکانیکی بوده است: چطور می‌توانم تمامی این نخ‌ها را به صورت موازی اجرا کنم؟ چطور می‌شود با یک هزینه‌ی کم، کارها را هماهنگ کرد و وقوع رخدادها را به نخ‌ها اطلاع داد؟ تمامی این‌ها به وسیله‌ی مفاهیمی به نام الگوریتم‌های بدون قفل انجام می‌شود.علاوه بر این طراحی به گونه‌ای است که بار Garbage Collection را از دوش ماشین جاوا بر می‌دارد. در محیط‌هایی که اعوجاج پایین (Low Jitter) مد نظر است (Jitter به معنای اختلاف و واریانس مشاهده شده در تأخیرها است - مترجم) ، نمی‌خواهیم زباله‌های حافظه‌ای تولید کنیم. زباله‌های بیشتر موجب فراخوانی Garbage Collector می‌شوند. بسیاری از ماشین‌ها مجازی فعلی مشکلاتی با Concurrent Collection ها دارند و می‌بایست تمامی نخ‌های را برای انجام عملیات خود متوقف کنند. بنابراین نمی‌توانند در زمان کوتاه پاسخگو باشند. طراحی Disruptor به گونه‌ای است که حافظه‌ی مورد نیاز را از پیش تخصیص داده و چند بار از آن استفاده می‌کند. در نتیجه در صورت وجود تعداد کافی هسته برای اجرای کارهایی که می‌بایست در حال اجرا باشند، می‌توانید به توان عملیاتی بالا و تأخیر پایین دست یابید.من گاهی اوقات می‌بینم که افراد هنگام استفاده از Disruptor بیش از تعداد هسته‌هایی که در اختیار دارند، نخ اجرا می‌کنند و این استفاده‌ی درستی از Disruptor نیست. بنابراین اگر شما سیستمی ١٦ هسته‌ای دارید، اما می‌خواهید 100 نخ را اجرا کنید، Disruptor برای این کار طراحی نشده است. اما اگر ١٦ هسته دارید و به ١٠ نخ احتیاج دارید، Disruptor بسیار خوب عمل می‌کند و توان عملیاتی بالایی خواهید داشت.مارتین، چرا بافر حلقوی؟بافر حلقوی از این نظر جالب است که با درک مکانیکی هماهنگی دارد. در یک بافر حلقوی به طور مکرر به خانه‌های یک نقطه از حافظه دسترسی پیدا می‌کنید. پیش‌تر اشاره کردم که سخت‌افزار فرض‌هایی را در مورد آخرین داده‌های استفاده شده و دسترسی قابل پیش‌بینی در نظر می‌گیرد. هنگامی که از یک بافر حلقوی استفاده می‌کنم، دسترسی‌های من به حافظه قابل پیش‌بینی است و پیش‌واکشی‌های سخت‌افزاری در اینجا به کار می‌آیند. بنابراین اطلاعات قبل از آن‌که من به آن نیاز داشته باشم در پردازنده (نهان‌گاه) قرار می‌گیرد. این روشی است که در اکثر سخت‌افزارها استفاده می‌شود. بخشی از جذابیت‌های مطالعه‌ی سخت‌افزار این است که چیزهای زیادی در مورد ساختار داده‌هایی که هم در سخت‌افزار و هم در نرم‌افزار بسیار خوب کار می‌کنند، یاد می‌گیرید. اگر به نحوه‌ی کارکرد اکثر کارت‌های شبکه، درایورها و توصیفات طراحی نگاه کنید، می‌بینید که همه از بافرهای حلقوی استفاده می‌کنند، در حالی که نرم‌افزارهای امروزی عموماً از آن استفاده نمی‌کنند.موضوع دیگری که چند لحظه پیش به آن اشاره کردید و در نوشته‌های شما هم دیده می‌شود، مفهوم الگوریتم‌های بدون قفل است. به ما بگویید بدون قفل یعنی چه و چرا به آن احتیاج داریم؟بله، همان‌طور که قبلاً هم گفتم، هر وقت که وارد ناحیه‌ی بحرانی میان دو نخ می‌شویم، می‌خواهیم داده‌هایی را برداریم، یا اینکه نخ دیگری را از یک تغییر آگاه کنیم، اغلب این کارها با استفاده از قفل‌ها یا متغیرهای شرطی انجام می‌شود. متغیرهای شرطی ممکن است به صورت Notify در جاوا، یا سینگال در Java EE، یا Mutex در Posix ظاهر شود. همه‌ی این‌ها در نهایت به چیزی تبدیل می‌شوند که یک ناحیه‌ی بحرانی یا امکان سیگنال دادن را فراهم می‌کند. هر زمان که این اتفاق می‌افتد، اگر قفل شما دچار ازدحام شده باشد، لازم است با سیگنال دادن، سایرین را آگاه کنید و مجبورید هسته‌ی سیستم‌عامل را درگیر کنید. بنابراین فراخوانی‌های سیستم‌عاملی انجام می‌دهید که کاری با سربار به شدت بالاست. مثل این است که از دولت کمک بخواهید و آن‌ها نیز از وکلا برای کمک شما استفاده کنند. این رویه کار خواهد کرد، امنیت دارد، و کارآمد است اما هزینه‌ی آن به شدت بالاست. اجرای چنین دستور‌العمل‌هایی میلیون‌ها چرخه به طول می‌انجامند.عارضه‌ی جانبی دیگری که از آن اجتناب می‌شود این است که زمانی که از الگوریتم‌های بدون قفل استفاده می‌کنید به این معنی است که شما شخص سومی (Third Party) را وارد کار نمی‌کنید. در این الگوریتم‌ها بر سر یک سری گام‌ها برای هماهنگ‌سازی به توافق می‌رسید و تغییرات را با نمایان شدن حافظه به یک ترتیب خاص به اطلاع سایرین می‌رسد. برای این کار لازم است کنترل ترتیب اعمال تغییرات در نقاط مختلف الگوریتم را به دست بگیرید.فرض کنید که من و شما می‌خواهیم برای انجام یک کار تعامل کنیم. من و شما هر کدام می‌توانیم بخشی از کار را انجام دهیم و توافق کنیم در چه نقاطی اطلاعاتمان را به اشتراک می‌گذاریم و تعامل می‌کنیم. پروتکلی برای این کار تعریف می‌کنیم و نقاط مربوطه را در پروتکل مشخص کنیم. الگوریتم‌های بدون قفل به ما اجازه چنین کارهایی را می‌دهند. بنابراین با به کارگیری چنین روش‌هایی در فضای کاربری (User Space) یک برنامه، نخ‌ها می‌توانند بدون دخیل کردن هسته‌ی سیستم‌عامل با هم تعامل کنند.این روش‌ها عموماً چگونگی نمایان کردن حافظه به یک ترتیب خاص را نشان می‌دهند زیرا اکثر کامپایلرها و پردازنده‌ها برای دستیابی به کارایی بیشتر سعی می‌کنند خیلی کارها را خارج از ترتیب انجام دهند البته تا جایی که به «تصور» اجرای هر نخ به ترتیب تعیین شده‌ی آن خدشه‌ای وارد نشود. لازم نیست حتماً این ترتیب رعایت شود.مثال خوبی از این مورد این است که حلقه‌ای داریم که درون آن تغییرات و محاسباتی روی داده‌ها انجام می‌دهیم و در عین حال لازم است که شمارنده‌ی حلقه نیز افزایش پیدا کند. آیا مهم است که در ابتدا، میانه، یا انتهای حلقه شمارنده را افزایش دهیم؟ تنها چیزی که اهمیت دارد این است که این کار قبل از بررسی شرط حلقه انجام شود و کامپایلرها و پردازنده‌ها برای افزایش کارایی این کارها را انجام می‌دهند.چنین چیزهایی زمانی که با نخ‌ها کار می‌کنیم اهمیت پیدا می‌کنند. چون اگر نمایان شدن، خارج از ترتیب رخ دهد در هماهنگی با سایر نخ‌ها دچار مشکل می‌شویم. برای این کار باید راهنمایی‌ها و دستورالعمل‌هایی را در کد قرار دهیم تا نشان دهیم برخی کارها باید به ترتیب خاصی انجام شوند (چیزهایی که در معرض دید سایر نخ‌ها هستند). بنابراین بخشی از کار تعیین این ترتیب تغییرات در حافظه است و به نظر من مهم‌ترین نکته است.نکته‌ی مهم بعدی این است که برخی از کارها که ممکن است دارای چند مرحله باشند باید به صورت Atomic اجرا شوند. فرض کنید چند نخ داریم که هر کدام پایان کارشان را با افزایش یک شمارنده نشان می‌دهند. اگر مراقبت نشود ممکن است برخی از شمارش‌ها گم شوند (مثلاً دو نخ شمارنده را با مقدار ١٠ دیده و همزمان آن را به ١١ افزایش می‌دهند). کاری که باید برای حل این مشکل انجام دهید استفاده از روش‌های مقداردهی و معاوضه همروند (Concurrent Set and Concurrent Swap) است. در این روش‌ها مقدار متغیر به صورت شرطی تغییر می‌کند، یعنی زمانی می‌توانم یک متغیر را به‌روز رسانی کنم که در وضعیتی باشد که من از آن آگاهم. مثلاً متغیری را می‌خوانم که مقدارش ١٠  است، آن را افزایش می‌دهم، اما زمانی می‌توانم مقدار آن را در حافظه بنویسم که مقدارش هنوز ١٠  باشد اگر این‌طور نباشد عملیات شکست خواهد خورد و باید دوباره امتحان کنم.الگوریتم‌های بدون قفل این دو کار اصلی را انجام می‌دهند: اطمینان از این‌که کارها به ترتیب درست انجام شوند، و این‌که برخی کارها به صورت Atomic انجام می‌شوند، تا بتوان هماهنگ بود. با این دو روش می‌توان اکثر الگوریتم‌هایی را که نیاز به هماهنگی دارند، پیاده‌سازی کرد. اگر کار دارای چند مرحله است یک ماشین حالت می‌سازیم و گام‌ها را یک به یک انجام می‌دهیم.تا به حال چند بار موضوع Garbage Collection در جاوا را مطرح کرده‌اید. آیا فکر می‌کنید تکامل زبان‌ها از malloc و free به Garbage Collection باعث بهبود شده یا ترکیبی از مزایا و معایب است؟سوال جالبی است. اگر موارد کاربرد خیلی خاصی دارید، می‌توانید تخصیص و آزادسازی حافظه را خودتان خیلی کاراتر از سایر روش‌های مدیریت حافظه‌ی عام‌منظوره (مثل Garbage Collection) انجام دهید. یک مثال از این،‌ استفاده از بافر حلقوی برای تبادل اطلاعات میان تولیدکننده و مصرف‌کننده (Producer/Consumer) است. خیلی از مسائل این‌طور نیستند، در واقع چندین تولیدکننده و چندین مصرف‌کننده وجود دارد، یا اینکه چند نخ درگیر هستند. در محیط چند نخی مدیریت حافظه دشوار است. ممکن است است بگویید از شمارش مراجع (Reference Counting) استفاده می‌کنیم اما برای شمارش مراجع می‌بایست از روش‌هایی استفاده کنیم که پیش‌تر در مورد آن‌ها صحبت کردیم (قفل‌گذاری و نواحی بحرانی) که هزینه‌ی زیادی دارند. بنابراین مدیریت حافظه با این روش احتمالاً یکی از کندترین روش‌هاست. Garbage Collector ها با جمع‌آوری همروند زباله‌ها و ردگیری حافظه‌های بدون استفاده، بسیاری از مشکلات ما را حل می‌کنند و جلوی بسیاری از خطاها را می‌گیرند.من مقدار زیادی برنامه‌نویسی در زبان‌های سطح پایین و سطح بالا با امکان Garbage Collection انجام داده‌ام و وقتی که شما Garbage Collection دارید قطعاً نگرانی برای دسته‌ای از خطاها را ندارید. می‌توانید به راحتی به حافظه دسترسی پیدا کنید و لازم نیست در مورد دسترسی‌های غیر مجاز و بررسی شرایط مرزی نگران باشید، اما این‌ها هزینه دارد. مسئله‌ی جالب این است که از نظر تئوری Garbage Collection می‌تواند کارآمدترین روش عام‌منظوره تخصیص و آزادسازی حافظه باشد. مشکل اینجاست که اکثر Garbage Collector ها با نگاه ساده انگارانه‌ای نوشته شده‌اند. آن‌ها انتظار دارند که در برخی مراحل کارشان، همه چیز متوقف شود. این باعث می‌شود که بخشی از برنامه به صورت غیر موازی اجرا شده و قانون Amdahl بر آن حاکم شود و در نتیجه مقیاس‌پذیری محدود شود. البته Garbage Collector هایی هم وجود دارند که واقعاً به صورت همروند عمل می‌کنند و کارایی فوق‌العاده‌ای دارند. یک مثال خوب C4 محصول شرکت Azul است. اما این تنها محصول تجاری است که من می‌شناسم و می‌تواند توان عملیاتی بالایی ارائه دهد و به سادگی بدون متوقف کردن برنامه قابل استفاده باشد.با توجه به قانون Amdahl، آیا محدودیتی روی تعداد هسته‌های قابل استفاده توسط ماشین مجازی جاوا وجود دارد؟ البته با این فرض که در سایر قسمت‌های برنامه گلوگاهی وجود نداشته باشد.این وابسته به این است که چه مقدار تخصیص حافظه دارید و چه کارهایی در حال انجام است. بردن نخ‌ها به وضعیت امن (Safe Point)، یکی از بزرگ‌ترین مشکلات ماشین‌های مجازی امروزی است. این مسئله در برخی موارد مشکل‌ساز می‌شود. برای هرکاری که بخواهد باعث متوقف شدن کامل برنامه (Stop The World) شود لازم است ابتدا وضعیت تمامی نخ‌ها را به حالت امن ببریم. در این نقطه است که حالا می‌توانیم برنامه را متوقف کنیم و می‌توانیم چرخه Garbage Collection را اجرا کنیم، می‌توانیم کلاس‌ها را تخلیه کنیم (Class Unloading)، می‌توانیم بهینه‌سازی‌ها را انجام دهیم و خیلی کارهای دیگر. اما قبل از همه این کارها لازم است که همه نخ‌ها را به وضعیت امن برسانیم. اینها مسائلی هستند که می‌بایست بصورت ترتیبی اجرا شوند.برای اینکه این مسأله روشن‌تر شود می‌توانیم به این موضوع اشاره کنیم که خیلی از افراد زمان Garbage Collection را در برنامه‌های خود اندازه‌گیری می‌کنند اما یکی از چیزهای دیگری که می‌بایست اندازه‌گیری شود، زمان توقف برنامه است، در بسیاری از موارد متوجه خواهید شد که زمان توقف برنامه به مراتب بیشتر از زمان Garbage Collection است. من اغلب در اندازه‌گیری‌ سیستم‌ها می‌بینم که متوقف کردن برنامه زمان بیشتری نسبت به انجام کار واقعی Garbage Collection دارد.فکر می‌کنید تا چه حد می‌شود با تنظیم گزینه‌ها و پارامترهای Garbage Collector ها کارایی برنامه‌های سرور را افزایش داد؟در اینجا عموماً به دو دسته از مسائل بر می‌خورم. یکی این است که شخصی با اعمال تغییرات بیشتر به سیستم ضرر رسانده است تا سود. در حقیقت بهتر بود که سیستم را با تنظیمات پیش‌فرض رها می‌کردند. مورد دیگر این است که افراد پیکربندی را به درستی انجام نداده‌اند، و برنامه‌شان را به درستی پروفایل نکرده‌اند تا میزان مورد نیاز حافظه و سایر پارامترها را بدست آورند چرا که فقط اندازه‌گیری این موارد بر اساس داده‌های واقعی، می‌تواند باعث بهبود اجرای برنامه‌هایتان شود.بزرگ‌ترین چالشی که افراد در این مسئله دارند این است که آن‌ها تست‌هایی که نمایان‌گر میزان کارایی برنامه‌هایشان باشد ندارند. آن‌ها معمولاً سعی می‌کنند به مشکلاتی که در سیستم‌های واقعی رخ می‌دهند واکنش نشان دهند و چون نظارت مناسبی روی سیستم‌ها ندارند، راهی برای ایجاد کردن مجدد مشکلات ندارند. در نتیجه نمی‌توانند تنظیمات را به درستی انجام دهند و کورکورانه و بر اساس حدس و گمان عمل می‌کنند.برای استفاده‌ی هوشمندانه‌تر از Garbage Collector افراد بر چه چیزهایی نظارت داشته باشند؟فکر می‌کنم فعال کردن ثبت وقایع (Log) مهم‌ترین چیز باشد. من یک مقاله با عنوان Garbage Collection Distilled نوشته‌ام. هدف از نوشتن این مقاله این بود که انواع مختلف Garbage Collector هایی که با ماشین مجازی جاوا ارائه می‌شوند و پارامترهای اصلی تنظیمات آن‌ها معرفی شوند. یکی از تنظیماتی که باید انجام شود فعال کردن ثبت اطلاعات وقایع است. وقتی که این اطلاعات را داشته باشید، می‌توانید از ابزارهای دیگری استفاده کنید. سربار فعال کردن آن در سیستم‌های محصول (Production System) ناچیز است و حتی متوجه آن نخواهید شد. پس از آن می‌توانید اطلاعات را برداشته و با استفاده از ابزارها، ببینید در برنامه‌های شما چه اتفاقاتی رخ داده است.پیش از این در مورد ناتوانی زبان جاوا در تعریف کردن آرایه‌ای از رکوردها (به جای آرایه‌ای از ارجاع‌ها) صحبت کردید. همچنین در مورد برخی ساختارهای خارج از Heap برای حل این مسئله صحبت کردید. ممکن است بیشتر در این مورد توضیح دهید؟اگر بتوانیم چینش قابل پیش‌بینی در حافظه داشته باشیم، خواهیم توانست کارایی پیش‌بینی شده‌ای در زیرسیستم حافظه داشته باشیم. بنابراین زبان‌های برنامه‌نویسی باید این امکانات را در اختیار ما قرار دهند. فکر نمی‌کنم این امکانی باشد که توسعه‌دهندگان هر روزه به آن نیاز داشته باشند اما فکر می‌کنم که برای طراحان زبان‌ها خیلی مهم باشد. آن‌ها باید بتوانند انواع مجموعه‌ها از قبیل نگاشت‌ها (Map)، درخت‌ها و ... را به نحوی طراحی کنند که کارایی مناسبی در کار با حافظه داشته باشد. متأسفانه زبان جاوا و بایت کد این شفافیت را به ما نمی‌دهند تا چینش حافظه را با توجه به نیاز انجام دهیم.در واقع من، در 3 موقعیت به داشتن کنترل روی چینش حافظه نیاز دارم. یکی تعریف آرایه‌ای از ساختارها یا اشیاست تا بتوانیم به طور مستقیم و با پیمایش در حافظه به عناصر دسترسی پیدا کنیم.مورد دوم این‌که گاهی نیاز دارم یک شی‌ء را در دل شیء دیگری قرار دهم. مثلاً یک صف یک سر و یک ته دارد. من می‌خواهم زمانی که به سر یا ته این صف دسترسی پیدا می‌کنم اطلاعات همانجا باشد. بنابراین باید بتوانم اشیاء کوچک را درون اشیاء بزرگتر قرار دهم. یک مثال خوب از آنها، انواع atomic int و atomic long هستند. اشیاء کوچکی که پوششی (Wrapper) روی انواع داده‌ای اولیه هستند.سومین چیزی که به آن نیاز دارم، داشتن توانایی گسترش یک چیز در زمان اجراست. این مفهوم خیلی شبیه به داشتن یک ساختار در زبان C است که آرایه‌ای با طول متغیر در انتهای خود دارد. این مورد برای چیزهایی مثل رشته‌ها (String) خیلی مفید است. اشیاء رشته مقادیری مثل hash code، طول رشته، اندیسی در آرایه و در نهایت آرایه‌ای از بایت‌ها (حروف آن رشته) را نگهداری می‌کنند. چرا باید یک شیء داشته باشیم که نماینده‌ی رشته باشد و از آنجا به نقطه‌ی دیگری ارجاع کنم که آرایه را نشان دهد؟ این آرایه باید به صورت پیوسته در انتهای شیء مورد نظر قرار گیرد تا محلی بودن (Locality) حافظه حفظ شود. ماشین جاوا از برخی ترفندها برای کار با چیزهایی مثل رشته‌ها استفاده می‌کند اما من باید بتوانم چنین کاری را برای همه‌ی ساختارها انجام دهم تا مطمئن شوم چینشی کارا دارم. باید بتوانم با علم به وجود چنین امکاناتی،‌ کتابخانه‌های خود را طراحی کنم. این تغییرات لازم نیست در سطح زبان باشد. این کار می‌تواند از طریق الگوها و نشانه‌هایی که از پیش با ماشین جاوا توافق شده است انجام شود (مثل Annotation ها). زمانی که ماشین جاوا این علامت‌ها را ببیند، کارهای لازم را انجام می‌دهد. با وجود این امکانات می‌توانیم در برخی از مجموعه‌ها و برخی الگوهای دسترسی به کارایی به مراتب بهتری دست یابیم.اگر می‌توانستید، آموزش علم کامپیوتر را برای کسانی که فارغ‌التحصیل نشده‌اند تغییر دهید، چگونه عمل می‌کردید؟به چیزهایی مثل روش‌های علمی خیلی بیشتر توجه می‌کردم. کار کردن بر اساس استدلال، اندازه‌گیری و علم، باید اساس باشد؛ همان‌طور که گرفتن مدرک در سایر رشته‌ها این‌گونه است مواردی از قبیل یادگرفتن نحوه‌ی استدلال، چگونگی دنبال کردن مطالبی که همواره تغییر می‌کنند، آگاهی از این مسئله که انسان خیلی راحت در دام پیروی از محبوبیت و مد (popularity and fashion) می‌افتد.چیزی که در رشته‌ی ما می‌توانیم از آن مطمئن باشیم تغییر است. بنابراین اگر در دانشگاه جزئیات را یاد بگیرید، خیلی زود تاریخ مصرفشان خواهد گذشت. باید چیزهایی را یاد بگیرید که در دراز مدت پایدار باشد.به نظرم مهم است که زمانی که افراد در مورد Agile صحبت می‌کنند در مورد چرخه‌ی بازخورد صحبت شود. آن‌چه که در دل Agile قرار دارد این است که طوری طراحی کنیم که چرخه‌ی بازخورد کوتاه شود. زمانی که چرخه‌ی بازخورد کوتاه باشد، تصمیمات بهتری گرفته می‌شود. در حقیقت انجام دادن غلط کارها اشکالی ندارد. چون چرخه‌ی شما کوتاه است، میزان هدر رفت هم کم است و همواره پیشرفت دارید. اما وقتی در مورد استانداردها و مراسم‌های Agile صحبت می‌کنیم از موارد اصلی باز می‌مانیم. فکر می‌کنم این چیزی است که ما در علم کامپیوتر باید یاد بگیریم: «یک چیز چطور کار می‌کند؟»در دنیای امروز افراد از دانشگاه فارغ‌التحصیل می‌شوند در حالی که هرگز با زبانی که به طور مستقیم با حافظه دسترسی دارد کار نکرده‌اند. خیلی خوب است که بتوانیم از این چیزها فاصله بگیریم اما اگر مفاهیم اساسی چگونگی کارکرد آن را ندانید، تصمیمات اشتباهی خواهید گرفت.مارتین، اگر شنوندگان بخواهند بیشتر در مورد نظرات و کارهای شما بدانند چطور این کار را انجام دهند؟وبلاگ من یکی از جاهایی است که می‌توانند از آن شروع کنند. همچنین می‌توانید در گروه درک مکانیکی در گوگل عضو شوید که گفتگوهایی خوبی در آنجا اتفاق می‌افتد. افراد زیادی داریم که موضوعات را با جزئیات بیشتری بررسی می‌کنند و در مورد نحوه‌ی کارکرد چیزها به طور اساسی صحبت می‌کنند.آیا ارائه‌ای از کنفرانس‌ها روی اینترنت وجود دارد که بخواهید شنوندگان آن‌ها را ببینند؟کارهای متفاوتی هست که من انجام دادم و امیدوارم در آینده هم انجام دهم. اگر نام من و ارائه‌هایم در infoq یا Yahoo را در گوگل جستجو کنید نقطه‌ی شروع خوبی است. برای معرفی و توضیح دادن یک موضوع به افراد معمولاً یک wiki در بلاگم قرار می‌دهم تا از آنجا شروع کرده و بیشتر مطالعه کنند. دوست دارم موضوعات جدید را به افراد معرفی کنم. قرار نیست آنجا همه چیزهایی که به آن نیاز دارند را پیدا کنند اما نقطه‌ی شروع خوبی است.مارتین، از شما خیلی متشکریم که با ما صحبت کردید.متشکرم که من را دعوت کردید.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>سید مرتضی هاشمی</author>
                <pubDate>Fri, 10 Dec 2021 16:12:47 +0330</pubDate>
            </item>
                    <item>
                <title>توسعه مبتنی بر تست (TDD)</title>
                <link>https://virgool.io/se-radio/%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D9%85%D8%A8%D8%AA%D9%86%DB%8C-%D8%A8%D8%B1-%D8%AA%D8%B3%D8%AA-tdd-g4ukwjwakeeh</link>
                <description>مطلبی که می‌خوانید ترجمه‌ قسمت ۱۵۵ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهددر این قسمت، یوهانس لینک با  لاسی کاسکلا نویسنده کتاب TDD در ارتباط با توسعه مبتنی بر تست (Test Driven Development) مصاحبه می‌کند. در این مصاحبه، مبانی TDD، منطق پشت آن و چالش‌های انجامش در محیط‌های دشوارتر بحث می‌شود.قبل از اینکه وارد مصاحبه شوم می‌خواهم که در زمینه زندگی حرفه‌ای خودت کمی برایمان صحبت کنی.من یک خوره‌ کامپیوتر هستم. برای تقریباً یک دهه در زمینه‌ای که عمدتاً برنامه‌نویسی بوده، کار می‌کرده‌ام. در ۴-۵ سال گذشته اختصاصاً با روش‌های چابک در حوزه مربی‌گری هم برای سازمان‌ها و هم در سطح تیم‌ها، کار می‌کرده‌ام اما هیچ گاه برنامه‌نویسی را کنار نگذاشته‌ام به عنوان مثال تا کنون مقدار زیادی تجربه‌های زیبای برنامه‌نویسی دونفره (Pair) داشته‌ام.هنوز هم بیشتر وقتتان را به برنامه‌نویسی می‌گذرانید؟بله. در واقع، ابتدای سال تصمیم گرفتم که به یک تیم برای مدت بیشتری بپیوندم. الان مدت ۷ ماه است که عضو یک تیم هستم.و آیا این خوب است؟ اینکه فقط کد بزنیم؟بله. فکر می‌کنم زمانش رسیده بود. در ۵ سال قبل از این، من با هر تیمی به طور ماکزیمم دو هفته کار می‌کردم و بعد جای دیگری می‌رفتم. البته ممکن بود برگردم اما این فرق می‌کند.علتی که من شما را دعوت کرده‌ام این است که شما کتابی منتشر کرده‌اید. فکر می‌کنم در سال ۲۰۰۸ بوده است.در واقع سال ۲۰۰۷.بله، یک کتاب در مورد توسعه‌ به روش مبتنی بر تست (Test Driven Development). عنوانش چه بود؟همین، مبتنی بر تستاینکه چیزی مبتنی بر چیز دیگر جلو رود تا حدی با اعتیاد به آن همراه می‌شود. آیا شما به نوعی معتاد تست هستید؟تا اندازه‌ای بله. قطعاً اگر بدون تست کار کنم، احساس ناخوشایندی دارم. بنابراین، بله می‌توان من را معتاد تست خواند.آیا شده که برخی مواقع بدون تست کار کنید؟متأسفانه هر از چند گاهی، در چنین وضعیتی قرار می‌گیرم. به عنوان مثال، در کاری که هم‌اکنون انجام می‌دهم کدهای میراثی (Legacy Code) هستند که نقاط زیادی از آن پوشش کافی تست ندارد. همچنین برخی تکنولوژی‌های استفاده‌شده، نوشتن تست را سخت کرده است. من احساس غریبی دارم. اگر با تست کار می‌کردم احساس راحتی و لذت خیلی بیشتری داشتم.روش TDD مدتی است که مطرح شده است اما هنوز افراد مختلف وقتی این لغت را استفاده می‌کنند، منظورهای مختلفی دارند. شما چطور TDD را تعریف می‌کنید؟ من اعتقاد دارم اولین بار، TDD در نوشته‌های انتشاریافته تعریف شد. TDD بیشتر به برنامه‌نویسی به روش تست اول (Test First Programming) اشاره داشت؛ ترکیبی از ایده‌های تست و ایده‌ پیاده‌سازی حداقل (ساده‌ترین چیزی که کار مورد نظر را انجام دهد) و سپس تست بعدی و پیاده‌سازی بعدی و به این شکل پیش بردن طراحی.آیا در مورد چرخه TDD فکر نمی‌کنید؟اولین تعریف TDD ترکیبی از این دو موضوع بود که: اول تست را می‌نویسید و بعد پیاده‌سازی می‌کنید و دیگر تأکید بر طراحی ناشی‌شده از آن (Emergent Design). بنابراین طراحی‌تان به شدت تحت تأثیر تست، نمو پیدا می‌کند. من برای TDD یک تعریف ساده‌تر در ذهنم دارم. قطعاً منظورم مفهوم «تست اول» هست ولی شما حتماً قبل از آنکه آغاز کنید در مورد طراحی فکر می‌کنید. شما حتماً ایده‌ای از این که کدتان را به کجا می‌خواهید ببرید دارید اما با این وجود اجازه می‌دهید که کد به شما بگوید که آن، پاسخ کار را نمی‌دهد و ممکن است به جهت‌های دیگر برویم. بنابراین تعاریف مختلفی که کم ‌و بیش از خودم هست دارم.مؤلفه‌های TDD کدامند؟ شما تا حالا، به «ابتدا تست را نوشتن» و «اجازه دادن به کد که مسیر بعدی را نشان دهد» اشاره کردید. من می‌توانم چیزهای دیگری از قبیل بازسازی (Refactoring) بعد از تست یا در حین تست را متصور شوم.بله. اساساً چرخه TDD، عبارتست از: «تست نوشتن، کد زدن و بازسازی (Refactor) کردن». این‌ها قطعاً مؤلفه‌ها هستند. این‌ها چیزهایی است که وقتی شما TDD کار می‌کنید همواره انجام می‌دهید.آیا در مورد TDD فکر می‌کنید چیزی وجود دارد که آن را به قطع، الزامی می‌کند؟بله. فکر می‌کنم وجود دارد. تحقیقات و مقالات مختلفی در مورد مؤثر بودن TDD، تأثیر TDD بر روی کیفیت کد و ... وجود دارد. اگر به آن دسته از تحقیقاتی که اظهار می‌کنند که ممکن است TDD تأثیرات منفی در کیفیت داشته باشد، نگاه کنید؛ وقتی خود نتایج واقعی را نگاه می‌کنید می‌بینید که برخی شاخص‌های شیء‌گرایی هستند که امتیاز پایین‌تری آورده‌اند. این واقعاً به علت استفاده از TDD به عنوان روش توسعه نیست بلکه به علت فقدان مهارت طراحی شیءگرا است. اساساً TDD موتوری است که یک ریتم طبیعی برای ایجاد یک طراحی شیءگرای خوب ایجاد می‌کند. مشکل این‌جا است که TDD جادویی نیست که این حس را به شما بدهد که طراحی شیء گرای خوب چیست. این یک مؤلفه فراموش‌شده یا ذکرنشده TDD است.بنابراین شما فکر نمی‌کنید که TDD یک برنامه‌نویس خوب را بد بکند ولی حرف‌هایی در این ارتباط هست. من شنیده‌ام که برخی می‌گویند انجام دادن TDD، افراد را از توجه واقعی به طراحی، منحرف می‌کند یا در این زمینه، شلخته می‌کند.من هم هر از چند گاهی، اظهارات مشابهی می‌شنوم اما این‌طور فکر نمی‌کنم. من فکر می‌کنم شما وارد جریان کاری جدیدی می‌شوید. به نوعی روش فعلی که در کار کردن دارید به هم می‌ریزد. قطعاً می‌تواند آزاردهنده باشد که کاری را انجام دهید که کاملاً با آنچه قبلاً انجام می‌دادید متفاوت است ولی من فکر می‌کنم واقعاً به شما کمک می‌کند که بهبود یابید. این فقط یک دیدگاه دیگر در زمینه نحوه‌ نگاه به کار و طراحی‌تان است. شما اساساً از تست به عنوان یک ابزار طراحی استفاده می‌کنید.بیایید به این موضوع برگردیم که چگونه تست می‌تواند طراحی را بهبود دهد. من ابتدا به مباحث اولیه برمی‌گردم. شما گفتید اولین مرحله از چرخه TDD، نوشتن تست است. روشن است که این تست در مورد چیزی است که هنوز کار نمی‌کند. درست است؟بله.چگونه می‌توانیم چیزی را که هنوز کار نمی‌کند یا حتی وجود ندارد را تست کنیم؟این به آن علت است که زمانی که ما در TDD از تست صحبت می‌کنیم، معنای دیگری به این کلمه می‌دهیم. وقتی ما به عنوان بخشی از چرخه «تست، کد و بازسازی»، تست می‌نویسیم، در واقع، چیزی را ارزیابی نمی‌کنیم بلکه یک خواسته را بیان می‌کنیم، چیزی که مفقود است را بیان می‌کنیم. به نوعی بیشتر در حوزه ذکر مشخصات (Specification) هستیم تا اینکه در حوزه ارزیابی (Verification) باشیم. به سادگی، تنها به چیزی که در پیاده‌سازی فعلی اشتباه است یا مفقود است اشاره می‌کنیم.مفقود از نظر نیازمندی‌ کاربران؟بسته به کدتان دارد. گاهی مواقع می‌تواند مربوط به چیزی کاملاً سطح پایین و تکنیکی باشد. ما با بخش‌هایی از کد که اشیاء هستند سروکار داریم. هر از چند گاهی بخشی از کدی که با آن کار می‌کنید به حوزه کاربران خیلی نزدیک می‌شود. بنابراین بستگی دارد.بنابراین شما می‌گویید که اکثر مواقع تست‌هایی که می‌نویسید، می‌توانند به نیازمندی‌‌های کاربران ترجمه شوند یا اگر از جهت دیگر بگوییم، نیازمندی‌های کاربر به چنین تست‌هایی تبدیل شوند؟ یا اینکه موارد اندکی هست که از دید خارجی سیستم کار کنید؟به شخصه به این گرایش داشته‌ام که در سطح زیر نیازمندی‌های کاربران باشم. این تا حدی مربوط به نوع سیستم‌هایی است که بر روی آن‌ها کار می‌کرده‌ام؛ به نوع کدهایی که از افراد دیگر به ارث می‌برده‌ام. این چیزی است که من عموماً در اطرافم می‌بینم. اما تعداد کافی هم افرادی قابل مشاهده هستند که بر روی سطوح بالاتری از تست کار می‌کنند. آنها همواره یا اغلب از بیرون به درون کار می‌کنند. برای من به نوعی برعکس است. اکثر مواقع در درون، کار می‌کنم و تلاش می‌کنم به چیزهایی برسم که به مقدار کافی بزرگ باشند که واقعاً یک معنی برای کاربر نهایی داشته باشند و هر از چندگاهی این نعمت را داشته‌ام که بر روی کاری از خارج به داخل کار کنم و چیزهایی را از دیدگاه سیستمی بیان کنم.وقتی می‌گویید «نعمت»، به این معناست که این روش بهتری است؟خوب فکر می‌کنم حداقل برای من این‌طور باشد. به خاطر این که برای من خیلی نادر رخ می‌دهد. اگر همیشه آن را انجام دهم، احتمالاً دارم آن را بیش از حد انجام می‌دهم. اعتقاد دارم نقطه بهینه تئوری، جایی در این میان قرار دارد. در واقع خیلی مهم نیست که آن‌جا کجاست یا آن چیست. همین قدر که در عوض منحرف شدن از آن نقطه بهینه، راهمان را به سمت آن بیابیم کافیست.شما به منحنی یادگیری (Learning Curve) اشاره کردید. روشن است که در ابتدای کار باید زمانی بوده باشد که شما جذب TDD شده‌اید و گفته باشید: بله، حس می‌کنم که به من سود می‌رساند. آیا آن زمان را به خاطر می‌آورید؟من خاطرات تاری از آن موقع دارم. به خاطر می‌آورم که زمانی بود که من سیستم را از کار می‌انداختم و آن قدر آن را شخم می‌زدم تا دوباره کار کند و بعد دوباره آن را از کار می‌انداختم و به این امید بودم که دوباره بتوانم سرپایش کنم و بعد تغییراتم را به عقب برمی‌گرداندم. بعد از آن شرایط به این روش رو آوردم که گام‌های بیشتری داشته باشم طوری که سیستم برای مدت طولانی از کار نیافتد و کاملاً داغان نشود. در عوض، به وسیله تست به این اشاره کنم که چه چیزی مفقود است و بعد آن را پیاده‌سازی کنم و بعد اطمینان یابم که مجدداً همه تست‌ها قبول می‌شوند. جایی در این انتقال، به امید رسیدم. الان اساساً اگر به تست مسلح نباشم، احساس بدی دارم.آیا تجربیات کاری شما بعد از آن زمان که به امید رسیدید، تغییرات اساسی کرد؟قطعاً این‌طور بود. استرس زیاد در من متوقف شد. به عنوان مثال در پروژه‌ای که الان کار می‌کنم هر دو هفته یک‌بار، نسخه منتشر می‌‌کنیم. من دیگر استرس زیادی برای این ندارم که تعداد زیادی خطا در آن نباشد. خطاهایی که به دستمان می‌رسد خیلی کمتر و کم‌اهمیت‌تر شده است. در واقع در مقایسه با مثلاً ۸ سال پیش خیلی استرس کمتری دارم.وقتی می‌گویید تعداد خیلی کمی خطا دارید، آیا می‌توانید در مورد تعدادشان به ما بگویید؟نمی‌دانم. سیستمی که ما بر روی آن کار می‌کنیم چندین سال است که موجود است. من برای چند ماه است که آمده‌ام. آن‌ها انواع مختلفی سیستم خطا و تیکت دارند و اکثرشان بی‌ربط هستند. ایده‌ای ندارم که چه تعداد هستند. وقتی ما یک دوره دوهفته‌ای توسعه را آغاز می‌کنیم، تعداد زیادی خطا و اندکی ویژگی جدید برای انجام دادن نداریم بلکه اساساً بیشتر ویژگی جدید و شاید یکی دو خطا داریم.فکر می‌کنم ندیدم شما از اصطلاح تست واحد (Unit Test) استفاده کنید. گفتید تست و گفتید بیان مشخصات (Specification). اما اغلب افراد از اصطلاحات تست واحد و TDD به نوعی به شکل مترادف استفاده می‌کنند. شما چطور فکر می‌کنید؟ آیا یکسان هستند یا اینکه انجام تست واحد، کاملاً متفاوت با TDD است؟من اصطلاح تست واحد (Unit Test) را خیلی دوست ندارم! هر از چند گاهی از این اصطلاح استفاده می‌کنم ولی این مشکل وجود دارد که وقتی به یک سازمان می‌روید، این اصطلاح می‌تواند معانی کاملاً متفاوتی در مقایسه با دیگر سازمان‌ها یا معنی موردنظر شما داشته باشد. اول از همه: واحد چیست؟ ممکن است بگویند ما از فلان تکنولوژی استفاده می‌کنیم و شیء یا کلاس نداریم. در اینصورت واحد چیست؟ به عنوان مثال ممکن است در آنجا واحد، فایل‌های منبع (Source) باشد. به غیر از آن، در سازمان‌های مختلف تست واحد معمولاً مربوط به سطوح خیلی ریز است که در یک زمان، تنها با یکی دو کلاس سروکار دارد. بنابراین اولین مورد مشکل‌زا بودن اصطلاحات است. مورد دوم این است که من فکر می‌کنم نمی‌توان حکم کرد که وقتی با روش مبتنی بر تست (Test Driven) کار می‌کنید باید با نوع خاصی از تست کار کنید اگرچه عمده تست‌هایی که هنگام TDD کار کردن می‌نویسم طوری هستند که می‌توان آنها را تست واحد نامید.یعنی اینکه خیلی ریزدانه هستند و در ارتباط با یک متد یا شیء مجزا هستند؟بله. اغلب مواقع، تست‌هایی که می‌نویسم شامل تعداد اندکی شیء می‌شود. اگر تأثیرات جانبی (Side Effect) داشته باشند، اطمینان می‌یابم که آن را پاکسازی (Clean-up) کرده باشم تا اینکه برای انجام تست بعدی، تأثیرات پاک شده باشد. اغلب موارد با تعداد اندکی شیء، تست می‌نویسم که یک کار خیلی کوچک خاص و مجزا را انجام می‌دهد اما هر از چند گاهی انواع دیگری از تست هم می‌نویسم. به عنوان مثال ممکن است بخواهم دسته‌ای از مؤلفه‌های گرافیکی را برپا کنم: یک برنامه خیلی کوچک GUI که چند مؤلفه گرافیکی دارد که در کنار هم وجود دارند و با هم تعامل دارند. طبق تعریف دقیقش، اینها تست واحد نیستند ولی همچنان فکر می‌کنم که معنی می‌دهد که این مورد خاص را هم به صورت مبتنی بر تست انجام داد. در چنین شرایطی، چنین روشی می‌تواند بهترین باشد.یعنی واقعاً GUI را تست می‌کردید؟ترجیحاً نه تمام واسط کاربری را. بخش کوچکی از آن را. ممکن است یک دکمه و یک فیلد متنی داشته باشید که می‌خواهید تعاملاتی با هم داشته باشند. ممکن است یک پنجره کوچک که تنها یک دکمه و یک فیلد متنی دارد و چیز دیگری ندارد را بالا بیاورید. در آن صورت، از یک فریم‌ورک گرافیکی استفاده کرده‌اید: مثلاً Spring یا چیز دیگری. بنابراین، این زیرساخت‌های استفاده شده بیشتر از آن هستند که بتوانیم آن را تست واحد بنامیم؛ شاید وابسته به تعریفتان باشد.من فکر می‌کنم برای انجام تست در آن سطح به غیر از JUnit یا nUnit ساده به ابزارهای دیگری هم نیاز دارید تا بتوانید فرضاً دکمه را کلیک کنید و کارهای این چنینی انجام دهید.بله. اگر شما زیاد این کار را می‌کنید فکر می‌کنم باید حداقل استفاده از نوعی فریم‌ورک را درنظر بگیرید و مراقب باشید این کار را به یک کابوس (در مرحله‌ی نگهداری از نرم‌افزار) تبدیل نکنید.اما شما به ابزارهای مختلفی مانند تکنولوژی‌های ضبط - بازپخش (Capture - Replay) نیاز ندارید؟ضبط - بازپخش، ایده خوبی است. اما مشکلی که اینجا وجود دارد این است که چیزی برای ضبط ندارید. اگر دکمه‌ای در جایی مفقود است چه طور می‌خواهید ضبط کنید که اگر دکمه کلیک شد اتفاقی بیافتد. اصلاً دکمه‌ای نداریم.بله. نکته ظریفی است. من می‌شنوم که افراد در جاهای مختلف از TDD استفاده می‌کنند: Java، .Net، Phyton، Rubby. آیا تکنولوژی می‌شناسید که برای TDD مناسب نباشد؟قطعاً با برخی تکنولوژی‌ها، نوشتن تست خیلی سخت‌تر می‌شود. به عنوان مثال پارسال من در بنگلر هند بودم. من داخل یک تیم جاوا بودم اما اتاق کناری ما یک گروه بودند که بر روی کد C کار می‌کردند. ما علاقه داشتیم که برویم و کمک‌شان کنیم. جالب بود. من برنامه‌نویس C نیستم. من در مورد همه کارهایی که آن‌جا می‌شود کرد اطلاع نداشتم. ما مقداری پیشرفت کردیم اما مسأله این است که زبان برنامه‌نویسی کار نوشتن مجموعه تست‌ها را خیلی سخت می‌کند. قطعاً می‌توانید این کار را انجام دهید اما API ها و فریم‌ورک‌هایی که آن‌جا فراهم است نسبت به JUnit و nUnit و این گونه ابزارها خیلی سطح پایین‌تر هستند.این یک مطلب است. مطلب دیگر این است که وقتی من با زبان جاوا در IDE های مدرن مانند Eclipse کار می‌کنم، من تایپ می‌کنم و تایپ می‌کنم و بعد بلافاصله تست‌ها را اجرا می‌کنم. من کامپایل نمی‌کنم چون IDE آن را به شکل پیوسته انجام می‌دهد و کار آن قدر آنی انجام می‌شود که نیازی نیست به آن فکر کنید اما وقتی که بعنوان مثال با C کار می‌کنید، کامپایل کردن خودش چیز بزرگی است. وقتی می‌خواهید تست‌ها را اجرا کنید باید ابتدا کامپایل کنید و بعد صبر کنید. ممکن است ۲-۳ ثانیه یا ۱۰ ثانیه طول بکشد و بعد از آن تست‌ها را اجرا می‌کنید. بنابراین چرخه فیدبک به جای ۱ ثانیه ممکن است ۱۰ ثانیه به طول بیانجامد. این مطلب اساساً روش اجرا کردن چرخه TDD را عوض می‌کند. یکی از دوستانم در مورد این روش جدید می‌گوید که TDD به روش خوش‌بینانه است به این ترتیب که پس از آن‌که کامپایل و اجرای تست را آغاز کردید، بلافاصله به تایپ کردن‌تان ادامه می‌دهید. در پس‌زمینه کامپایل در حال انجام است و وقتی کامپایل تمام شد، تست‌ها اجرا خواهند شد اما شما به کارتان ادامه می‌دهید. شما با پیش‌فرضی که در مورد قبول شدن یا ردشدن تست‌ها دارید، کارتان را ادامه می‌دهید. شما فرض می‌کنید که پیش‌فرض و درکتان از تست‌ها صحیح است. اغلب مواقع، این روش کار می‌کند اما هر از چند گاهی می‌بینید که تست رد نشده است اما قرار بود که رد شود یا تست قبول نشده است اما قرار بوده قبول شود؛ بنابراین پیش‌فرض اشتباهی داشته‌اید و مجبورید که ذهن و کدتان را به عقب، به بعد از تست قبلی ببرید. بنابراین می‌توانید آن را انجام دهید ولی جور دیگری است و حس دیگری دارد.آیا فکر می‌کنید که در این گونه محیط‌ها TDD همچنان ارزش دارد؟ یا فکر می‌کنید که چه مدت اگر چرخه فیدبک طول بکشد ارزش دارد که همچنان از TDD استفاده کنیم؟۴۲ خوبه! (به شوخی). ایده‌ای ندارم. من محیطی ندیده‌ام که TDD را سودمند نیافته باشند. یا بگوییم تا حدی سودمند چون به هر شکل، این مربوط به اشخاص است.آیا در محیط‌های ++C از نوعی که ۱۵ دقیقه یا حتی بیشتر طول بکشد تا سیستم Build شود بوده‌اید؟شخصاً خیر. من با برخی افراد صحبت کرده‌ام که در شرایط خیلی جالب کار می‌کرده‌اند مثلاً در بانک لندن که با ++C کار می‌کرده‌اند. آن‌جا مجموعه ابزارهایی مانند BI یا Emacs هست. آنها در IDE های پیچیده خود، امکانات بازسازی (Refactoring) را ندارند. در واقع IDE وجود ندارد. با این وجود TDD کار می‌کردند. برای مثال بازسازی  را با نوشتن Shell Script هایی انجام می‌دادند که فایل‌های کد برنامه‌ را بوسیله عبارات منظم (Regular Expression) دستکاری می‌کرد: ابزارهایی از قبیل sed و awk . این کار به نظر خیلی پرزحمت می‌آید اما آن‌ها تصمیم گرفتند که این کار را بکنند و آن را ادامه دادند. بنابراین واضح است که این کار برایشان سود داشته است حتی با وجود اینکه بر روی یک سیستم قدیمی کار می‌کرده‌اند و از تکنولوژی‌های دشواری استفاده می‌کرده‌اند و ++C دوستانه‌ترین زبان برای برنامه‌نویسان نیست. شخصاً ندیده‌ام اما شنیده‌ام که خیلی افراد می‌گویند که گرچه خیلی ترسناک به نظر می‌رسد اما ما واقعاً آن را انجام می‌دهیم و راضی هستیم.من دو جنبه در این قضیه می‌بینم. یک جنبه این است که آیا براساس واقعیات، انجام چنین کاری ارزشش را دارد یا خیر؟ مثلاً اگر صرفه‌جویی که به علت کار نکردن بر روی خطاهایی که با این روش، جلوی آن گرفته می‌شود را درنظر بگیریم. و جنبه دیگر این است که برای افراد چه حسی دارد. توسعه‌گران عادی چه مدت زمان را برای چرخه فیدبک تحمل می‌کنند؟سخت است که بگوییم.به جنبه‌های فنی‌تر برگردیم. به عنوان مثال شما گفتید که گاهی مواقع از تست واحد (Unit Test) محض و تست مجزای چیزها، پیروی نمی‌کنید. وقتی می‌خواهید این کار را بکنید و چیزهایی از قبیل سیستم‌های ساختگی یا پایگاه داده دارید، احتمالاً می‌خواهید آن شیء که در حال تستش هستید را از چیزهای دیگر مثلاً پایگاه داده و زیرساخت‌ها، مجزا کنید. برای آن چه کار می‌کنید؟یکی از تکنیک‌های اصلی برای این کار، تزریق وابستگی‌ (Dependency Injection) است. برای این کار در زبان جاوا، از استفاده از کلمه new اجتناب می‌کنید. می‌خواهید پیوستگی کد تحت تست از پیاده‌سازی مؤلفه‌های همکارش را از بین ببرید. برای مثال به جای اینکه بگویید ()this=new widget آن widget و وابستگی را به تابع سازنده، می‌فرستید. به این ترتیب در تست‌تان می‌توانید، یک شیء را با تعدادی نمونه‌های قلابی از وابستگی‌هایش بسازید. به عنوان مثال با بهره‌گیری از اشیاء مقلد (Mock Object). فکر می‌کنم این، مهمترین تکنیک ضروری در این‌جا است.آیا تکنیک سختی است؟ من استفاده از لغت شیء مقلد (Mock Object) را برای موارد بسیار گوناگونی شنیده‌ام. برخی مواقع من را گیج می‌کند.من آن را اینقدر دشوار نمی‌بینم. مشتاقم در مورد گیج شدن در ارتباط شیء مقلد بدانم.گاهی، افراد که در مورد شیء مقلد صحبت می‌کنند معنی‌اش واسطی (interface) است که تنها مقادیر از پیش‌تعریف‌شده‌ای برمی‌گرداند و گاهی آن را برای چیزی استفاده می‌کنند که قرار است رفتار پیچیده‌ای را در حین تست، تقلید کند. روشن است که انواع مختلفی از شیء مقلد وجود دارد.درست است. چندین اصطلاح در این مورد وجود دارد. یکی از آن‌ها ابتدا توسط مارتین فاولر نگاشته شده است. چند سال پیش او مقاله‌ای با عنوان Mocks or Stubs نوشت. فکر می‌کنم اسمش این بود. می‌توانید چک کنید. (عنوان مقاله Mocks Aren&#x27;t Stubs است و از این آدرس در دسترس است - مترجم). او این دسته‌بندی را انجام داد که فکر می‌کنم کاملاً جهانی باشد. شیء خُرد (Stub) وجود دارد و شیء مقلد (Mock) هم وجود دارد. شیء خُرد (Stub)، ساده‌ترین پیاده‌سازی ممکن از یک واسط است. متدهایش کاری نمی‌کنند صرفاً یک مقدار ثابت null یا صفر یا ۱۵ یا ... برمی‌گردانند. اصولاً همه چیزش هاردکد است. همچنین اشیاء قلابی (Fake)  هم وجود دارند که کم‌ و بیش یک پیاده‌سازی سبک‌تر از شی‌ء واقعی هستند. اصولاً وقتی یک شیء قلابی می‌گیرید و آن را فراخوانی می‌کنید مانند شیء واقعی عمل می‌کند اما واقعی نیست.به عنوان مثال اگر یک پایگاه داده قلابی داشته باشم، واقعاً مقادیر و ستون‌ها را داخل خودش نگهداری می‌کند؟یک پایگاه داده قلابی (Fake) می‌تواند یک نگاشت درهم‌سازی (Hash Map) یا چیزی باشد که مبتنی بر آن ساخته شده است. چیزی را واقعاً بر روی دیسک ذخیره نمی‌کنید درعوض آن‌ها را بر روی حافظه نگه می‌دارید و وقتی جستجو می‌کنید، ممکن است یک دور روی همه اشیاء بزنید تا اینکه به چیزی که دنبالش هستید، برسید.یعنی به نوعی شیء اصلی را شبیه‌سازی می‌کند؟بله، می‌توانیم به این شکل بگوییم. و بعد دسته سوم را داریم که اشیاء مقلد (Mock) هستند. که کمابیش قابل تنظیم هستند. شما برای یک واسط (interface) یک شیء مقلد می‌گیرید و می‌توانید به آن بگویید که وقتی فلان اتفاق افتاد، فلان رفتار را بکن. بعنوان مثال می‌توانید بگویید اگر یک اتفاقی افتاد باعث رد شدن تست شود. من فکر می‌کنم این دسته‌بندی در مورد بدل‌های تست (Test Double) کاملاً سراسری است و پذیرفته شده جهانی است.آیا فریم ورک تست شما، امکانات لازم در ارتباط با اشیاء مقلد را می‌دهد یا از ابزارهای دیگر برای این کار استفاده می‌کنید؟بستگی به تکنولوژی مورد استفاده شما دارد. من اغلب با جاوا کار می‌کنم. در چند سال گذشته، به صورت فزاینده‌ای از ابزار JDave استفاده کرده‌ام. JDave نوعی فریم‌ورک تست است و با JMock یکپارچه می‌شود و یکسری امکانات داخلی، برای تولید اشیاء مقلد دارد. برای این کار، در سطح زیرین، از JMock استفاده می‌کند اما می‌تواند میزبان فریم‌ورک‌های خوب دیگر هم باشد.بنابراین عموماً نیاز به یک فریم‌ورک دیگر خواهم داشت؟اصولاً بله. نمی‌توانید خودتان شیء مقلد را بنویسید. کار ملالت‌باری می‌شود. بله، نیاز به یک فریم‌ورک یا کتابخانه دارید.من فهمیدم موقعی که نخواهم وابستگی‌های یک شیء را تست کنم می‌توانم وابستگی‌های آن را تقلید کنم یا به صورت قلابی ایجاد کنم. اما زمانی هست که به پایگاه داده واقعی، یا فراخوانی وب‌سرویس واقعی و ... نیاز دارم. چگونه آنها را تست کنم؟یک مثال از جایی که این کار را می‌کنید، شیء دسترسی به داده (Data Access Object) است. یک بار من بر روی برنامه‌ای کار می‌کردم که بر روی یک پایگاه داده رابطه‌ای می‌نشست و شیء دسترسی به داده را داشتیم که مسئول جابجایی داده‌ها از پایگاه داده و قرار دادن آنها در اشیائی است که بتوانید با آنها کار کرده و دستکاری‌شان کنید. یا برعکس ممکن است بخواهید که یک شیء آن حوزه (Domain) را بدهید و بخواهید که آن را در پایگاه داده ثبت (Persist) کنید. حالا، چگونه این‌ها را به روش مبتنی بر تست (Test Driven) تست می‌کنید؟ چند روش وجود دارد به عنوان مثال در جاوا، می‌توانید اینترفیس‌های JDBC را تقیلد (Mock) کنید یا قلابی‌اش (Fake) کنید یا این‌ که می‌توانید یک پایگاه داده واقعی، برپا کنید و تست‌ها را روی آن اجرا کنید. این مثالی است که به نظر من به طور پیش‌فرض، احتمالاً از پایگاه داده استفاده می‌کنید.ولی فکر نمی‌کنید که زمان زیادی طول می‌کشد مثلاً راه‌انداختن Oracle نیم‌دقیقه طول می‌کشد و باز کردن چند جلسه (Session)، هر کدامشان، ۱۰ ثانیه دیگر طول بکشد...بله، در واقع در این صورت من از پایگاه داده‌های سبک‌ مانند H2 یا HSQL استفاده می‌کنم. تعدادی پایگاه داده‌ داخل حافظه (In-Memory) وجود دارد که واقعاً سبک هستند و درکسری از ثانیه برپا می‌شوند. ممکن است تأثیراتی داشته باشد اما واقعاً همانند Oracle و MySQL پایگاه داده‌های مناسبی هستند.اما به عنوان مثال اگر با Hibernate کار کنید، زبان پرس‌وجو خاص خودش را دارد. من قطعاً یک خبره Hibernate نیستم. من در به‌ خاطر آوردن این که چطور یک کار را با زبان پرس‌‌وجوی Hibernate می‌شود انجام داد، به مشکل می‌خورم. بنابراین نمی‌شود که همه چیز را قلابی کنم. در نظر بگیرید تستی بنویسم که: آقای «شیء دسترسی به داده»، اگر این کار را با تو کردم، آن‌گاه تو باید این فراخوانی API را بر روی واسط Hibernate داشته باشی و من به این روش، آن را قلابی (Mock) کرده‌ام. اگر به این روش کار کنم آن وقت، نمی‌دانم که آیا نحو (Syntax) آن جمله خاص، درست بوده است یا خیر. بنابراین من ترجیح می‌دهم که بر روی پایگاه داده واقعی کار کنم که بتوانم تست‌های معنی‌داری بنویسم که بتواند چیزی را برایم مشخص کند.چیزی که از این برداشت می‌کنم این است که هرگاه بخواهید از شیء مقلد (Mock) برای تقلید چیزی استفاده کنید باید واقعاً آن چیز را به خوبی بشناسید. حداقل در مورد API ها باید بدانید که چطور باید از آنها استفاده شود. در غیر این صورت، نمی‌توانید شیء مقلد صحیحی برای آن بنویسید.دقیقاً. این مثال دیگری از تکنولوژی‌هایی است که من در مورد آنها ترجیح می‌دهم که از تست‌های کاملاً خالص و ریز استفاده نکنم.در مورد هزینه TDD چطور؟ آیا توسعه به این روش پرهزینه‌تر است؟ فکر می‌کنم اکثر افراد می‌گویند که دست‌کم در ابتدای کار این گونه است.قطعاً این هزینه منحنی یادگیری است. شما در ارتباط با بهره‌وری، آن چاله ابتدای کار را خواهید داشت. تعدادی مطالعات تحقیقاتی وجود دارد که تلاش دارند که به‌نوعی اختلاف‌های بین تست‌اول (Test First) و تست‌آخر (Test Last) یا بین تست‌اول و تست‌نکردن (Test Never) را اندازه‌گیری کنند. مشکلی که این‌جا وجود دارد این است که هیچ‌گاه به یک اثبات قطعی نمی‌رسید زیرا باید واقعاً افراد یکسانی را استفاده کنید و بگذارید که برای مدتی بر روی چیزی با یک تکنیک کار کنند و بعد از آن اصولاً آنها را شستشوی مغزی دهید و کاری کنید که هرچه در آن مدت آموخته و یافته‌اند را فراموش کنند و بعد مجبورشان کنید که همان کار را با یک تکنیک دیگر انجام دهند تا بتوانید یک مقایسه معنی‌دار داشته باشید. بنابراین، گروهی از مطالعات یک چیز را پیشنهاد می‌کنند و گروهی دیگر، چیز دیگری را پیشنهاد می‌کنند اما فکر می‌کنم اصولاً اینکه آیا چیزی پرهزینه‌تر یا کم‌هزینه‌تر است و مواردی از این دست، وابسته به باور شخصی شما است. به شخصه، شکی ندارم که برای من بهره‌وری بیشتری دارد که تست‌اول کار کنم تا اینکه تست‌آخر کار کنم.در ارتباط با تیم‌هایی که دیده‌اید چطور؟ فکر می‌کنید که نسبت به قبل از آنکه TDD را برایشان معرفی کنید، سریع‌تر شده‌اند؟می‌توانم بگویم که گرایش به سریع‌تر شدن داشتند. مشکلی که اینجا وجود دارد این است که TDD تنها بازیگر ماجرا نیست. در همین حین، در طی زمان، حجم کدتان را افزایش می‌دهید. ممکن است اندازه تیم‌تان را افزایش دهید. ممکن است با یک تیم ۵ نفره شروع کرده باشید اما الان ۲ تیم ۵ نفره باشید یا ممکن است ۱۰ تیم بشوید. بنابراین در طی زمان، متغیرهای دیگر تغییر می‌کنند و سخت است که بگوییم آیا واقعاً سریع‌تر شده‌اند یا خیر زیرا خروجی نهایی مستقیماً وابسته به بهره‌وری اشخاص نیست بلکه متغیرهای زیادی درگیر است. اما به شخصه اعتقاد دارم تیم‌هایی که TDD را به خدمت می‌گیرند سریع‌تر می‌شوند. یعنی اگر خودشان را در حالتی که TDD را به خدمت نگرفته‌اند، تصور کنم و مقایسه کنم. عمده این قضیه به علت داشتن تست است. فکر می‌کنم بزرگترین تفاوت از داشتن تعداد کافی تست ناشی می‌شود که به شما احساس امنیت خوشایندی می‌دهد. به علاوه، از بهبود کیفیت کد و طراحی‌ها نیز سود برده می‌شود و البته خیلی چیزهای دیگر از قبیل یادگیری افراد هم هست.برخی می‌گویند داشتن تعداد زیادی تست، شما را کند می‌کند زیرا نیاز دارید به غیر از تغییر کد محصول، کدهای تست را نیز تغییر دهید.درست است. خیلی این را شنیده‌ام. فکر می‌کنم این یک جنبه اصلی و ذکر نشده در مورد TDD است. کافی نیست که فقط چرخه «تست، کد و بازسازی (Refactor)» را انجام دهید. نیاز دارید که به غیر از آن، حسی در مورد اشیاء در ذهن داشته باشید و لازم است که کدهای تست را هم بازسازی کنید. فقط بازسازی کردن کدهای محصول نیست. شما باید به همان نسبت به کدهای تست‌تان هم اهمیت دهید.فکر می‌کنید همان اصول راهنما که در مورد کد محصول مفید است در مورد کد تست هم مفید است؟اعتقاد دارم بله. اما اصل (Principle)، اصل است و با قاعده (Rule) تفاوت دارد. به عنوان مثال ممکن است اصول مختلفی داشته باشید که با هم در تضادند و مجبور شوید که یک تصمیم شخصی بگیرید. مثلاً اینکه امسال یک مقدار کد تکراری اینجا وجود دارد اما این تکرارها، باعث می‌شود که تست‌های کمی ‌بهتر و قابل‌فهم‌تر داشته باشم. یعنی ممکن است تصمیم بگیرید که این کدهای تکراری بماند هرچند که اصول می‌گویند که باید از دستشان خلاص شوید.و آیا این شرایط را در کد محصول هم می‌یافتید؟ممکن است. آن دنیا، کمی متفاوت است. در کد تست، تعدادی سناریو را تشریح می‌کنید که با طبیعتی که حوزه کد محصول دارد متفاوت است. در آن‌جا محصول‌تان را مدل می‌کنید بنابراین فکر می‌کنم تفاوت وجود دارد. ممکن است این تفاوت شدید باشد اما من فکر می‌کنم که تفاوت کمی وجود دارد.بیایید به سراغ موضوعی نه کاملاً متفاوت اما متفاوت برویم. در کتابتان بین TDD و Acceptance TDD تفاوت قائل شده‌اید. به من گفتید که مقداری «توسعه مبتنی بر رفتار» BDD (Behavioral Driven Development) هم انجام داده‌اید. تفاوت بین این سه چیست؟ آیا فقط شکل تکامل‌یافته همدیگر هستند؟ چگونه می‌توانیم مفهوم این سه چیز را ترسیم کنیم؟من ابتدا در مورد BDD صحبت می‌کنم. منشأ BDD خیلی نزدیک به TDD است. اصطلاح BDD توسط دَن نورث  ابداع شد. طبق اظهارات دَن، او این اصطلاح را برای شرایطی به کار گرفت که نمی‌خواست در مورد تست صحبت کند و در عوض می‌خواست در مورد بیان مشخصات برخی رفتارها صحبت کند. پیش از این اشاره کردم که ما از واژه‌ تست به معانی مختلفی استفاده کرده‌ایم. خیلی از افراد از واژه‌ تست، این معنی ذاتیش را درنظر دارند که تست به معنای ارزیابی بعد از کار است. در TDD، معنای آن بیان پیشاپیش مشخصات چیزی است که هنوز وجود ندارد. بنابراین ناهمخوانی وجود دارد. آنچه دَن، سعی در انجام آن داشت (و بعداً به آن BDD اطلاق کرد)، استفاده از واژگان متفاوتی بود که برای طرز فکر TDD مناسب‌تر بودند. BDD از این‌جا آغاز شد.در اینجا دو جهت برای تکامل به وجود آمد. یک مسیر، تکامل TDD به تست‌های توسعه‌دهندگان بود که خیلی ریزدانه بود اما با اصطلاحات متفاوتی بیان می‌شد. جایی که می‌خواهید تست را نه با عنوان تست بلکه با عنوان بیان مشخصات استفاده کنید.مسیر دیگر تکامل این بود که از تست‌های واحد (Unit Test) سطح پایین خارج شویم. حال چه تست باشد چه بیان مشخصات باشد. تلاش کنیم که از آن خارج شویم و چیزها را از دیدگاه کاربران بیان کنیم و بیشتر در حوزه کاربران نهایی و حوزه واسط کاربری قرار گیریم و به جای زبان‌های برنامه‌نویسی، بیشتر از زبان کاربران  استفاده کنیم. در واقع این با انتخاب بین تست یا تست پذیرش (Acceptance Test) رابطه دارد. من فکر می‌کنم این دو جهت اصلی است که BDD تکامل یافته است.بنابراین فکر می‌کنید که BDD باعث شده است که TDD و Acceptance TDD، تکراری شوند؟این به نظر درست نمی‌آید. من این‌طور نمی‌گویم. من می‌‌گویم BDD انواع مختلفی قاعده ندارد بلکه تنها یک شاخه از TDD یا تست پذیرش (Acceptance) است.اما آنطور که من متوجه شدم، BDD نمی‌تواند هر دو جنبه را پوشش دهد.بله. برای این اصطلاح هم، معانی مختلفی استفاده شده است. انواع مختلفی از BDD وجود دارد. شما « BDD با گرایش کد» و « BDD با گرایش ویژگی‌ها یا عملکردها» را دارید. احتمالاً از ابزارهای مختلفی برای این دو گونه مختلف BDD استفاده می‌کنید. در عمل، شما دو چیز مختلف را اجرا می‌کنید هرچند هر دو BDD خوانده می‌شوند.آیا برای BDD، ترجیحی در مورد ابزارها دارید؟من پیش از این به JDave اشاره کردم. من آن را یک فریم ورک تست خواندم اما در واقع یک فریم‌ورک BDD است و مفاهیم و اصطلاحات BDD را درخود تعبیه کرده است. JDave اصولاً الهام‌گرفته از rspec است. امروزه Cucumber یکی از فرزندان پروژه rspec است. Cucumber به نوعی یکی از ابزارهای مورد علاقه من در ارتباط با گونه تست پذیرش از BDD است.آیا در پروژه‌هایی که شرکت می‌کنید همچنان استفاده از برخی ابزارهای قدیمی تست پذیرش (Acceptance Test) مانند Fitness را در نظر می‌گیرید؟من زیاد با Fitness کار نکرده‌ام. چند باری به آن برخوردم و به نظرم ابزار خوبی بود. فکر می‌کنم بین این روش مبتنی بر جداول یا حتی نسخه روایتی (Narrative) از Fitness با سناریوها و تست‌هایی که می‌توانیم در ابزارهایی مانند Cucumber داشته باشیم، تفاوت زیادی وجود دارد. تفاوت آن‌چنان کلان نیست اما آن قدر زیاد هست که من دیگر استفاده از ابزاهایی مانند Fitness را در نظر ندارم. البته برای کدهای قدیمی اگر یک سیستم میراث از تست‌های Fitness وجود داشته باشد، احتمالاً همان مسیر را ادامه می‌دهم. اما در یک زمینه خالی، احتمالاً ابزارهایی مانند Cucumber را استفاده می‌کنم.به من گفتید که دارید کتاب دیگری می‌نویسید.بله، در واقع در ارتباط با تست واحد (Unit Test) است. انتشاراتم -انتشارات Manning- از من خواست که آیا می‌خواهم با روی آشرو کار کنم. او یک کتاب net. دارد و بیشتر از آنکه جاواکار باشد، اهل net. است. در واقع این همکاری به نوعی ترجمه کتابش به دنیای جاوا است. روشن است که برخی مفاهیم متفاوت هستند و در آن‌جا به کار نمی‌آید بنابراین این‌کار نمی‌تواند یک ترجمه مستقیم باشد.آیا قرار است فراتر از موضوع مبتنی بر تست (Test Driven) باشد؟بله، ما به TDD اشاره می‌کنیم و معرفی کوتاهی در مورد آن ارائه می‌کنیم اما اصولاً تمرکز کتاب بر روی هنر تست نوشتن است یا اگر از اصطلاحات BDD استفاده می‌کنید تمرکز بر نوشتن بیان مشخصات است.آیا کتاب در سطح حرفه‌ای‌ها است؟بله. به نوعی کتابی برای حرفه‌ای‌ها است. کلی کد منبع و این‌جور چیزها.چه وقت قرار است منتشر شود؟گفتنش سخت است. قطعاً می‌توانم بگویم امسال نخواهد بود. امیدوارم یک سال بعد، کتاب در دستم باشد.در پایان آیا چیزی هست که بخواهید اضافه کنید؟چیزی به ذهنم نمی‌رسد.من یک سئوالی به ذهنم رسید. آخرین باری که من شما را دیدم در Agile 2008 بود و شما یکی از ستاره‌های برنامه‌نویسی بودید.آن مسابقات، اساساً یک رقابت در زمینه تست‌کردن به روش TDD در معرض عموم بود. شما مسابقه را بردید. چطور این کار را کردید؟ما جاسوسیِ جاشوآ  -یکی از داوران- را کردیم! علاوه بر آن تقلب هم همراهم برده بودم (شوخی)! فکر می‌کنم ما تکنولوژی‌هایی را انتخاب کردیم که برای حضار، جذاب بود. فکر می‌کنم به مقدار کافی مردم را سرگرم کردیم.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Sat, 27 Nov 2021 22:23:07 +0330</pubDate>
            </item>
                    <item>
                <title>رسیدگی به خطاها (قسمت دوم)</title>
                <link>https://virgool.io/se-radio/%D8%B1%D8%B3%DB%8C%D8%AF%DA%AF%DB%8C-%D8%A8%D9%87-%D8%AE%D8%B7%D8%A7%D9%87%D8%A7-%D9%82%D8%B3%D9%85%D8%AA-%D8%AF%D9%88%D9%85-khi7qvi247i4</link>
                <description>مطلبی که می‌خوانید ترجمه‌ی قسمت ۲۱ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت، مارکوس ولتر و مارکوس آرنو نگاه عمیق‌تری به استثناها (Exception) و شرایط خطا، نحوه دسته‌بندی آن‌ها و نحوه مقابله با آن‌ها خواهند داشت. نگاهی به سطوح مختلف ضمانت‌هایی خواهیم داشت که یک تکه‌ کد در ارتباط با شرایط استثنا می‌تواند فراهم کند و با تعدادی از سرمشق‌ها (Best Practice) و مصالحه‌هایی (Trade-off) که دارند بحث را به پایان می‌رسانیم. فکر می‌کنم ما در مورد دو دسته شرایط استثنا (Exception) بحث کردیم. آیا می‌توانید به طور خلاصه آنها را توضیح دهید؟بله، خوب است که با واژه‌شناسی (Terminology) شروع کنیم. نه به خاطر اینکه من به این جور موارد رسمی علاقه‌مندم بلکه به این خاطر که خوب است برای ادامه، معانی لغات شفاف باشد. در ارتباط با استثنا (Exception) و شرایط آن، تمایز از آن جا ناشی می‌شود که آیا واقعاً برای برنامه‌نویس مورد انتظار (Expected) هستند یا خیر. استثناهای موردانتظار، مواردی هستند که درباره آنها اطلاع دارید و می‌تواند رخ دهد و فردی ممکن است بخواهد آن را به نحوی رسیدگی کند. مواردی که فراخواننده کد شما ممکن است انتظار آن را داشته باشد یا شما بخواهید که انتظارش را داشته باشد. به عنوان مثال، وقتی شبکه یا پایگاه داده از کار افتاده است یا وقتی که کسی، یک نام غیرمعتبر وارد کرده است. در این زمان، فراخواننده را آگاه کرده و انتظار دارید که فراخواننده به آن رسیدگی کند. شما در مستندات کلاس، متد، زیرسیستم‌ یا ... مسیرهای ممکن را مستند می‌کنید.و دسته دوم؟دسته دوم چیزهایی هستند که موردانتظار نیستند. در وهله اول، فکر کردن و اطلاع دادن آنها غریب به نظر می‌رسد. منشأ اصلی استثناهایی که مورد انتظار نیستند، باگ‌ها یا هر شرایطی هستند که کسی فکر نکرده است که نیاز به رسیدگی دارد. اگر این موارد رخ دهد، نمی‌توان آن را ترمیم کرد فقط می‌توان مطمئن شد که چیز خیلی بدی رخ نداده است و سیستم را خاموش کنیم و مواردی از این قبیل. بنابراین خودتان را به این محدود کنید که شرایط استثنا موردانتظار را به روش خوش‌تعریفی رسیدگی کنید و در مورد شرایطی که انتظار آن نمی‌رود، یک بلاک دریافت (Catch) خواهید داشت که در همه موارد آنها را رسیدگی می‌کند که اطمینان می‌یابد که چیز خیلی بدی رخ نداده است و سیستم مانند شرایط مورد انتظار، به شکل برازنده‌ای، رفتار می‌کند.من معتقدم صحبت در مورد شرایط استثنا، خطاها و مشکلات نرم‌افزار، یکی از رهاشده‌ترین موضوعات در مهندسی نرم‌افزار است. رسیدگی به خطاها، به خوبی شناخته نشده است. تعداد زیادی تعریف و روش‌ مختلف وجود دارد اما تعداد خیلی خیلی کمی، قاعده تعریف‌شده مشخص در مورد آن داریم که چگونه باید آن را انجام داد و چگونه می‌توان آن را خوب انجام داد.بله، توصیه ما در این مورد این است که اصطلاحات را از هم مجزا کنید. شرایط استثنایی که به نوعی انتظارش را دارید خطا (Error) خوانده می‌شوند و شرایط استثنایی ای که به هیچ‌ عنوان انتظارش نمی‌رفته را استثنا (Exception) می‌گوییم. و این نباید با اصطلاحات زبان جاوا به اشتباه گرفته شود.بله، دقیقاً. زبان جاوا این موارد را به خوبی از هم مجزا نمی‌کند. اما این تمایز برای نحوه رسیدگی به آنها در سطح معماری بسیار مفید خواهد بود.من فکر می‌کنم مدلی که در مورد سطوح ضمانت (Guarantee) داریم بر روی طراحی معماری نرم‌افزار نقش دارد.بله، دقیقاً. در واقع، تعریف این سطوح ضمانت به هرب ساتر برمی‌گردد که در کتابش، ++Exceptional C  آن‌ها را مستند کرد. سطوح ضمانت که ما می‌خواهیم معرفی کنیم مرتبط با همان سطوحی است که ساتر در کتابش گفته است. البته دقیقاً همان دسته‌بندی‌های او نیست اما به آن نزدیک است. آن کتاب، کتاب خیلی خوب و قابل توصیه‌ای است.اولین و بنیادی‌ترین سطح ضمانت، می‌گوید: هر اتفاقی بیافتد، باید پایدار باشیم. باید بتوانیم بعد از رخداد مشکل، دوباره فراخوانی داشته باشیم و نباید نشتی منابع (Resource Leak) داشته باشیم. کدهای زیادی هستند که این سطح از ضمانت را پشتیبانی نمی‌کند با این وجود باید، این سطح از ضمانت، یک سطح مبنایی باشد که همه بخش‌های کد محصول آن را برآورده کند و اگر در جایی، بعضی جنبه‌های این سطح بنیادی ضمانت برآورده نمی‌شود، باید فکر کنیم که مشکل کجاست که می‌تواند هرگونه مشکل یا استثنایی باشد که منجر به نشتی یک منبع می‌شود مثلاً می‌تواند یک دستگیره (Handle) پایگاه داده، دستگیره GUI، سوکت، نخ (Thread) یا هر چیز دیگری باشد. شرایطی که یک منبعی از سیستم‌عامل برای همیشه باقی بماند یا حداقل به اندازه طول عمر پردازش (Process) باقی بماند که به همان اندازه باقی ماندن برای همیشه، بد است. همه بخش‌های کد باید اطمینان یابند که هر شرایط استثنایی که رخ دهد، منابع آزاد خواهند شد. در زبان‌های برنامه‌نویسی مختلف روش‌های مختلفی برای این امر وجود دارد. در زبان جاوا، بلاک‌های finally را داریم. در زبان ++C، توابع مخرب (Destructor) را داریم. هر زبانی ابزار خاص خود را دارد اما این مسأله واقعاً مهمی است که تحت هیچ شرایطی هیچ منبعی نباید نشتی داشته باشد. مورد دیگر این است که باید پس از فراخوانی بخشی از کد، در یک وضعیت پایدار باقی بمانیم خصوصاً در مورد توابع سازنده (Constructor) این مطلب صادق است. اگر تابع سازنده استثنایی (Exception) ایجاد کند به این معناست که شیء مقداردهی اولیه نشده و در دسترس نیست. این یکی از فواید توابع سازنده است که یا یک شیء کاملاً آماده و مقداردهی اولیه شده خواهید داشت و یا اصلاً شیءای نخواهید داشت. اما فرض کنید، مقداردهی اولیه را مدتی بعد و از طریق تابع مقداردهی اولیه (Initializer)  انجام می‌دهید و در حین آن مشکلی پیش می‌آید. در اینجا ممکن است یک شیء نیمه آماده داشته باشید. در این صورت، حتی اگر نشتی منبع نداشته باشید، این امر می‌تواند در آینده، به هر نوع رفتار تعریف‌نشده‌ای بیانجامد و ضمانت بنیادی (Fundamental Guarantee) رعایت نمی‌شود. ضمانت بنیادی می‌گوید که هر اتفاقی که بیافتد باید پایدار و در یک وضعیت تعریف‌شده و قابل فراخوانی باشیم. برای ضمانت بنیادی کافیست که با رخداد هر خطایی یک استثنا (Exception) پَرت شود اما در ضمن لازمست که در یک وضعیت تعریف‌شده قرار بگیریم.وقتی تابع سازنده، به خطا می‌خورد واقعاً چه کار می‌توانم بکنم؟ در آن صورت یک شیء ای که در یک وضعیت نامطمئن قرار دارد خواهم داشت. آن موقع چه کار باید بکنم؟در مورد تابع سازنده، عموماً مشکلی نخواهد بود زیرا اگر تابع سازنده بصورت غیرعادی، شکست بخورد، زبانی که استفاده می‌کنید اطمینان می‌دهد که ارجاعی به شیء موردنظر بدست نخواهید آورد. اکثر زبان‌ها این طور رفتار می‌کنند. بنابراین اگر تابع سازنده با نوعی استثنا، شکست بخورد، اصلاً شیءای نخواهید داشت که بخواهید ارجاع یا اشاره‌گری به آن داشته باشید. مطمئناً در مورد شیء غیرقابل فراخوانی، مشکلی نخواهد بود.بنابراین من یک اشاره‌گر تهی (Null) یا چیزی شبیه به آن خواهم داشت.شما از تابع سازنده، یک استثنا (Exception) می‌گیرید. هیچ اشاره‌گری برگشت نخواهد شد و زبان‌ها اطمینان می‌دهند که اشاره‌گری که بتوانید آنها را به متغیرها انتساب دهید، نخواهید داشت. به همین علت است که اگر بخواهید ضمانت بنیادی را برآورده کنید، مقداردهی اولیه به اشیاء در توابع سازنده، ایده خوبی است.بسیار خوب. این ضمانت سطح اول بود؟بله، بگذارید یک مثال اضافه کنم. به عنوان مثال در دنیای جاوا، فریم‌ورک Hibernate  یک نمونه بد در این مورد است. در آن جا، هندل به پایگاه داده، جلسه (Session) خوانده می‌شود که یک شیء پیچیده بزرگ است. هر جلسه، یک نهانگاه (Cache) سطح یک دارد که اشیاء را نگهداری و ثبت می‌کند. مستندات Hibernate می‌گوید که در صورتی که در جلسه هر نوع استثنایی رخ دهد (که در حالت خوشبینانه می‌تواند یک لاگ یا هر چیز دیگری باشد)، جلسه به یک وضعیت مستندنشده می‌رود و لازمست که آن را دور انداخته و با یک جلسه جدید آغاز کنید. این برعکس چیزی است که ضمانت بنیادی می‌گوید. این یک طراحی بد است. ایده خوبی است که Hibernate طور دیگری رفتار کند.بیایید به سطح بعدی ضمانت برویم: ضمانت ابتدایی (Basic Guarantee). ضمانت ابتدایی، بر روی ضمانت بنیادی ساخته می‌شود اما همچنین نیازمند این است که شیء، قابل استفاده باشد. ضمانت ابتدایی می‌گوید که: نباید نشتی منبع وجود داشته باشد و شیء باید در یک وضعیت پایدار و تعریف‌شده قرار بگیرد. ضمانت بنیادی به شما اجازه می‌دهد که هنگام بروز خطا یک نشانه‌ای قرار دهید که مشکلی رخ داده است و سپس برای هر متدی، یک حفاظی قرار دهید که استثنایی (Exception) پَرت کنید که بگوید این شیء در یک وضعیت غیرمجاز قرار دارد و از یک شیء دیگر استفاده کنید اما ضمانت ابتدایی می‌گوید که هر اتفاق و استثنایی که رخ دهد شیء باید همچنان قابل استفاده باشد. در صورتی که از مؤلفه‌های بدون‌حالت (Stateless) استفاده کنید این نوع ضمانت اغلب فراهم خواهد بود. زیرا در مؤلفه‌های بدون‌حالت، حالت قابل مشاهده‌ای وجود ندارد و هر اتفاقی که رخ دهد مؤلفه‌ها قابل فراخوانی خواهند بود. داده‌ها وارد می‌شوند، عبور می‌کنند اما مؤلفه‌ها می‌توانند دوباره و دوباره و دوباره فراخوانی شوند. بله، ممکن است استثنایی رخ دهد اما هر اتفاق یا استثنایی که رخ دهد مؤلفه را غیرمعتبر نمی‌کند و همچنان می‌تواند استفاده شود. به همین علت است که بدون‌حالت بودن برای داشتن کدهای محکم (Robust Code)، خوب است و به همین علت است که مؤلفه‌های بدون حالت، در مقایسه با مؤلفه‌های حالت‌دار، رسیدگی به خطا را تا حد زیادی ساده‌تر می‌کند.سطح سوم ضمانت، ضمانت قوی (Strong Guarantee) است که از اصطلاحات هرب ساتر است. ضمانت قوی، معانی تراکنش (Transaction) و عقب‌‌گرد (Rollback) را الزام می‌کند. اگر یک فراخوانی شکست بخورد، ضمانت قوی الزام می‌کند که شی‌ء دقیقاً در حالت قابل مشاهده‌ای (Observable State) قرار می‌گیرد که قبل از فراخوانی قرار داشته است. تفاوت بین حالت درونی و حالت قابل مشاهده این است که یک شی‌ء ممکن است یک نهانگاه (Cache) داخلی داشته باشد. ضمانت قوی الزام نمی‌کند که این نهانگاه داخلی به قبل بازگردد بلکه باید هرگونه وضعیت قابل‌مشاهده از خارج از شیء (که تنها به خاطر بهینه‌ کردن کارایی نیستند) به عقب برگردد. مفهوم عقب‌گرد، زمانی مطلوب است که شما با حالات اشیاء سروکار دارید. اگر عقب‌گرد نمی‌داشتید، فراخواننده مجبور می‌بود که قبل از فراخوانی یک کپی بگیرد و حالت قبلی شیء را نگه دارد و با پیچیدگی‌هایی مواجه بود. خیلی بهتر است که این کارها به صورت درونی در خود مؤلفه‌ فراخوانی‌شده انجام شود.شیء تغییرناپذیر (Immutable) یک روش طراحی خوب برای رسیدن به ضمانت قوی است. اگر یک شیء تغییرناپذیر داشته باشید هر اتفاقی که بیافتد حالتش تغییر نمی‌کند. اگر فراخوانی داشته باشید که بخواهد حالت را تغییر دهد، یک کپی تغییریافته از شیء برگشت داده می‌شود اما شیء اصلی تغییر نمی‌کند بنابراین به وضوح مفهوم عقب‌گرد برآورده می‌شود زیرا شیء اصلی اصلاً تغییر نمی‌کند.گاهی اوقات علاقه‌مندیم که تراکنش‌های انحصاری داشته باشیم و فراخوانی‌های مختلف، تثبیت (Commit) و عقب‌گردهای (Rollback) منحصر به خودشان را داشته باشند. اما دشوار است که بخواهید یک چنین سیستم پایگاه داده‌ای را خودتان بنویسید و عموماً نمی‌خواهیم این کار را انجام دهیم. عموماً روشی که استفاده می‌شود این است که در لایه منطق کسب‌وکار (Business Logic) از مؤلفه‌های بدون‌ حالت (Stateless) استفاده می‌شود و حالت‌ها داخل پایگاه داده قرار می‌گیرد و مفهوم عقب‌گرد را پایگاه داده فراهم می‌کند که این روش آسان‌تر از این است که بخواهیم این کارها را در داخل مؤلفه‌هایی که بالای لایه پایگاه داده قرار دارند، انجام دهیم.بسیار خوب، این ضمانت قوی بود و ضمانت بعدی، ضمانت پَرت نکردن (No Throw) است.درست است. ضمانت پَرت نکردن، همان چیزی را تضمین می‌کند که اسمش می‌گوید. هرچه اتفاق بیافتد، نباید چیزی پَرت کنید. چنین چیزی خیلی نادر است. خصوصاً در زبان‌هایی مانند #C و Java خیلی نادر است. زیرا در آن جا هر فراخوانی که داشته باشید ممکن است به خطای داخلی ماشین مجازی (Virtual Machine) یا کم آوردن حافظه (Out of Memory) و موارد این چنینی بیانجامد بنابراین چنین چیزی به ندرت در زبان‌هایی مانند #C یا جاوا ضرورت پیدا می‌کند. ولی این ضمانت، اگر به لایه‌های زیرین و داخل سیستم‌عامل نزدیک شوید، یا اگر به سطوح زیرین ماشین نزدیک شوید، در مورد سیستم‌های تعبیه شده و در مورد سیستم‌های پایگاه داده، اهمیت می‌یابد. در آن جا مهم است که بخشی از کد داشته باشید که بتوانید روی این حساب کنید که هیچ چیزی پَرت نمی‌شود.نکته کلیدی این است که نخواهید به بالاترین سطح ضمانت ممکن برسید. برای رسیدن به بالاترین سطح باید بیشترین هزینه را بکنید که اغلب بصرفه نیست بلکه باید به طراحی‌تان فکر کنید که کدتان چه سطحی از ضمانت را برآورده می‌کند یا به عبارت دیگر هر بخشی از کد من، نیاز است که چه سطحی از ضمانت را برآورده ‌کند. نکته کلیدی، این است که همه اجزاء سیستم می‌بایست ضمانت بنیادی را برآورده کنند: هر اتفاقی که بیافتد نباید نشتی منبع داشته باشید و هر اتفاقی که بیافتد نباید کدی داشته باشید که در یک وضعیت تعریف‌نشده قرار بگیرد و باید همچنان در دسترس استفاده‌کنندگان باشد. بعد از آن می‌توانید به برآورده کردن ضمانت ابتدایی هم فکر کنید: هر اتفاقی که بیافتد مؤلفه‌ها باید قابل استفاده مجدد باشند. و ضمانت قوی: باید مفاهیم تراکنش و عقب‌گرد فراهم شود و ضمانت پَرت نکردن: بخشی از کد باید باشد که بتوانیم در مورد آن اطمینان داشته باشیم که هر اتفاقی از جمله هر شرایط  استثنایی که بیافتد با آن به صورت برازنده‌ای، رفتار کند.فکر می‌کنم که خیلی سخت باشد که در مورد مؤلفه‌های بزرگ سیستم به ضمانت پَرت نکردن برسیم.بله، مطمئناً سخت است و اغلب ضرورتی ندارد ولی وقتی در مورد سیستم‌های تعبیه شده با مأموریت‌های بحرانی فکر می‌کنم، امیدوارم یک مصلح که در قلب سیستم قرار دارد یا یک سیستم کنترل سبک که در پس‌زمینه قرار دارد، بخش‌هایی باشند که ضمانت پَرت نکردن را فراهم می‌کنند. بله، مطمئناً کدهایی درون سیستم وجود دارند که این گونه‌اند اما مؤلفه‌های بزرگ‌تر باید شامل هرگونه شرایط مشکل‌داری باشند. موافقم که برای بسیاری از سیستم‌ها از جمله سیستم‌های متداول کسب‌وکار، خیلی دشوار است که به چنین ضمانتی برسیم و چنین زحمتی بصرفه نیست.برگردیم به اصطلاحات قبلی شما. اینکه می‌بایست فقط با خطاها (Error) برخورد کنیم و برطرفشان کنیم و یاد بگیریم که چطور با آنها برخورد کنیم. اما اساساً خطاها، استثنا (Exception) نیستند.سئوال خوبی است. اول از همه، درست است که این مهم است که با خطاها با این روش‌های دارای ضمانت برخورد کنیم. جهت یادآوری عرض می‌کنم که خطاها، مشکلات مورد انتظار هستند. اما شرایطی مانند سیستم‌های تعبیه‌شده با مأموریت‌های بحرانی هستند که ضمانت پَرت نکردن را ارائه می‌کنند و لازم است که حتی با شرایط استثنا هم بصورت برازنده‌ای برخورد کنیم. بنابراین می‌توان گفت: بله، عموماً در هنگام طراحی سیستم در مورد برخورد با خطاها فکر می‌کنید اما در مورد باگ‌ها و این گونه چیزها، فقط به چیزهایی از قبیل پایان دادن برازنده برنامه فکر می‌کنید. اما مواردی هم هست که نیاز دارید یا مطلوب است که در مورد باگ‌ها هم به این فکر کنید که تا چه حد قابلیت اطمینان می‌خواهید در مورد آن‌ها داشته باشید.فکر می‌کنم این مطلب ما را به موضوع دیگری که در سطح معماری در ارتباط با برخورد با استثنا ها داریم، می‌برد. مهمترین سرمشق (Best Practice) در مورد برخورد با استثناها این است که استثناها را در مرزهای سیستم رسیدگی کنید. این که اگر یک سیستم بزرگ با ماژول‌های مختلف دارید آن را تفکیک کرده و استثناها را تنها در مرزهای سیستم، رسیدگی کنید. ممکن است یک سیستم با تنها یک مؤلفه داشته باشید و استثناها را در GUI یا دقیقاً در سطح زیر GUI رسیدگی کنید. مثلاً این که یک پیغام بالا بیاید که: «یک خطای داخلی رخ داده است و من برنامه را بصورت برازنده‌ای می‌بندم.» یا اینکه: «خطایی رخ داده‌است. من کاری نمی‌کنم و دعا می‌کنم که سیستم به صورت پایدار ادامه یابد.» اما مهم است که همه جای کدتان را با بلاک‌های دریافت (Catch) برای رسیدگی به استثناها پر نکنید زیرا باعث ناخوانا شدن کد می‌شود و خیلی دشوار می‌شود که بفهمیم چه کار دارد انجام می‌شود.این توصیه شما در مورد استثناها بود اما در مورد خطاها چطور؟خطاها متفاوت هستند. خطا یعنی یک مشکل قابل انتظار رخ داده است. بخش قابل انتظار بودن که در تعریف خطا داریم به این معناست که کسی فکر می‌کند که می‌خواهید آن را به صورت محلی رسیدگی کنید. شما ممکن است به آن علاقه داشته باشید و بخواهید با آن برخورد کنید. بنابراین اگر می‌توانید و برایتان معنی می‌دهد آن را به صورت محلی، رسیدگی کنید. مثال آن، خطا خوردن اتصال است. اگر پایگاه داده، پایین آمده باشد و مؤلفه‌ای بگوید که اتصال از بین رفته است. در آنصورت شما یک استثنا (Exception) فنی می‌گیرید که البته در زبان اصطلاحات ما، به آن خطا (Error) می‌گوییم. در آن صورت ممکن است بخواهید که برای اتصال به پایگاه داده تلاش مجدد داشته باشید یا اینکه به پایگاه داده دیگری، تعویض کنید که به ویژگی‌های کیفی سرویس سیستم‌تان وابسته است. یا مثلاً در شرایطی که شبکه، پایین آمده باشد و داده‌ها بر روی سرور ذخیره شده باشند، ممکن است بخواهید در عوض، داده‌ها را از نهانگاه (Cache) بخوانید یا اگر فراخوانی، مربوط به ذخیره کردن داده‌ها در سرور باشد ممکن است بخواهید آن را در یک صف قرار دهید تا بعداً ارسال کنید.این یک استراتژی معماری است که در مورد این فکر کنید که چطور می‌توانید خطاها را بصورت محلی رسیدگی کنید. این به آن معنا نیست که مانند مثال پایگاه داده یا استفاده از نهان‌گاه، همیشه می‌توانید هنگام در دسترس نبودن شبکه، این کارها را انجام دهید. بله، تعداد زیادی از سیستم‌ها این کار را می‌کنند اما خیلی از سیستم‌ها هم این کار را نمی‌کنند. در این صورت، این امر باعث می شود که این موارد از گروه خطاهای قابل انتظار به گروه موارد غیرقابل انتظار که مانند باگ با آنها برخورد می‌شود منتقل شوند. بنابراین تمایز بین آنها خیلی قطعی نیست اما اگر اموری باشند که در دسته خطاها قرار بگیرند و قابل انتظار باشند، باید با آنها به صورت محلی برخورد شود و روش‌هایی از قبیل تلاش مجدد برای آن‌ها استفاده شود. یا لااقل باید در طراحیتان به این امور فکر کنید.اما نکته مهم این است که هیچ گاه یک استثنا یا خطای تکنیکی را دریافت (Catch) نکنید و - بدون این که کار دیگری بکنید- فقط انتظار داشته باشید که کار درست پیش خواهد رفت. به علت وجود استثناهای چِک‌شده (Checked Exception) در جاوا به این کار گرایش فراوانی وجود دارد زیرا در آن جا مجبور هستید به نوعی با قضیه برخورد کنید. این یک روش بد است که فقط استثنا را دریافت کنیم و امیدوار باشیم کسی آن را نفهمد. اگر استثنا وجود دارد بگذارید تا عبور کند و آن را در یکی از مرزهای زیرسیستم‌ها، مرز تیم یا مرز زیرسیستم‌های توزیع‌شده، رسیدگی کنید و اگر مشکل یک خطا است، در مورد برخورد با آن به صورت محلی فکر کنید و اگر نمی‌توانید به صورت محلی برخورد کنید بگذارید عبور کند و آن را اساساً تبدیل به استثنا کنید.بسیار خوب، فکر می‌کنم در ادامه چند قاعده سرانگشتی برایمان داشته باشید.بله، دقیقاً. این قواعد سرانگشتی برگرفته از کتاب Zidosley (ممکن است نام نویسنده بدرستی تشخیص داده نشده باشد - مترجم) هستند. آنها دقیقاً مطابق با آن کتاب نیستند ولی این قواعد از آنجا الهام گرفته شده است. اولین قاعده سرانگشتی این است که بین خطا (Error) و استثنا (Exception) تمایز قائل شوید. وقتی دارید مؤلفه یا بخشی از سیستم، و یک واسط (Interface) قابل فراخوانی از بیرون را طراحی می‌کنید، خوب است که به این فکر کنید که چه چیزهایی هست که می‌تواند با مشکل مواجه شود و برای کدام یک از آنها معنی می‌دهد که فراخواننده با آن برخورد داشته باشد و برای کدام یک از آنها معنی نمی‌دهد. خوب است که در این مورد فکر کنید اما تمایز دقیق آن، سخت است. شما نمی‌دانید چه کسانی کد شما را فراخوانی می‌کنند و چگونه درگیر آن می‌شوند. یک مثال که تمایز آن دشوار است، اعتبارسنجی (Authorization) است. یک روش متداول این است که اگر اعتبارسنجی ناموفق بود، یک استثنا پَرت کنیم. آیا چنین چیزی مورد انتظار است یا مورد انتظار نیست؟ اگر مورد انتظار باشد، ما می‌توانیم همه جا آن را داشته باشیم. همه جای کد، ممکن است چنین خطایی تولید شود. اگر بخواهیم بصورت استثنا با آن برخورد کنیم و آن را در سطح بالا، رسیدگی کنیم، دیگر نمی‌توانیم به صورت محلی آن را رسیدگی کنیم. این نشان می‌دهد که ما چنین مواردی داریم که باید به این تمایز دادن‌‌ها فکر کنیم. اما بیش از حد در مورد آن فکر نکنید و تلاش کنید بیش از حد در بکارگیری این تمایزها سخت‌گیری نکنید. نکته کلیدی، این است که مستنداتی در این مورد فراهم کنید که با یک فراخوانی چه مشکلاتی می‌تواند پیش بیاید و چه استثناهای فنی و چه نوع خطاهایی می‌تواند تولید شود. این مستندات می‌تواند توسط یک تولیدکننده خودکار مستندات API تهیه شود یا می‌تواند در ابزار تست خودکارتان باشد و یا از هر طریق دیگری فراهم شود. به هرحال به یک روشی باید مستند شود.قاعده خوب سرانگشتی دیگر این است که خطاها و استثناها را خودمستند (Self Document) کنید. همان طور که در قسمت اول رسیدگی به خطا گفتیم، چندین گروه مختلف هستند که به اطلاعات خطاها علاقه‌مندند. اول، کاربران هستند. راضی‌ کردن آنها اغلب ساده است. اگر مشکلی پیش آمده که یک شرایط خطای معنی‌دار برای آنها نیست، اجازه دهید که تعامل داشته باشند و به آنها بگویید که یک خطای داخلی رخ داده است. گروه دیگر، مدیرسیستم‌ها هستند که روی کامپیوترهای مراکز داده کار می‌کنند. آنها نیاز به اطلاعات مشخص دارند. اما مهمترین گروهی که بیشترین میزان جزییات را نیاز دارند، برنامه‌نویسان هستند. هرگاه نوعی استثنا فنی یا خطایی رخ دهد لازم است که شامل همه داده‌های مورد نیاز برای فهمیدن آن، برای بازسازی شرایط زمینه‌ای آن (Context) و برای رسیدگی به آن فراهم باشد. این به آن معناست که همواره کلاس‌های استثنا شامل داده‌هایی هستند که به آنها اضافه شده است و یک سلسله‌مراتب ارث‌بری دارید که نحوه برخورد متفاوت با آنها را بازتاب می‌دهد.نکته مهم این است که سطح درستی از جزییات را نگهداری کنید. اغلب، این کار، کار دشواری است. برخی سطوح جزییات خیلی مفید است مثلاً اینکه سرور بعد از رخداد استثنا پایدار بوده یا پایدار نبوده است. برخی افراد یک سلسله مراتب عظیم از انواع استثناها می‌سازند که خیلی ریزدانه است درحالیکه نحوه رسیدگی به استثناهای مختلف آن تفاوتی ندارد. این، کار هزینه‌بری است که صرفه‌ای ندارد. بله، می‌بایست استثناها را خودمستند کنیم اما نباید در این کار زیاده‌روی کنیم.این ما را به قاعده سرانگشتی سوم می‌رساند که تنها برای استثناها و خطاهایی، کلاس مجزا بسازید که برای کنترل جریان کار نیاز دارید. به این معنا که تا حدی که ممکن است آن را ساده نگه دارید.بله، دقیقاً. این همان چیزی است که من می‌گفتم. معمولاً با تعداد زیادی از استثناها با یک روش خیلی عمومی برخورد و رسیدگی می‌شود. اغلب یک بلاک دریافت (Catch) دارید و برای رسیدگی به آن‌ها، تنها آن‌ها را لاگ می‌زنیم و یک پیغام به کاربر نمایش می‌دهیم که یک خطای داخلی رخ داده است و یا مدیرسیستم را آگاه می‌کنیم تا سرور را راه‌اندازی مجدد کند یا مواردی از این قبیل. بنابراین در رسیدگی به آنها تفاوتی نیست و فایده‌ای در داشتن استثناهای نوع‌های مختلف نیست و صرفه‌ای در آن نیست.زبان‌های برنامه‌نویسی مختلف و فرهنگ‌های برنامه‌نویسی مختلفی وجود دارد. در بسیاری از زبان‌ها نوعی فرهنگ طراحی سلسله‌ای عظیم از کلاس‌های کامل استثنا وجود دارد. اما اغلب نیازی به آن نیست و زحمتی است که عموماً صرفه‌ای ندارد.قاعده سرانگشتی دیگر این است که تنها راه گزارش کردن استثناهای فنی از طریق کلاس‌های استثنا نیست. اغلب این طور هست اما همچنان امکان استفاده از مقادیر خروجی تابع هم فراهم است. به شکل خاص، گردآوری پارامترها (Collecting Parameters) یک الگوی خوب برای گزارش مشکلات با یک روش عموماً ساده‌تر و دم‌دستی‌تر از پَرت کردن استثنا است. در این روش یک گردآورد (Collection) به عنوان پارامتر ورودی متد می‌دهید و اگر مشکلی داخل متد پیش بیاید، اقلامی به آن اضافه می‌شود. این روش اجازه می‌دهد که بتوانید در عوض یک مشکل، چندین مشکل را به فراخواننده گزارش دهید. این کار برای مثال در اعتبارسنجی در واسط کاربر، خیلی کاربرد دارد. اگر دیالوگی داشته باشید که مثلاً دو فیلد داشته باشد و بر روی هر دو قیودی داشته باشید که باید اعتبارسنجی شوند، طراحی بدی است که در کد بررسی‌کننده، اگر اولین فیلد مشکل داشت، یک استثنا پَرت کنید و یک پیغام به کاربر نمایش دهید که فلان قید برآورده نشده است مثلاً «باید فیلد نام را وارد کنید». و آنگاه کاربر مجدد درخواست را ارسال کند و بررسی بعدی انجام شود. این طراحی خوبی نیست اما از طریق استثنا کار دیگری نمی‌توانید بکنید. اما یک طراحی خوب در اینجا این است که یک گردآورد (Collection) به تابع بررسی‌کننده بفرستیم و برای هر اعتبارسنجی که برآورده نمی‌شود یک قلم به آن اضافه نماییم و بتوانیم فهرست همه مشکلات را در پیغامی که به کاربر نمایش می‌دهیم داشته باشیم. بنابراین پَرت کردن استثنا تنها روش برای گزارش کردن مشکلات و شرایط خطا نیست و خوب است این را خصوصاً در طراحی واسط کاربر به خاطر داشته باشید.بسیار خوب، و قاعده سرانگشتی آخر؟قاعده سرانگشتی آخر این است که استحکام (Robustness) در درجه اول اهمیت قرار دارد و بهینه سازی کارایی (Performance) در درجه دوم است اگر در درجه سوم و چهارم نباشد! استحکام در درجه اول قرار دارد. این مطلب بارها گفته شده و باید روشن باشد اما هنوز روشن نیست و بارها و بارها افراد دوباره می‌گویند که استفاده از استثناها باعث کاهش کارایی می‌شود. سرعت را کاهش می‌دهد و سربار عظیمی دارد بنابراین من از آن استفاده نمی‌کنم. از مقدار خروجی تابع استفاده می‌کنم چون سریع‌تر است یا اینکه من استثنا‌ها را از قبل می‌سازم و در موقع آن، استثنا‌های از پیش ساخته را استفاده می‌کنم. اینکار، عجیب‌غریب است. این به آن معناست که در گزارش خطا، اطلاعاتی می‌گیرید که ممکن است دقیق نباشد. شرایط استثنا نادر هستند یا باید نادر باشند! و فکر کردن در مورد کارایی هنگام رسیدگی به خطا واقعاً ایده خیلی بدی است. شرایط استثنا آن قدر نادر هستند که عموماً اگر سربار داشته باشند اهمیتی ندارد و استفاده از استثناها با تکنولوژی امروزی کاملاً سریع است. بله، از خروجی تابع کندتر است اما چیزی است که اصلاً اهمیتی ندارد. اگر شما به آن توجه کنید برای کسی مهم نیست!اگر سیستم تعبیه شده دارید حداقل، تأثیر این سربار را اندازه‌گیری کنید. اگر آن را اندازه‌گیری کردید و به این نتیجه رسیدید که بله، استثناها، گلوگاه (Bottleneck) شما هستند، در آن صورت شما باید سیستم را مجدداً طراحی کنید. اما اگر موفق نشدید و همه این کارها شکست خورد، آن موقع به حذف کردن استثناها و کاهش استحکام فکر کنید اما قبل از آن، طراحی خود را ساده کنید. استثناها یک ابزار ساده برای جدا نگه داشتن بیشتر بخش‌های کد شما از جزییات برخورد با مشکلات هستند. روش‌های دیگر، مستعد خطا هستند بنابراین از استثناها استفاده کنید و مسائل کارایی را درنظر نگیرید مگر آن که اندازه‌گیری کرده باشید که این کار تأثیر وخیمی بر روی کارایی گذاشته است که من جداً در مورد آن شک دارم.من در این مورد تجربه‌ای دارم. وقتی برنامه‌نویسی ++C برای یک سیستم تعبیه‌شده می‌کردم، سربار قرار دادن کدهای استثنا کامپایلر در خروجی باینری را اندازه‌گیری کردیم. در آنجا سربار رد پا (Footprint)  و سربار زمان اجرا داشتیم که مربوط به ساختن پُشته (Stack) و پاک کردن آن برای رسیدگی به استثنا بود. بنابراین در ++C مقداری سربار وجود دارد اما همانطور که آرنو گفت، آن را اندازه‌گیری کنید و ببینید که آیا اهمیتی دارد و آیا بر روی کارایی برنامه‌تان تأثیری دارد یا خیر.بله، خصوصاً در مورد سیستم‌های تعبیه‌شده، قطعاً شرایطی هست که نمی‌خواهید از استثنا استفاده کنید اما آن را اندازه‌گیری کنید و در مورد سیستم‌های معمولی کسب‌وکار، سربار اهمیتی برای سیستم‌تان نخواهد داشت.این مطلب من را به یک نوع دیدگاه در مورد استثناها رهنمون می‌کند. چیزی که تا حدی غیرعادی است اما کمک می‌کند تا خیلی از مسائل فنی مرتبط با برخورد با استثناها را درک کنید و آن، این است که استثناها واقعاً پیچیده هستند. آنها از این که رسیدگی به خطا را بدون آنها انجام دهید ساده‌تر هستند اما با این وجود استثناها یک نوع دستور goto غیرمحلی هستند. و اضافه بر آن، یک goto غیرمحلی به جایی هستند که نمی‌شناسید. اگر این طور به استثناها نگاه کنید، کمک می‌کند تا طراحی‌تان را ساده نگه دارید و آن را به صورت مؤثر و سازگار با سیستم‌تان استفاده کنید. از استثناها به صورت خردمندانه استفاده کنید و آن را تا جایی که می‌شود ساده نگه دارید زیرا رسیدگی به خطا خیلی خیلی پیچیده است.مایکل، آیا می‌خواهی این قسمت را جمع‌بندی کنی؟بسیار خوب، آنچه آموختم این بود که فراخوانی متدها باید حتی در شرایط استثنا، همواره منابع را آزاد کنند که همان ضمانت بنیادی است. اغلب مطلوب است که ضمانت قوی‌تری داشته باشیم به عنوان مثال ضمانت ابتدایی که اگر مشکلی پیش آمد بتوانیم فراخوانی را تکرار کنیم یا اینکه ضمانت‌های قوی و یا پَرت نکردن داشته باشیم. هر API باید به صراحت بیان کنند که چه استثناهایی و در چه وقتی پَرت می‌کنند. ما اصطلاحی را در اینجا معرفی کردیم که خطا به شرایط قابل انتظار اشاره دارد. در نهایت آرنو توصیه کرد که استثناها را همواره در مرزهای تیم‌ها یا مرز توزیع‌شدگی‌ها رسیدگی کنیم یعنی هرجایی که یک مرز شبکه‌ای بین زیرسیستم‌ها یا مؤلفه‌ها وجود دارد اما ترجیحاً در سطح‌های درشت‌تر و نه در سطح‌های ریز.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Fri, 19 Nov 2021 13:50:29 +0330</pubDate>
            </item>
                    <item>
                <title>برآورد نرم‌افزار</title>
                <link>https://virgool.io/se-radio/se-radio-estimation-ich0an3ojpfp</link>
                <description>مطلبی که می‌خوانید ترجمه ی قسمت قسمت ۲۷۳ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این قسمت که در نوامبر ۲۰۱۶ منتشر شده است، سوِن یوهان با استیو مک‌کانل درباره‌ی برآورد نرم‌افزار (Software Estimation) صحبت می‌کند. مباحثی که مطرح می‌شود:چرا و چه وقت کسب‌وکارها به برآورد نیاز دارند یا چه وقت ندارند؟تبدیل برآورد‌ها به طرح‌ریزی و سنجش پیشرفت بر اساس این طرح‌ریزی به چه نحوی است؟چرا برآورد‌های نرم‌افزار همواره مملو از عدم قطعیت است؟این عدم قطعیت‌ها چه هستند و چه‌طور با آن‌ها روبرو شویم؟من سوِن یوهان هستم و امروز استیو مک‌کانل مهمان من است. استیو مدیر ارشد اجرایی و مهندس ارشد نرم‌افزار در شرکت نرم‌افزاری Construx است؛ او مؤلف Code Complete ، Rapid Development و بسیاری کتاب‌های دیگر است. او در سال ۲۰۰۶ کتابی در مورد برآورد نرم‌افزار منتشر کرد. همچنین به عنوان سردبیر مجله مهندسی نرم‌افزار IEEE فعالیت کرده است. من امروز با استیو درباره‌ی برآورد هزینه‌ی نرم‌افزار صحبت می‌کنم. استیو به برنامه خوش آمدی!متشکرم که مرا دعوت کردید.آیا چیز مهمی را در معرفی شما فراموش کردم؟نه فکر می‌کنم تقریباً به طور کامل توضیح دادید.خوب. برآورد چیست؟فکر می‌کنم وقتی سوال می‌کنیم که برآورد چیست باید میان نحوه‌ی استفاده‌ی عمومی افراد -که در بسیاری از موارد ناسالم و غیرسازنده است- و آنچه‌که یک برآورد واقعاً هست، تمایز قائل شویم؛ هم از لحاظ تعریف کتابی و هم از لحاظ نحوه‌ی درست صحبت کردن در مورد برآورد. فکر کنم اگر به تعریف برآورد در واژه‌نامه نگاه کنید، برآورد یک پیش‌بینی آماری از مدت زمان انجام یک کار، یا هزینه‌ی آن، و یا این‌‌که چه تعداد ویژگی را می‌توان در یک زمان مشخص تحویل داد است. بنابراین مفهوم مورد نظر در اینجا پیش‌بینی است. تعریف واژه‌نامه‌ای معمولاً مفهومی از تقریبی، تجربی و مقدماتی بودن یا چیزی شبیه به آن را نیز مطرح می‌کند. بنابراین در واقع ما درباره‌ی یک تصویر مقدماتی یا پیش‌گویی تجربی یا همچنین چیزی صحبت می‌کنیم. فکر می‌کنم این درست باشد. این بهترین و سازنده‌ترین روش فکر کردن به آن در نرم‌افزار است.در عمل آن‌چه فهمیدیم این است که افراد در هر دو سوی تصمیمات فنی و کسب‌وکار، قطعاً گرایش دارند که از کلمه‌ی برآورد به معنی پیش‌گویی آماری استفاده کنند؛ اما از آن به معنی تعهد هم استفاده می‌کنند. یعنی افراد کسب‌وکار می‌پرسند به برآورد شما این کار چقدر طول می‌کشد؟ افراد فنی هم می‌گویند فکر می‌کنیم تا فلان تاریخ طول بکشد. در این لحظه تاریخ مورد نظر تبدیل به تعهدی به کسب‌وکار می‌شود؛ این کمی فراتر از برآورد می‌رود. فکر می‌کنم استفاده از این کلمه علاوه بر اشاره برآورد و تعهد، برای اشاره به اهداف هم استفاده می‌شود. مثلاً طرف کسب‌وکار ممکن است بگوید ما واقعاً دوست داریم که این کار تا فلان تاریخ تمام شود و در حین گفتگو ما به نحوی کلمات برآورد و تعهد را تلفیق می‌کنیم. این منجر به انواع مشکلات می‌شود که می‌توانیم در صورت نیاز در مورد آن‌ها صحبت کنیم؛ اما فکر می‌کنم برای کوتاه کردن سخن اگر بتوانیم در گفتگوهایمان و یا حداقل در ذهن‌مان میان برآورد‌ها، تعهدات و اهداف تمایز قائل شویم -حداقل در جنبه‌ی فنی معادله- خودمان را برای داشتن گفتگوهای بسیار سازنده‌تری درباره‌ی برآورد آماده کرده‌ایم. ما ارزش بسیاری در صِرفِ روشن کردن این مفهوم دیده‌ایم. چون روشن کردن مفهوم، منجر به روشن شدن فعالیت هم می‌شود. بنابراین می‌دانیم کِی برآورد می‌کنیم، کِی درباره‌ی یک هدف صحبت می‌کنیم، و کِی تعهد می‌دهیم. روشن کردن این کلمات در حقیقت به ما کمک می‌کند تا از دادن تعهد درحالی که فکر می‌کنیم صرفاً برآورد می‌کنیم، دوری کنیم.تعهد، هدف و برآورد. رئیس من از من یک برآورد خواست اما در واقع می‌خواست به هدفی برسد و از ما تعهدی برای رسیدن به هدف بگیرد. آیا این بازگویی از زبان من درست است؟ :-)فکر می‌کنم درست باشد. فکر می‌کنم روش سازنده‌ای برای فکر کردن به آن است. یعنی [تشریح] کامل آن این است که کسب‌وکار چیزی در ذهن دارد که فکر می‌کند به درد کسب‌وکار می‌خورد. این هدف است. معمولاً کسب‌وکار می‌پرسد چه برآوردی از این کار دارید؟ فکر می‌کنید چه تعداد ویژگی می‌توانید تا فلان تاریخ تحویل دهید؟ بنابراین آن‌چه که کسب‌وکار طبیعتاً فکر می‌کند این است که آن‌چه که امیدوار بودیم به آن دست پیدا کنیم، صد درصدِ آن‌چیزی است که در ذهنمان بود. عموماً این‌طور است که افراد خوش‌بین هستند. افراد فنی می‌روند و کار واقعیِ برآورد کردن را انجام می‌دهند که من در واقع به آن برآورد می‌گویم. و عموماً برمی‌گردند و همان‌طور که از نام خوش‌بینی پیداست متوجه می‌شوند در واقع هدف کسب‌وکار [در زمان] مورد نظر قابل دست‌یابی نیست؛ [هدف] خیلی خوش‌بینانه بود. توانایی حقیقی سازمان برای تحویل آن کافی نیست. اتفاقی که در اینجا رخ می‌دهد این است که ما از برآورد استفاده می‌کنیم تا بفهمیم توانایی‌مان در رسیدن به یک هدف و این‌که به آن متعهد شویم معقول است یا خیر. برآورد در واقع به ما کمک می‌کند تعیین کنیم که این تعهدی است که «احتمالاً» به آن دست می‌یابیم یا این تعهدی است که «احتمالاً» نمی‌توانیم زیر بار آن برویم. اما مفهومی از بی‌ثباتی و احتمال در هر برآورد واقع‌بینانه وجود دارد. بنابراین در هر برآورد واقع‌بینانه درجه‌ای از انعطاف‌پذیری وجود دارد. وقتی می‌گوییم برآورد، حاکی از احتمال برآورده شدن تعهد است، برآورد آن را تضمین نمی‌کند. در عوض می‌گوید که فرصت خیلی خوبی برای برآوردن تعهد داریم یا این‌که امکان تلاش کردن برای آن را داریم یا این‌که هیچ شانسی برای عمل به تعهد نداریم و در نتیجه احتمالاً از همان ابتدا نباید زیر بار آن برویم.وقتی کتاب‌تان را خواندم توضیح خیلی خوبی در این مورد داده بودید؛ با [تمثیل] یک چمدان زمانی که به تعطیلات می‌روید. با تثبیت میزان چیزهایی که می‌تواند در چمدان قرار بگیرد. شاید بخواهید در مورد این مثال به مخاطبان بگویید. فکر می‌کنم [موضوع را] خیلی واضح کند.بله حتماً. این بخش از کتاب در واقع از ستونی که کمی قبل‌تر در IEEE منتشر کرده بودم گرفته شده است. فرض کنید می‌خواهیم به تعطیلات برویم و می‌خواهیم تصمیم بگیریم که چمدان با چه اندازه‌ای برای لباس‌هایمان لازم داریم. واقعاً نمی‌خواهیم اندازه‌ی دقیقِ چمدانی را بدانیم که دقیقاً به اندازه‌ی لباس‌های ماست. ما می‌خواهیم چمدانی داشته باشیم که به اندازه‌ی همه‌ی لباس‌ها جا داشته باشد، اما نه آن‌قدر بزرگ که کلی جای خالی در آن باشد و در فرودگاه ما را دچار دردسر کند. مسئله‌ای که در آن فصل از کتاب مطرح می‌کنم این است که زمانی که می‌خواهید به سفر بروید، کاری که می‌کنید این است که چمدان‌تان را برمی‌دارید. ممکن است تعدادی لباس دیگر هم داشته باشید که باید در آن جا شوند و شاید لازم باشد چمدان را به زور ببندید. اما اگر اندازه‌ی آن به اندازه‌ی کافی بزرگ باشد می‌توانید به زور هم که شده آن را ببندید. [بنابراین] احتمالاً خوب است و چمدان به اندازه‌ی کافی بزرگ است. فکر می‌کنم این قیاس مناسبی با کاری است که ما می‌خواهیم در برآورد نرم‌افزار انجام دهیم. ما تلاش نمی‌کنیم با برآورد‌هایمان بگوییم که به طور دقیق به آن‌ها دست خواهیم یافت. چیزهای زیادی در پروژه‌های نرم‌افزاری تغییر می‌کند. این تصور که ما دقیقاً به هر آن‌چه برآورد می‌کنیم دست خواهیم یافت وابسته به این است که ما دقیقاً همان‌چیزی را که در ابتدا شروع کردیم، تحویل بدهیم؛ این به ندرت رخ می‌دهد. چیزهای زیادی در طول مسیر تغییر می‌کند. اما [کافی است] آن‌چه که در ابتدا برآورد می‌کنیم به اندازه‌ی کافی نزدیک به واقعیت باشد، به نحوی که بتوانیم به چیزی مشابه به آن دست یابیم حتی اگر نیاز به کار بیشتری داشته باشد،‌ شاید یکی دو آخر هفته یا آخر وقت (که معادل به زور چپاندن لباس‌ها در چمدان هستند). اگر این محقق شود ما کم و بیش آن‌چه که گفته بودیم تحویل می‌دهیم را، کم و بیش در بازه‌ی زمانی که گفته بودیم، تحویل داد‌ه‌ایم. من فکر می‌کنم اکثریت کسب‌وکارها درک می‌کنند که زندگی غیر قطعی است. با وجود این‌که همه چیز را در نظر گرفتیم و شاید دقیقاً مطابق آن‌چه که انتظار داشتیم پیش نرفتیم، اما به اندازه‌ی کافی به آن نزدیک شدیم، به طوری که این اجرای پروژه را خوب و به طور کلی یک پروژه‌ی موفق در نظر می‌گیریم. این به نوعی ماهیت داستان چمدان بود. هدف آن این بود که نشان دهد خیلی خوب بود اگر هیچ چیز هرگز تغییر نمی‌کرد و می‌توانستیم به دقت پیش‌بینی کنیم که دقیقاً چه رخ خواهد داد؛ هرچند در واقعیت این‌گونه نیست اما آن‌چه واقعاً می‌خواهیم این است که به اندازه‌ی کافی به برآورد‌هایمان نزدیک شویم؛ به طوری که بتوان فاصله را با حد معقولی از کار اضافی، یا حذف کردن ویژگی‌ها در مقیاس‌های کوچک، یا تغییرات کوچکی که روی موفق بودن پروژه تأثیر ندارند، پر کنیم.اما خطای برآورد از کجا سرچشمه می‌گیرد؟:-) من تقریباً ۲۰ سال است که یک کلاس برآورد کردن را تدریس می‌کنم. حداقل در ۱۰ سال گذشته به دانشجویان تمرینی می‌دهم و به آن‌ها می‌گویم که سه دقیقه وقت دارید که طوفان فکری کنید و هر تعداد که می‌توانید از منابع تغییرات در پروژه را بیابید که باعث می‌شوند برآورد‌هایی که پروژه بر آن بنا شده بود باطل شود. از همان تغییراتی که به صورت روزمره رخ می‌دهند. من به دنبال تغییرات تصادفی و غیرمنتظره نیستم که شاید بتوان پیش‌بینی کرد بلکه به دنبال چیزهایی هستم که در برآورد‌ها در نظر گرفته نشدند و حتی اگر آن‌ها را در نظر می‌گرفتید نمی‌توانستید برآورد را بهبود دهید. چیزهایی که همواره در پروژه‌ها رخ می‌دهند. به آن‌ها سه دقیقه وقت می‌دهم تا هر تعداد که می‌توانند بگویند. در یک گروه بیست نفری معمولاً لیستی از ۳۰ یا ۴۰ مورد تهیه می‌شود. لیست را بررسی می‌کنیم و می‌گویم که از شما خواستم که اتفاقات نادر را نگویید. آیا این‌ها اتفاقات غیرمتداول هستند یا عموماً رخ می‌دهند؟ آن‌ها همیشه می‌گویند این‌ها متداول هستند و همیشه اتفاق می‌افتند. چیزهایی که از آن صحبت می‌کنیم از این قبیل‌اند: یک عضو کلیدی از دسترس خارج می‌شود، کار را ترک می‌کند، یا به پروژه‌ی دیگری ملحق می‌شود؛ اولویت‌های مدیریتی عوض می‌شود، یعنی اولویت‌ها در ابتدای پروژه در حین پروژه تغییر می‌کنند؛ بودجه تغییر می‌کند، پروژه را با ده نفر شروع می‌کنید، بودجه عوض می‌شود و باید با هفت نفر کار را انجام دهید؛ بازار تغییر می‌کند، رقیب ویژگی‌ای منتشر می‌کند که باید به آن در نسخه‌ی بعدی محصول عکس‌العمل نشان دهید. این لیست ادامه دارد... .این قبیل چیزها هستند که در تمام پروژه‌ها اتفاق می‌افتد. در حقیقت فکر می‌کنم اگر پروژه‌ای پیدا کنید که از ابتدا تا انتها حقیقتاً پایدار مانده باشد، به شدت متعجب می‌شوید. در اکثر مواقع وقتی می‌گویم پایدار منظورم این است که فرض‌هایی که برآورد را تحت تأثیر قرار می‌دهند از ابتدا پایدار بمانند. این‌ها فرض‌هایی در مورد مجموعه ویژگی‌ها، افراد تیم، پشتیبانی سازمانی و ... هستند.ین کار را سخت می‌کند. منظورم این است که برخی از همکاران سابقم را می‌شناسم که برآورد می‌خواستند و در انتها فقط اعداد را مقایسه می‌کردند. [آن‌ها می‌گفتند:] این‌ها ۱۰۰۰ نفر/روز برآورد کرده بودند در حالی که ۱۲۰۰ نفر/ساعت وقت گرفت؛ [پس] این افراد، بد هستند. من فرصتی برای دفاع ندارم. چه‌طور باید از خودم دفاع کنم. راهی وجود دارد؟ آیا باید همه چیز را بنویسم، یا این صرفاً احساس شخصی من است که افراد اسلحه‌ای روی سر من گذاشته‌اند [و می‌گویند] تو کاملاً اشتباه برآورد کردی!بله، فکر می‌کنم بسته به جزئیات، این سناریو می‌تواند به دلایل مختلفی اتفاق بیفتد. دلیل ناسالمی که ممکن است این اتفاق رخ دهد این است که افرادی که پروژه را برآورد می‌کنند برآوردگران خوبی نیستند و در واقع چیزی تغییر نکرده است و باید همان ۱۲۰۰ نفر/ساعت را در ابتدا برآورد می‌کردند. اما این کار را نکردند و ۱۰۰۰ نفر/ساعت برآورد کردند. بنابراین از برنامه عقب افتادند. این اساس برحقی در انتقاد به تیم است. فکر می‌کنم این گاهی اتفاق می‌افتد. حقیقت موضوع این است که وضعیت سرمشق‌های (Practice) [نحوه‌ی] برآورد هنوز خیلی خوب نیست. هنوز در اغلب موارد تیم‌ها و سازمان‌هایی را می‌بینیم که از چیزهایی که به آن سرمشق‌های «عقیده‌ی خبره» (Expert&#x27;s Judgment) گفته می‌شود، استفاده می‌کنند. این به آن معنی است که این سرمشق‌ها به طرزی که استفاده می‌شوند به شدت در معرض خطا هستند. بنابراین خیلی اوقات این انتقاد برحق است.در مواقع دیگر فکر می‌کنم یکی از دلایلی که پروژه‌ای که ۱۰۰۰ نفر/ساعت برآورد شده بود، ۱۲۰۰ نفر/ساعت طول بکشد تغییرات ردگیری نشده در مفهوم پروژه هستند. فکر می‌کنم این خیلی متداول است. من موارد خیلی خیلی زیادی را دیده‌ام که تیم‌های پروژه با یک مفهوم از پروژه و مجموعه‌ای از نیازمندی‌ها شروع به کار روی پروژه می‌کنند. [سپس] تغییرات نیازمندی‌ها یا نیازمندی‌های جدید وارد می‌شوند. و همه‌ی افراد از جمله‌ی افراد کسب‌وکار دور میزی می‌نشینند و تغییرات را نگاه می‌کنند و می‌گویند این تغییرات خوب هستند؛ باید آن را انجام دهیم؛ هزینه‌ی آن ارزشش را دارد. اما اتفاقی که می‌افتد این است که هرچند همه با تغییرات موافق‌اند آثار تجمعی تغییرات را در پروژه ردگیری نمی‌کنند. از قدرت من خارج است که به شما بگویم چه تعداد تیم‌های پروژه را دیده‌ام که دور میز می‌نشینند و توافق می‌کنند که یک تغییر خوب است و به صورت داخلی موافقند که [این تغییر] روی پروژه و هزینه‌های آن تأثیرگذار است اما با این وجود این هیچ تأثیر موجی (Ripple Effect) [برای بروزرسانی] پروژه‌ی اصلی، بودجه‌ی اصلی یا زمان‌بندی اصلی ندارد. بنابراین فکر می‌کنم خیلی متداول است که پروژه‌ای که ۱۰۰۰ نفر/ساعت برآورد شده باشد اما ۱۲۰۰ نفر/ساعت طول بکشد. بسیار محتمل است که این ۲۰۰ نفر/ساعت را اضافه کرده باشیم؛ به صورت توافقی هم اضافه کرده باشیم. و اگر از کسب‌وکار بپرسید که فلان چیز یا بهمان چیز ارزشش را داشت؟ این تفاوت میان ۱۰۰۰ و ۱۲۰۰ ارزشش را داشت؟ خیلی محتمل است که بگویند بله. بنابراین آن‌چه که واقعاً از آن صحبت می‌کنیم اصلاً یک مسئله‌ی فنی نیست، یک مسئله‌ی ارتباطی [و انتقال مطلب] است. از این لحاظ که اطمینان حاصل کرد سازمان بفهمد که خود سازمان است که تصمیمی می‌گیرد و قلمروی (Scope) پروژه را افزایش می‌دهد. این تجاوز نیست؛ افزایش قلمرو آن است؛ این‌ها یکسان نیستند.ظاهراً سال‌ها پیش وقتی بیل گیتس همچنان مدیرعامل مایکروسافت بود، درخواستی برای گزارش وضعیت پروژه‌ها در قالب خاصی می‌کند. نمی‌دانم این یک داستان است یا واقعیت دارد، اما به هر حال آن را دوست دارم. ظاهراً خواست گزارش وضعیت در یک صفحه باشد که در بالای آن زمان‌بندی اولیه‌ی پروژه باشد و در خط دوم زمان‌بندی فعلی پروژه و سپس لیستی از تفاوت‌ها و دلایلی باشد که چرا زمان‌بندی فعلی مانند زمان‌بندی اولیه نیست. فکر می‌کنم این روش خیلی زیرکانه‌ای باشد. چون او با درخواست گزارش‌ها در این قالب می‌خواهد نشان دهد میل دارد زمان‌بندی اولیه را به یاد داشته باشد اما نمی‌خواهد تمامی تغییراتی که بین زمان‌بندی اولیه و زمان‌بندی فعلی وجود دارد را بخاطر آورد؛ با این‌که احتمالاً دلایل خوبی برای تغییرات وجود دارد. اما در گزارش وضعیت، من خلاصه‌ای سریع می‌خواهم از این‌که چرا تصویر من از زمان‌بندی اولیه تغییر کرده و باید به جای زمان‌بندی اولیه، روی زمان‌بندی فعلی تمرکز کنم.باشه، من این را امتحان خواهم کرد :-) خوب به نظر می‌رسد. میزان زیادی عدم قطعیت در برآورد وجود دارد. درست است؟ حتی اگر همه‌ی این کارها را انجام دهم، ممکن است خیلی اشتباه کنم. چون وقتی یک پروژه را برآورد می‌کنم خصوصاً در ابتدای آن، زمانی که مشتری می‌گوید می‌خواهم یک فیسبوک برای سگ‌ها داشته باشم :-)) و ما آن را برآورد می‌کنیم. در شروع کار، من اطلاعات خیلی کمی در مورد آن دارم. هر چه بیش‌تر پیش می‌روم درک بیش‌تری از مشکلات پروژه پیدا می‌کنم و برآوردی بهتری می‌کنم. فکر می‌کنم یک اصطلاح برای آن وجود داشته باشد: مخروط عدم قطعیت (Cone of Uncertainty).درست است.می‌توانید این را توضیح دهید؟بله، حتماً. چند دقیقه پیش در مورد وضعیت نامطلوبِ سرمشق‌های برآورد صحبت کردیم. یکی از جنبه‌هایی که وضعیت سرمشق‌ها نامطلوب است این است که هنوز هم افراد در زمان اشتباهی در پروژه‌ها برآورد می‌کنند و بار زیادی به برآوردها تحمیل می‌کنند. [برآوردهایی] که قبل از آن‌که بدانند چه می‌کنند تهیه شده است. فکر می‌کنم تمام جنبه‌های برآورد، چند وجهی هستند. تقریباً هر چیزی که از آن صحبت می‌کنیم، یک دیدگاه کسب‌وکاری و دیدگاه نظرِ فنی دارد. دیدگاه کسب‌وکاری سالم و ناسالم و همین‌طور دیدگاه فنی سالم و ناسالم. به نظر من هیچ چیز ناسالمی در این نیست که کسب‌وکار در روز صفر پروژه، قبل از این‌که هیچ کاری انجام شده باشد، بخواهد بداند پروژه دقیقاً چقدر طول می‌کشد و چقدر هزینه دارد؟ این درخواست برای کسب‌وکار منطقی است. چیزی که منطقی نیست این است که افراد فنی بروند و وانمود کنند که چیزی که خواسته شده را به آنان داده‌اند. چون در روز صفر پروژه همان‌طور که گفتید مجهولات زیادی وجود دارد. ممکن است بی‌ثباتی‌هایی داشته باشیم. انواع مختلفی از بی‌ثباتی خواهیم داشت. بی‌ثباتی در تعداد کارمندان، به طور خاص چه کسانی عضو کارمندان خواهند بود؟ پروژه کی شروع خواهد شد؟ کارمندان کی در دسترس قرار می‌گیرند؟ دقیقاً چه ویژگی‌هایی در مجموعه قرار خواهند گرفت؟ توصیف جزئیات پیچیدگی‌های این ویژگی‌ها و … . ما بی‌ثباتی‌های بی‌شماری در روزهای نخست پروژه داریم. یکی از روش‌هایی که من در این مقطع می‌پسندم این است که سازمان لیستی از پروژه‌های قبلی که انجام داده است داشته باشد، که شامل هزینه و نیرو و زمان‌بندی است. بنابراین حتی در روز صفر پروژه کسب‌وکار می‌تواند بگوید ما فکر می‌کنیم پروژه‌ی جدید از لحاظ حجم چیزی شبیه به فلان پروژه است که بر اساس اطلاعات گذشته‌ی ما ۱۵۰۰ نفر/ساعت و ۴ ماه طول کشید. بنابراین پس از این افراد فنی می‌توانند بازگردند و بگویند بله به نظر ما هم این شبیه فلان پروژه است و یک برآورد کلی -چیزی مانند آن‌که با انگشت در هوا نگه داشتن مسیر باد را تشخیص دهیم- فکر می‌کنیم در همان محدوده باشد. این بدین معنی است که با پیشرفت بیشتر کار ممکن است دو برابر بیشتر یا کم‌تر باشد. این فکر منطقی است. یا ممکن است افراد فنی بازگردند و بگویند نه، من فکر می‌کنم شما فلان پروژه را در نظر دارید در حالی که واقعاً منظورتان فلان چیز و بهمان چیز دیگر هم هست و وقتی همه‌ی این‌ها را تجمیع کنیم چیزی شبیه به بیسار می‌شود که به میزان چشم‌گیری بیشتر است. می‌توانید این گفتگوها را در روزهای خیلی ابتداییِ پروژه داشته باشید. این‌ها به شما اعداد و ارقام نمی‌دهند و اما حداقل انتظارات شما را در محدوده‌ی مناسبی قرار می‌دهند.مفهوم مخروط عدم قطعیت به ما می‌گوید زمانی پروژه‌های نرم‌افزاری با سطوح بالای تغییر که از تمامی منابع سرچشمه می‌گیرند، شناخته می‌شوند که پروژه واقعاً در مسیر قرار بگیرد. از مجموعه‌ی ویژگی‌ها، عدم قطعیت‌های معماری، و عدم عطعیت‌های کارمندان گرفته تا چیزهایی مثل این‌که مفهوم پروژه تا چه حد در حین پروژه تغییر خواهد کرد و انواع عدم قطعیت‌های دیگر وجود دارد. اگر ما کارمان را در بخش مدیریت فنی خوب انجام دهیم، تلاش خواهیم کرد به منشأهای عدم قطعیت هجوم برده تا میزان تغییر را کاهش دهیم. اگر کارمان را خیلی خوب انجام دهیم، این کار را به ترتیب انجام خواهیم داد و ابتدا به منشأهای دارای بی‌ثباتی زیاد هجوم می‌بریم. یعنی در هر برهه از پروژه به منشأ دارای بیشترین میزان بی‌ثباتی هجوم می‌بریم طوری که تمامی منشأهای دیگر نسبت به مواردی که تا به حال به آن‌ها هجوم برده‌ایم بی‌ثباتی کم‌تری داشته باشند. این فعالیت‌ها است که مخروط عدم قطعیت را شکل می‌دهد و بی‌ثباتی را به شدت و به سرعت کاهش می‌دهد. بسیاری از تیم‌ها این‌طور عمل نمی‌کنند. تیم‌هایی را می‌بینیم که سخت‌ترین کار را برای آخر کار می‌گذارند که از منظر برآورد کنترل پروژه مطلقاً بدترین کار ممکن است :-) بنابراین مخروط عدم قطعیت راهی برای توصیف آن چیزی است که می‌تواند در یک پروژه‌ی سالم اتفاق بیفتد و به هیچ وجه توصیفی از آن‌چه که در تمام پروژه‌ها اتفاق می‌افتد نیست.این‌طور به نظر من می‌رسد که عدم قطعیت و مدیریت مخاطرات (Risk Management) خیلی به هم نزدیک هستند یا تقریباً یکسان هستند.فکر می‌کنم اگر نگاهتان را به مدیریت مخاطرات گسترده‌تر کنید، این‌طور باشد. وقتی ما در شرکت خودمان از مدیریت مخاطرات صحبت می‌کنیم معمولاً میان مدیریت مخاطرات ذاتی و اتفاقی تفاوت قائل می‌شویم. آن‌چه در پروژه‌های نرم‌افزاری می‌بینیم این است که همیشه روی مخاطرات اتفاقی تمرکز می‌کنیم. مثل این‌که فلانی و بهمانی پروژه را ترک کنند، یا این‌که فلان یا بهمان روش فنی جواب ندهد. اما فکر می‌کنم در اکثر پروژه‌ها مخاطرات اتفاقی در واقع در مقایسه با مخاطرات ذاتی ناچیز هستند. می‌توانیم این‌ها را مخاطرات عمومی هم بنامیم. مخاطرات عمومی یا ذاتی، مخاطراتی شبیه به این هستند که ما کارمان را در فهم نیازمندی‌ها خوب انجام نمی‌دهیم و [در نتیجه] مجبور خواهیم شد دوباره‌کاری کنیم. زمان زیادی را صرف ساختن چیز اشتباهی می‌کنیم و آن را به مشتری نشان می‌دهیم و آن‌ها می‌گویند ما این را نمی‌خواستیم و آن چیز دیگر را می‌خواستیم. کیفیت پایین هم یکی دیگر از مخاطرات فجیع ذاتی است. تیم‌های پروژه‌ی زیادی را می‌بینیم که کاری را بسیار عجولانه انجام می‌دهند و بخش زیادی از کار کیفیت را به تعویق می‌اندازند. بدهی فنی (Technical Debt) بدی را در حین پیشرفت کار انباشت می‌کنند. کارشان را روی پروژه انجام می‌دهند و فکر می‌کنند که در حال پیش‌رفت هستند اما در واقع به صورت غیر رسمی، در حال انباشت کردن مقدار زیادی کارِ رفع خطا هستند. این در واقع باعث ناپایدار شدن برآوردهای کنترل پروژه می‌شود. فکر می‌کنم خوب است که روی مخاطرات منحصر به فرد اتفاقی تمرکز کنیم؛ اما وقتی که به مخاطرات ذاتی -مخاطراتی که تقریباً در تمامی پروژه‌ها واقعاً رخ می‌دهند- بنگریم، [خواهیم دید] که میان کارهایی که برای باریک کردن مخروط عدم قطعیت انجام می‌دهیم و کارهایی که برای مدیریت مخاطرات ذاتی در پروژه‌ها انجام می‌دهیم، همپوشانی زیادی وجود دارد.چیزهایی مثل اسکرام، یا [متدولوژی‌های] چابک یا روش‌هایی که میزان تکرارکنندگی زیادی دارند هم هستند که در واقع مخاطرات را کاهش می‌دهند؛ حداقل بسیاری از مخاطراتی که شما توضیح دادید را کاهش می‌دهند. چون اگر بخواهم هر دو هفته یک‌بار چیزی که کار می‌کند را تحویل دهم یعنی چیزی که باید توسط یک سرویس تست و دیگر ذی‌نفعان مورد پذیرش قرار بگیرد، این باعث کاهش مخاطره‌ی انجام نشدن کار می‌شود.من عمدتاً به این شکل می‌بینمش -البته روی آن تأکید زیادی هم دارم- که آیا این واقعاً یک پیاده‌سازی کاملاً وفادار به اسکرام است؟ و آیا ما داریم دقیقاً در مورد اسکرام صحبت می‌کنیم؟ فکر می‌کنم بیش از حد بارِ کلمه‌ی چابک، شده و در حال حاضر فریبنده و آبکی شده است. به حدی که اگر تیمی بگوید که چابک کار می‌کند به من هیچ اطمینانی در رابطه با این‌که روش کار آن‌ها بهتر از آبشاری باشد، نمی‌دهد. فرض کنیم تیمی بگوید که از اسکرام استفاده می‌کند و حقیقتاً اسکرام انجام دهند و فقط حرف آن را نزده باشند و یک پیاده‌سازی تا حد زیادی وفادار به اسکرام داشته باشند. در این صورت، فکر می‌کنم بخشی از آن‌چه در اسکرام خیلی خوب جواب می‌دهد این باشد که روشی که در اسکرام جا انداخته می‌شود در واقع این استعداد نهانی را دارد که به برخی از مخاطرات ذاتی در پروژه‌ها هجوم ببرد. بنابراین این خیلی وابسته به این است که تیم یک پیاده‌سازی با وفاداری بالا به اسکرام داشته باشد.شما به دوره‌های دو هفته‌ای اشاره کردید. بله اگر تیم حقیقتاً دوره‌ها را کوتاه نگه دارد و چیزی را پایان هر دوره تحویل دهد، به چند طریق کمک می‌کند. یک راه این است که اگر از نظام (Discipline) پیش‌برد نرم‌افزار به سمت یک سطح قابل انتشار از کیفیت پیروی کنیم، به بررسی مخاطرات عمومیِ مربوط به کیفیت پایین کمک کرده‌ایم. اما بسیاری از تیم‌ها را می‌بینیم که از اسکرام استفاده می‌کنند و این‌کار را انجام نمی‌دهند. این یکی از حالت‌های اصلی شکست در اسکرام است. این که تیم‌ها نظام نگه‌داشتن نرم‌افزار در یک سطح قابل انتشار از کیفیت را ندارند. و وقتی چنین کاری را انجام می‌دهند مقدار زیادی از مزایای اسکرام را از دست می‌دهند. صِرف این‌که ما هر دو هفته یکبار [مؤلفه‌ها را] ادغام می‌کنیم حس بهتری از پیش‌رفت نسبت به آن‌چه در حالت آبشاری انجام می‌دهیم به ما می‌دهد. فرض کنید نیازمندی‌هایمان را به صورت دسته‌های بزرگ انجام داده‌ایم و بیشتر آن را در ابتدای کار انجام داده‌ایم. بنابراین طرح‌ریزیِ اسپرینت را انجام می‌دهیم و آن را به یک دوره‌ی دو هفته‌ای نگاشت می‌کنیم. تصور می‌کنیم این دوره‌ی دوهفته‌ای حدود ده درصد از نیازمندی‌های کلی پروژه را برآورده می‌کند. خوب اگر به انتهای دوره‌ی دو هفته‌ای برسیم و فقط نیمی از کار را انجام داده باشیم -به عبارت دیگر تنها پنچ درصد از پروژه را انجام داده باشیم- این یک داده‌ی اولیه‌ی خیلی قوی به ما می‌دهد که پروژه‌ی ما احتمالاً دو برابر بیشتر از آن‌چه فکر می‌کردیم طول خواهد کشید. این یک تضمین صد درصدی نیست اما باعث می‌شود سؤال ایجاد شود و باعث می‌شود این سؤال زودتر ایجاد شود. وقتی به دوهفته‌ی دوم وارد می‌شویم می‌توانیم بگوییم خود را می‌رسانیم و یا این که بگوییم همچنان با نیمی از آن سرعتی که فکر می‌کردیم پیش خواهیم رفت. دو هفته‌ی دیگر یک نقطه‌ی بررسی (Check Point) جدید خواهیم داشت. این عالی است. در پروژه‌های آبشاری سنتی که برای بیست هفته طرح‌ریزی شده بود، به راحتی ممکن بود پانزده هفته در پروژه پیش رویم پیش از آن‌که به فکر بیفتیم که مشکلی داریم. در بسیاری موارد ممکن بود نوزده و نیم هفته پیش برویم، پیش از آن‌که به این مشکل اقرار کنیم. اما اجرای خوب از یک پیاده‌سازی اسکرام ممکن است بعد از دو تا چهار هفته پس از طرح‌ریزی متوجه این مشکل شویم. بنابراین به لحاظ مدیریت مخاطرات عمومی، افکار واهی و برآوردهای کم، خیلی تأثیر گذار است.مسئله‌ی دیگر این است که ما به موضوع مدیریت مخاطرات رسیدیم. مدیریت مخاطرات شامل کنترل مخاطرات، مدیریت مخاطرات، اولویت‌بندی مخاطرات و ... می‌شود. اما نقطه‌ی شروع همه‌ی این‌ها شناسایی مخاطرات است. فکر می‌کنم یکی از چیزهایی که در اسکرام خصوصاً با دوره‌های کوتاه، تعبیه شده است این است که اگر در یک دوره آن‌چه که تصور می‌کردیم را تحویل ندهیم، باعث می‌شود از خود بپرسیم چرا این‌طور شد؟ این طبیعتاً به سرعت و مکرر موجب شناسایی مخاطرات می‌شود. بنابراین [با این که] اسکرام هرگز مستقیماً از شناسایی مخاطرات صحبت نمی‌کند، این مفهوم شناسایی مخاطرات اساساً از آن نتیجه می‌شود. با یک پیاده‌سازیِ با وفاداری بالا به اسکرام، شناسایی مخاطرات مداوم و زودهنگام را به دست می‌آوریم. اگر بتوانیم مخاطرات را زودهنگام شناسایی کنیم معمولاً گزینه‌های قدرت‌مندتری برای رسیدگی به آن مخاطرات داریم. در نتیجه همه چیز بهتر کار خواهد کرد. بنابراین بله، فکر می‌کنم اگر اسکرام بر اساس کتاب و با وفاداری بالا اتخاذ شود این استعداد نهفته برای کاهش مخاطرات مهمِ ذاتیِ سنتی و منشأهای بی‌ثباتی در نرم‌افزار را دارد.چیز دیگری که می‌خواهم توضیح دهم این است که یک زیرجریان (Undercurrent) در اسکرام وجود دارد که به نظر من با برآورد مغایر است. در اسکرام یک جوّ فرهنگی وجود دارد که فکر می‌کنم جزئی از سرمشق‌های اسکرام نباشد. اما اگر ادبیات اسکرام از جمله کتاب اصلی آن که توسط کِن شوِیبر و ... نوشته شده است را بخوانید، تأکیدی قوی بر توانایی اسکرام در انعطاف‌پذیری و پاسخ دادن به تغییرات و نیازمندی‌ها وجود دارد. به طوری که هر چند واقعاً ذکر نمی‌شود خیلی راحت ممکن است به این ایده برسید که تنها راهی که باید همواره یک پروژه‌ی اسکرام را اجرا کنیم این است که نیازمندی‌ها را در ابتدا تثبیت نکنیم و حتی تلاشی برای این کار نکنیم؛ صرفاً باید نیازمندی‌ها را در حین انجام کار شناسایی کنیم و در حین انجام کار آن را دگرگون کنیم و فقط از همین طریق آن را انجام دهیم. اگر این روش را اتخاذ کنیم -که ممکن است در برخی موارد جواب دهد- از هرگونه اندیشه‌ی برآوردهای طولانی مدت‌تر دست برداشته‌ایم. بنابراین زمانی که از اسکرام به این شکل سرمشق گرفته شود -به طور خاص اگر نیازمندی‌ها فقط دوره به دوره انجام شوند- ما از توانایی خود برای برآورد کردن، به شکل ضعیفی استفاده کرده‌ایم. من نمی‌گویم که این خوب است یا بد است، من می‌گویم وقتی که از [این] ترکیب اسکرام و برآورد کردن صحبت می‌کنم، این ترکیبی است که جواب نخواهد داد.چطور برآوردهای اسکرام و آن‌چه که واقعاً تحویل داد‌ه‌ایم را ارزیابی می‌کنید؟ مثلاً یک پروژه‌ی اسکرام را شروع می‌کنیم و برآوردهایمان را انجام می‌دهیم و تصمیم می‌گیریم که پنج ویژگی را می‌خواهیم. معمولاً [این کار را] تک به تک انجام نمی‌دهیم،‌ احتمالاً دو ویژگی را به صورت موازی انجام می‌دهیم. برآوردمان را [با] درجه‌ی داستان (Story Point) انجام می‌دهیم، و یک سرعت (Velocity) داریم. بعد از مدتی خیلی دشوار است که آن‌چه که قبلاً انجام داده‌ایم را با نیازمندی‌های اولیه تطبیق دهیم. چون هرگز میزان زمانی را که برای یک نیازمندی صرف کرده‌ایم را یادداشت نکرده‌ایم.فکر می‌کنم چند سؤال در اینجا وجود دارد. روشی که من با آن اسکرام و برآورد آشتی می‌دهم این است که -صادقانه بگویم، من فکر نمی‌کنم کار زیاد یا تغییر بزرگی در اسکرام نیاز باشد که تا این آشتی برقرار شود- از یک رویکرد دسته‌ای به نیازمندی‌ها در ابتدای پروژه استفاده شود. این به آن معنی نیست که بعداً نمی‌توانیم نظرمان را عوض کنیم. تمام فکر اصلی بیانیه چابک‌سازی (Agile Manifesto) در XP پذیرفتن تغییرات بود. این نبود که تعهد ندهید بلکه این بود که خودتان را به نحوی آماده کنید که وقتی تغییرات اتفاق افتاد بتوانید به آن پاسخ دهید و آن را بپذیرید. اسکرام به شما قابلیت خوبی در پذیرفتن تغییرات می‌دهد اما این به آن معنی نیست که شما نمی‌خواهید ثبات داشته باشید. بنابراین با قرار دادن حد کافی از تعاریف در نیازمندی‌ها این آشتی برقرار می‌شود. منظورم [تعریف کردن] هر اندازه از مجموعه کل نیازمندی‌هایتان است که می‌توانید در ابتدای پروژه‌ی اسکرام داشته باشید. این شامل این است که آن‌ها به قدری خوب تعریف شده باشند که بتوانید از برآوردهای درجه‌ی داستان برای آن استفاده کنید. سپس برآوردهای درجه‌ی داستان را انجام می‌دهید. محاسبه می‌کنید که در مجموع چند درجه داستان در پروژه دارید و آن را در زمان‌بندی نگاشت می‌دهید: تعداد داستان‌ها در هر دوره. سپس کار توسعه‌ی جزئیات پروژه را شروع می‌کنید و سرعت‌تان را اندازه می‌گیرید. این به شما توانایی چشمگیری می‌دهد تا بر این که آیا واقعاً درحال پیش‌رفت بر اساس طرح‌ریزی هستید و این که آیا واقعاً به برآوردهایتان دست می‌یابید، نظارت کنید. همیشه تصوری از آن‌چه که فکر می‌کنید سرعت اولیه‌تان خواهد بود دارید و بعد از دو یا سه دوره، داده‌های واقعی پروژه را خواهید داشت که می‌توانید از آن برای اصلاح کردن برآوردهایتان استفاده کنید. این داده‌ها یا به شما می‌گویند برآوردهای اولیه شما خوب بودند و یا این که نیاز به اصلاح دارند. در هر صورت هنوز هم در ابتدای پروژه هستید و این توانایی را دارید که بگویید ما فکر می‌کردیم سرعت‌مان ۲۵ درجه داستان در هر دوره خواهد بود اما الان که دست به کار شدیم با سرعت ۱۵ درجه داستان در هر دوره پیش می‌رویم. بنابراین اگر با همین سرعت پیش برویم ۶۷٪ از برآورد تجاوز خواهیم کرد. هیچ کس دوست ندارد که این را بشنود. کسی خبر بد را دوست ندارد. اما اگر به جای دیرتر گفتن، زودتر به آن‌ها بگویید رضایت بیشتری دارند. اسکرام قابلیت خوبی برای این به شما می‌دهد. اگر نیازمندی‌هایتان را از پیش تعریف کنید و تا سطحی از جزئیات این کار را انجام دهید که بتوان به آن درجه‌ی داستان نسبت داد. اتفاقی که می‌افتد این است که شاید شما چند دوره پیش بروید و تغییرات زیادی رخ ندهد و شما اولویت‌ها را به صورت نزولی تحویل می‌دهید. همه چیز خوب پیش می‌رود تا این‌که تغییرات رخ می‌دهند. این خیلی خوب است چون اسکرام سازوکار فوق‌العاده‌ای برای پذیرفتن این تغییرات به شما می‌دهد. می‌توانیم تغییرات پیشنهادی را در قالب درجه داستان برآورد کنیم و اولویت آن را در مقایسه با داستان‌های موجود در انباره‌ی انتشار (Release Backlog) تعیین کنیم. می‌توانیم آن‌ها را اضافه کنیم و بدانیم زمان‌بندی‌مان چه‌قدر زیاد می‌شود، چون چیزی به آن اضافه می‌کنیم و سرعت‌مان را می‌دانیم. یا این‌که می‌توانیم ویژگی‌های جدید را با کارهای کم اولویت‌تر در انباره جابجا کنیم و مجموع درجات داستان را ثابت نگه‌داریم.یکی از چیزهایی که برای من آزاردهنده است این است که در ساختار اسکرام ضرورتاً به شکلی است که گویی یک بهشتِ برآورد است: به ما قابلیت خوبی در ارائه‌ی برآوردهای عددی کیفی زودهنگام می‌دهد، به ما قابلیت بررسی و اصلاح زودهنگام برآوردها را در حین کار می‌دهد؛ به ما ساختار و نظامی برای صحبت کردن در مورد تغییرات را در حین انجام کار می‌دهد؛ به نحوی که برآوردهای قبلی را به طور کامل باطل نمی‌کند. بنابراین ابزار بسیار خوبی برای برآورد در اختیار شماست. اما [همه این‌ها در صورتی است که] تیم حاضر باشد این‌طور به اسکرام نگاه کند و به همین خاطر است که زمانی که درباره‌ی جو فرهنگی در تیم‌های اسکرام صحبت می‌کنم آزرده می‌شوم. گاهی تیم‌ها فکر می‌کنند برآورد کردن با اسکرام در تضاد است. من فکر می‌کنم خلاف این درست باشد. فکر می‌کنم اکثر کسب‌وکارها مایل‌اند تصوری از پایان کار و آن‌چه که برای آن پول صرف کرده‌اند داشته باشند. برآورد با این طرز فکرِ ارائه یک تصویر از آن‌چه کسب‌وکار برای آن خرج می‌کند، جفت و جور می‌شود.چیز دیگری که می‌گویم این است که من به شدت به این نتیجه رسیده‌ام که یکی از پاشنه‌های آشیل در توسعه‌ی چابک و تکرارشونده (Iterative) با نگاه از منظر کسب‌وکار این است که کسب‌وکارها ترجیح می‌دهند اشتباه کنند تا این‌که در ابهام باشند. منظورم این است که اگر بگوییم می‌خواهیم این مجموعه ویژگی‌ها را بسازیم که این‌قدر طول می‌کشد و این قدر هزینه دارد و به میانه‌ی پروژه برسیم و بگوییم می‌دانی چیست؟ الان تصویر بهتری داریم و می‌خواهیم برنامه‌مان را اصلاح کنیم؛ فلان ویژگی‌ها را اضافه می‌کنیم و بهمان ویژگی‌ها را حذف می‌کنیم و الان برنامه این است. کسب‌وکار در واقع با تغییر عقیده کنار می‌آید؛ با اشتباه بودن کنار می‌آید؛ اما برای شروع به چیزی واقعی نیاز دارد. بنابراین الگویی که توصیف کردم از منظر کسب‌وکار یک الگوی دوام‌پذیر و قابل پذیرش است. آن‌چه که معمولاً از منظر کسب و کار قابل قبول نیست این توصیف متعارف چابک است که می‌گوید پولی که دارید را به ما بدهید و مجموعه ویژگی‌های مورد نظرتان را هم بدهید که لازم نیست کامل باشد. ما هر دو هفته یک‌بار از شما می‌پرسیم ارزشمندترین چیز بعدی که می‌خواهید برایتان انجام دهیم چیست؟ این به شما امکان می‌دهد که حداکثر میزان ارزش را از پولی که خرج کردید دریافت کنید چون ما همیشه روی مهم‌ترین چیز باقی‌مانده کار می‌کنیم. منطقی در این [نگاه] وجود دارد. چیز بدی در این تحلیل وجود ندارد، آن‌چه که بد است این است که در اکثر موارد [این نگاه] با نحوه‌ی بودجه‌بندی و خرج‌کردن کسب‌وکار مطابقت ندارد. کسب‌وکار بودجه را صرف نمی‌کند مگر این‌که حداقل تصویری کلی از آن‌چه که برای پولش خواهد گرفت داشته باشد. بنابراین این اندیشه که به من اعتماد کن، [چون] من همیشه ارزشمندترین چیز بعدی را تحویل می‌دهم برای کسب‌وکار به این معنی نیست که شما [اجازه دارید] آن کار را انجام دهید. این ما را به موضوع برآورد بر می‌گرداند. برآورد به این هدف کسب و کار کمک می‌کند که می‌خواهد از آنچه در ازای پولش خواهد گرفت تصویری حداقلی داشته باشد.به خاطر دارم که سال‌ها پیش که اولین پروژه‌ی XP من بود، تعدادی فوق ستاره‌های آن زمان هم به عنوان مشاور حضور داشتند. کاری که کردیم این بود که نگاهی کلی به آن‌چه که در طول سال می‌خواهیم انجام دهیم انداختیم. سال را به دوره‌های سه ماهه تقسیم کردیم. به طور تقریبی میزان کاری را که در هر فصل قابل انجام بود، برآورد کردیم. این [برآورد] همیشه روی دیوار بود. همان‌طور که شما گفتید خیلی اوقات نظرمان را تغییر می‌دهیم؛ با این حال اگر کسی وارد اتاق شود می‌تواند ببیند در یک سال آینده چه خبر است و خودمان هم همیشه می‌توانستیم در میان راه ببینیم که کجا هستیم. در واقع فهم خوبی از جایی که هستیم نسبت به طرح‌ریزی بلند مدت یا سالانه یا محصول به طور کل داشتیم.نمی‌خواهم این‌طور جلوه دهم که رویکرد تکرارشونده‌ی خالص هرگز مفید نیست. فکر می‌کنم عرصه‌هایی هست که در آن مفید است مثلاً در یک زمینه‌ی اکتشافی تحقیقاتی. فکر می‌کنم یک راه برای توضیح آن -که عوام پسند نیست- این باشد: نیازمندی‌ها [به روش] آبشاری، توسعه [به روش] اسکرام. این به نوعی آن‌چه که می‌گویم را خلاصه می‌کند. فکر می‌کنم در خیلی موارد خوب کار می‌کند. اما نمی‌خواهم این را القا کنم که محیط‌های دیگری وجود ندارد که در آنجا انجام نیازمندی‌ها به روش تکرارشونده‌ی خالص مفید نباشد. اگر من در فضایی در حال ظهور قرار داشته باشم، مثلاً اگر من پنج سال پیش روی برنامه‌های تلفن همراه کار می‌کردم که نمی‌دانستم و نمی‌توانستم برای یک سال طرح‌ریزی کنم چون خیلی در حال تغییر بود آن زمان، برنامه‌ام را می‌نوشتم و هر دو هفته مهم‌ترین چیز بعدی را انجام می‌دادم. اگر بازار تا این حد ناشناخته و متغیر است احتمالاً این رویکرد خیلی خوبی است. اگر در یک زمینه‌ی تحقیقاتی هستم و میزان زیادی از مجهول‌های مرکب (Unknown Unknown) دارم؛ [یعنی] حتی نمی‌دانم مجهول‌هایم چه هستند؛ آن‌وقت این‌که سعی کنم بفهمم بزرگ‌ترین مجهولات پیش‌رو چه هستند و دوهفته‌ی بعدی را روی آن‌ها کار کنم و سپس برگردم و بزرگ‌ترین مجهول بعدی را پیدا کنم، فکر می‌کنم پاسخ مناسبی باشد. نکته این است که ما در حال صحبت کردن از برآورد هستیم و با وجود این‌که این [برآورد کردن] رویکرد درستی برای مدیریت و کنترل یک پروژه با میزان زیادی عدم قطعیت است، اما این روش‌ها [ی کاملاً اکتشافی] از برآورد حمایت نمی‌کنند. بنابراین برآورد در تک‌تک پروژه‌ها ضروری نیست. فکر می‌کنم همیشه مفید است که از کسب و کار پرسید آیا به برآورد اهمیت می‌دهد؟ اما عموماً حتی لازم نیست این سؤال را بپرسیم. کسب‌وکارها از همان اول شدیداً برآورد را از شما می‌خواهند. بنابراین خیلی واضح است که کسب و کار به برآورد اهمیت می‌دهد.حتی در یک محیط استارتاپ Lean، البته این کم و بیش همان چیزی است که چند دقیقه پیش توضیح دادید. درست است؟ اگر نرخ بالایی از تجربه کردن را داریم یا این‌که ویژگی‌های جدیدی برای کاربران داریم که نمی‌دانیم می‌خواهند یا نه، برای این قبیل کارها واقعاً به برآورد نیاز نداریم.بله فکر می‌کنم در محیط استارتاپ اگر صد درصد اطمینان دارید که ایده‌ی خوبی دارید به این شکل باشد. مثلاً اگر به عقب برگردیم و من Lotus 1-2-3 باشم و VisiCalc از پیش در بازار وجود داشته باشد و من می‌دانم که مأموریت من این است که می‌خواهم نرم‌افزار صفحه گسترده‌ی نسل بعد را تولید کنم. اگر بخواهم محصولی جالب و پیش‌گام و تغییردهنده‌ی دنیا را به صحنه بیاورم، مجهولات زیادی از لحاظ نیازمندی در اینجا وجود ندارد. باید نسل بعدی صفحه گسترده را منتشر کنم. بله ممکن است جزئیاتی در ویژگی‌ها باشد، اما تا حد زیادی آبشاری است و می‌توانید با آن مثل یک پروژه‌ی آبشاری رفتار کنید. بنابراین لزوماً تمام استارتاپ‌ها چنین رویکردی ندارند. استارتاپ‌های دیگر وجود دارند که افراد فکر می‌کنند زمینه‌ای در حال ظهور است و فرصت‌های بالقوه‌ی زیادی در آن هست. دقیقاً مطمئن نیستیم که این فرصت‌ها چیست. ممکن است شما یا سرمایه‌گذاران مایل باشید که پول یا سهمی از سود را صرف کاوش برای یافتن ایده‌های مفید کنید. ما موارد زیادی در اطراف خودمان نزدیک سیاتل می‌بینیم، استارتاپ‌هایی که افراد حاضرند چیزی را برای یک یا دو سال بیازمایند و می‌گویند می‌خواهیم ببینیم تا کجا می‌توانیم پیش برویم و سرمایه‌گذاران بر اساس ایده، علاقه و زمینه‌ی مملو از فرصت‌های بالقوه، گاهاً حاضر به صرف مقدار زیادی پول هستند.وقتی به کسب و کارهای جاافتاده می‌رویم فکر می‌کنم کمی متفاوت باشد. در یک کسب‌وکار جاافتاده، کسب و کار می‌خواهد بداند اگر صدهزار دلار یا یک میلیون دلار خرج می‌کند در قبال آن چیزی به دست می‌آورد و بنابراین این‌جاست که دوباره به فکر برآورد برمی‌گردیم. آن‌ها به برآورد نیاز دارند قبل از این‌که حتی حاضر باشند در مورد فرصت کسب و کاری که به پول نیاز دارد صحبت کنند. همیشه استثناهایی در همه چیز وجود دارد. اما متداول‌ترین حالت در اینجا این است که کسب و کارها به هر چیزی که نیاز به هزینه‌ی زیادی دارد نگاه می‌کنند و می‌خواهند به نوعی آن را مورد بررسی تجاری قرار دهند. این ممکن است رسمی یا غیررسمی باشد اما می‌خواهند این بررسی را انجام دهند. این [بررسی] شامل هزینه و سود است. هر دوی این‌ها خیلی تقریبی هستند. همه‌ی ما این را می‌دانیم؛ اما این به آن معنی نیست که این کار را به طور کل رها خواهیم کرد. کاری که واقعاً باید انجام دهیم این است که بفهمیم چطور این اعداد را بهتر کنیم. بنابراین از نظر افراد فنی کاری که باید انجام دهیم این است که تقریب بهتری از این اعداد ارائه دهیم. این کار ماست که بدانیم توانایی واقعی تحویل سازمان چیست تا بتوانیم به کسب و کار بگوییم که هزینه چقدر است. در دنیای بی‌نقص، کسب‌وکار هم، به همین میزان در برآورد فرصت‌های بالقوه‌ی کسب و کار خوب است و می‌تواند سود را محاسبه کند. اما خوب این مسئله‌ی آن‌هاست :-) مسئله‌ی ما این است که کارمان را به بهترین شکلی که می‌توانیم برای محاسبه‌ی هزینه‌ها انجام دهیم.چطور این کار را انجام دهیم؟ چه روش‌های خوب و بدی در برآورد کردن وجود دارد؟ اگر کسی از من بخواهد که فیس‌بوکی برای سگ‌ها بسازم. چطور به برآورد برسم؟فکر می‌کنم قبلاً به چند مورد کلیدی اشاره کرده‌ایم. یکی این است که قبل از آنکه بتوانیم برآوردی کنیم که ارزش زیادی داشته باشد، باید به اندازه‌ی کافی در مخروط [عدم قطعیت] پیش‌رفته باشیم تا بدانیم از چه صحبت می‌کنیم. بنابراین این‌که تشخیص دهیم که در کجای مخروط عدم قطعیت قرار داریم کلیدی است و اگر هنوز در سمت پهن مخروط باقی مانده باشیم نمی‌توانیم قطعیت زیادی داشته باشیم. بنابراین بدون آمادگی فکری، برآورد نکنید. اعداد حسی و تصادفی را که کسی از خود در می‌کند، به عنوان برآوردهای معنی‌دار تلقی نکنید. این‌ها واقعاً نکات کلیدی هستند. یک نکته‌ی کلیدی دیگر که فکر می‌کنم در مورد آن صحبت کردیم، این است که اطمینان حاصل کنیم تمایز واضحی میان برآوردها، اهداف و تعهد وجود دارد. ما می‌خواهیم مطمئن شویم که خودمان را با این افکار گیج نمی‌کنیم که واقعاً یک برآورد کرده‌ایم یا این‌که با فکر گروهی یک هدف یا تعهد را پذیرفته‌ایم بدون این‌که واقعاً آن را بسنجیم و برآورد کنیم. در مورد داده‌های تاریخی هم صحبت کردیم. از چند طریق در مورد نگه‌داری هزینه‌ها، زمان‌بندی‌ها و میزان نیروی مورد نیاز در پروژه‌های گذشته صحبت کردیم؛ این یک نوع از اطلاعات تاریخی است. گفتیم که با یک برآورد اولیه‌ی پروژه‌ی اسکرام را شروع کنیم، اما به محض این‌که بتوانیم سرعت واقعیِ مشاهده شده را محاسبه کنیم، فرصت داریم [برآورد را] اصلاح کنیم؛ این نوع دیگری از داده‌های تاریخی است که من به آن داده‌های پروژه می‌گویم. این با داده‌های سازمان متفاوت است. داده‌های پروژه در واقع قدرت‌مندترین نوع داده‌های تاریخی برای اهداف برآورد هستند. اگر این قبیل کارها را انجام دهیم از اکثر خطاهای بارز در برآورد جلوگیری کرده‌ایم و حداقل تا نیمه‌ی راه پیش رفته‌ایم.مشکل برآورد نرم‌افزار در عمل این نیست که افراد تلاش خالصانه می‌کنند ولی از روش اشتباهی استفاده می‌کنند. مشکل بیشتر این است که افراد تلاش خالصانه نمی‌کنند یا این‌که اصلاً نمی‌دانند تلاش خالصانه چه هست. بنابراین اولین قدم در انجام یک کار این است که بگویم می‌خواهم کاری عاقلانه انجام دهم و به آن تحت عنوان یک فعالیتِ برآورد، توجه می‌کنم و با هم به آن خواهیم پرداخت تا یک برآورد واقعی انجام دهیم. این بزرگ‌ترین قدمی است که سازمان برمی‌دارد. وقتی که به قدم دوم می‌رسیم، استفاده از نوعی از داده‌های تاریخی واقعاً راه‌گشاست. البته قطعاً سرمشق‌های بهتر یا بدتری وجود دارد که به نظر من نگرانی ثانویه است. برای پروژه‌های کوچک که تیم‌های دست‌نخورده داریم، تجزیه‌ی یک برآورد که در آن هر یک از اعضای تیم یک بخش را برآورد می‌کنند، می‌تواند تا حد قابل قبولی برای یک پروژه‌ی کوچک و کوتاه جواب دهد.متأسفانه یکی از الگوهای متداولی که در سازمان‌هایی -که خالصانه برای بهبود برآوردهایشان تلاش می‌کنند ولی فهم درستی از آن ندارند- می‌بینیم این است که قبل از موعد به سطح جزئیات زیادی وارد می‌شوند. این مایه‌ی ناراحتی است. چون کار به شدت زیادی انجام می‌دهند و انگیزه‌شان خوب است اما زیادی کار می‌کنند. روش مورد استفاده‌شان روش درستی نیست. بنابراین گاهی سخت است که شرکت‌ها را متقاعد کنید که می‌توانند با کار کم‌تر و وارد شدن به جزئیات کم‌تر به برآوردهای بهترِ زودهنگام‌تری دست‌یابند. افراد نرم‌افزاری گرایش به ورود به جزئیات دارند اما در حقیقت وقتی وارد پروژه‌های با اندازه‌های مختلف می‌شویم، برآورد بر اساس داده‌های تاریخی و براساس صفاتی در سیستم که قابل شمارش‌اند و ... [کاملاً مفید است]. این‌ها، سرمشق‌هایی هستند که به ما در ارائه‌ی برآوردهای معنی‌دار و دقیق‌تر در ابتدای پروژه کمک می‌کنند. مگر این‌که در مورد یک پروژه‌ی دو یا سه نفری صحبت کنیم که چند ماه بیشتر طول نمی‌کشد. برای پروژه‌های بزرگ‌تر لازم است به جای استفاده از عقیده [خبره] یا لیست وظایف، به سراغ چیزی که من در کتابم به آن شمارش و محاسبه می‌گویم برویم.الان من غافل‌گیر شدم. چون من فکر می‌کردم بهترین راه این است که آن را تقسیم کنیم. شاید نه با جزئیات کامل اما حداقل این‌که نیازمندی‌ها را جمع‌آوری کنیم و آن‌ها را تقسیم کنیم و هر تکه را برآورد کنیم. در روش شمارش، چه چیزی را می‌شمارید؟ اخیراً مجموعه‌ای از نیازمندی‌های خیلی سطحی از یک مشتری گرفتم. او می‌خواست بداند که هزینه‌اش چقدر است. من با خودم گفتم بیا بشماریم. فیلدها را بشماریم، دکمه‌ها را بشماریم اما بعد از آن کمی احساس شک کردم که درست است یا نه. رئیسم هم پرسید: دیدم که داری می‌شماری اما...:-) در این مورد فهمیدنش سخت است. مواردی هستند که چیزهایی که گفتید نشانه‌های خوبی از کلیت قلمروی پروژه هستند؛ نمی‌توانم در مورد خاص شما بگویم که این‌طور است یا نه. به طور کلی چون بسیاری از تیم‌ها از اسکرام استفاده می‌کنند، فکر می‌کنم درجه‌ی داستان در دسترس‌ترین چیز برای شمارش باشد. تفاوت چشم‌گیری میان بررسی یک لیست ویژگی‌های جزئی و برآورد نیرو یا زمان لازم برای هر یک از آن‌ها به جای برآورد کردن درجه‌ی داستان آن‌ها وجود دارد. وقتی درجه‌ی داستان را برای ویژگی‌ها برآورد می‌کنیم، احتمالاً تصوری کلی از این‌که هر درجه داستان به چند روز یا ساعت یا هفته تبدیل می‌شود، داریم. با این حال اندازه‌ی آن را با درجه‌ی داستان بیان می‌کنیم. بعداً چون همه چیز را با درجه‌ی داستان برآورد کرده‌ایم و درجه‌ی داستان یک مقیاس نسبی است، مقادیر مختلف درجه داستان‌ها وابسته به یکدیگر هستند. زمانی که پروژه آغاز شود ما این توانایی را داریم که درجه داستان‌ها را با توجه به داده‌های واقعی پروژه اصلاح کنیم. اگر از اسکرام استفاده کنیم می‌توانیم خیلی زود در ابتدای پروژه این کار را انجام دهیم. مثلاً دو یا چهار هفته بعد از شروع پروژه باید اصلاحاتی معقول داشته باشیم. از سوی دیگر اگر دقیقاً همان کار را و دقیقاً با همان سطح از جزئیات اما بر اساس تلاش [لازم برای انجام کار] برآورد کنیم، ممکن است منجر به خوش‌خیالی شود یعنی بگویم من فکر می‌کردم این سه روز طول بکشد اما وقتی شروع به کار کردم، متوجه شدم که نمی‌‌شود. ممکن است چون می‌خواهم در سه روز تمام شود لازم شود میان‌بر بزنم در نتیجه بدهی فنی وارد پروژه کنم. فکر می‌کنم حتی اگر از یک دید سطحی، عمل برآورد کردن در هر دو، خیلی یکسان به نظر برسد اما در تحرکات (Dynamics) کاملاً متفاوت باشند.اما اگر درجه داستان‌ها را بشمارید هنوز هم به فهم خوبی از نیازمندی‌ها نیاز دارید. درست است؟به فهم کافی از نیازمندی‌ها نیاز دارید تا بدانید برای یک داستان مقیاس درجه‌ی آن در کجا قرار می‌گیرد. اگر درجه‌ی داستان را بر اساس کتاب انجام دهید مقیاس آن بی‌نهایت قابل تقسیم نیست. این‌طور نیست که بگوییم ۱، ۲، ۳، ۳.۱، ۳.۲ و … . اعداد متداول درجه داستان، اعداد فیبوناچی هستند ۱، ۲، ۳، ۵، ۸، … بنابراین لازم نیست بدانید که یک چیز دقیقاً ۵ است، کافی است بدانید که به اندازه‌ی ۳ کوچک نیست و به اندازه‌ی ۸ بزرگ نیست. باید به اندازه‌ای بدانیم که این گفتگو میسر باشد. لازم نیست در ذهن مان بدانیم که ۵.۵ است یا ۵.۷ هدف این سرمشق این نیست.باشه، اما در نهایت من باید درجه داستان‌ها را به هفته یا روز تبدیل کنم. درست است؟در واقع خیر. منظورم این است که در نهایت باید درجه داستان‌ها را به طرح اسپرینت تبدیل کنید و این‌که ما فکر می‌کنیم چه مقدار کار در یک اسپرینت می‌توانیم انجام دهیم...اگر مدیر من بخواهد بداند...بله. البته اگر تیمی دست نخورده داشته باشید که قبلاً تعدادی پروژه انجام داده باشد؛ که گاهاً اتفاق می‌افتد. خوشحالم که بگویم یکی از آثار جانبی برنامه‌ریزی نشده و غیر شایعِ حرکت به سمت اسکرام و [متدولوژی‌های] چابک این باشد که تیم‌ها را نسبت به قبل بیشتر در کنار هم نگه می‌دارد. این عقیده که یک تیم کارای دست‌نخورده را تجزیه کنیم در بیست سال نخست [فعالیت] من در صنعت خیلی دردآور بود. فکر می‌کنم در ده سال اخیر کم‌تر آن را دیده‌ام و فکر می‌کنم خوب باشد. اگر تیم دست‌نخورده‌ای داشته باشید، آن‌ها احتمالاً درکی سنجیده از [درجه داستان] سه، پنج یا ... دارند. بنابراین می‌توانید سرعت آن‌ها را از پروژه‌های قبلی که روی آن کار کردند بفهمید. ممکن است دقیقاً مطابق نباشد اما معمولاً خطا حدود دو برابر است و خیلی نزدیک خواهد بود. اگر تیم دست‌نخورده‌ای نداشته باشید و افراد را جمع کرده‌اید،‌ احتمالاً افراد تصورات متفاوتی از [درجه داستان] سه یا پنج دارند. بنابراین تیم باید به عنوان یک تیم، مقداری کار کند تا همگام شود. می‌توانید که این برآورد را خیلی زود در ابتدای پروژه به مدیرتان ارائه کنید و بگویید که مجموعه ویژگی‌ها ما ۲۴۰ درجه داستان است و بهترین حدس ما این است که می‌توانیم ۲۰ درجه داستان در هر دوره انجام دهیم که این پروژه را در ۱۲ دوره به پایان می‌رساند. قطعاً می‌توانید این را ارائه کنید اما می‌توانید همزمان با آن بگویید که ما سرعت تیم جدید را از روز اول اندازه خواهیم گرفت و وقتی که به دوره‌ی دوم یا سوم برسیم، یعنی ۴ تا ۶ هفته بعد از شروع پروژه، تصویری سنجیده‌تر از این‌که آیا ۲۰ درجه داستان در هر دوره قابل دست‌یابی است یا نه خواهیم داشت. حداکثر ۶ هفته دیگر برمی‌گردیم و به شما می‌گوییم که زمان‌بندی ۲۰ هفته‌ای هنوز هم واقع‌بینانه است یا باید آن‌ها را بر اساس مشاهدات تغییر دهیم.من که شگفت‌زده شده‌ام. چون خیلی وقت پیش یاد گرفتم که هنگام برآورد کردن عدم قطعیت‌ام را در برآورد با یک بازه بیان کنم. اگر کسی از من بپرسد که چقدر وقت می‌گیرد، می‌گویم بین ده تا سی روز یا ده تا سیزده روز. هر چه بازه بزرگ‌تر باشد،‌ عدم قطعیت‌ام را بیشتر بیان کرده‌ام. اگر با درجه داستان‌ها برآورد می‌کنیم این از بین می‌رود.در واقع از بین نمی‌رود چون عدم قطعیت از درجه داستان‌ها نشأت نمی‌شود، از سرعت نشأت می‌شود. بنابراین فکر می‌کنم به موضوع تمایز میان برآورد و تعهد برگشتیم. اگر مدیر من واقعاً یک برآورد از من می‌خواهد می‌توانم بگویم ما درجه داستان‌ها را شمرده‌ایم که ۲۴۰ است. اگر به سابقه‌ی افراد در این تیم و سرعت آن‌ها در پروژه‌های دیگر نگاه کنیم، به نظرمان می‌رسد سرعت‌مان چیزی بین ۱۵ تا ۲۵ درجه داستان در هر دوره باشد. هنوز به اندازه‌ی کافی اطلاعات نداریم تا مطمئن باشیم که سرعت‌مان ۱۵، ۲۰، یا ۲۵ است یا چیزی بین این‌هاست. بنابراین اگر امروز از ما برآورد بخواهید به شما بازه‌ای بر اساس ۲۴۰ درجه داستان با سرعتی بین ۱۵ تا ۲۵ درجه داستان در هر دوره می‌دهیم. اگر امروز از ما تعهد می‌خواهید،‌ تعهدمان را بر اساس حداقل بهره‌روی می‌دهیم که همان ۱۵ درجه داستان در هر دوره است. اما اگر به ما شش هفته فرصت بدهید می‌توانیم تعهد دقیق‌تر و بازه‌ی کوچک‌تری بدهیم و در حقیقت بازه نمی‌دهیم، تعهد می‌دهیم. ممکن است در ذهنمان بازه‌ای داشته باشیم اما آن زمان شرایط‌مان شبیه همان چمدان است؛ می‌دانیم که چه اندازه‌ای از چمدان نیاز داریم. ممکن است تغییراتی وجود داشته باشد که میزان زور مورد نیاز برای بسته شدن آن را تحت تأثیر قرار دهد، یعنی این‌که آیا پروژه به راحتی تمام خواهد شد یا باید مقداری اضافه‌کاری کنیم. اما تصور خیلی خوبی از تحویل کاری که سازمان از ما می‌خواهد، خواهیم داشت. ما با سازمان‌هایی کار می‌کنیم که عکس‌العمل‌های متفاوتی نسبت به این دارند. برخی‌ها می‌گویند ما الان تعهد را می‌خواهیم و اگر تنها چیزی که الان می‌توانید متعهد شوید سرعتی برابر با ۱۵ درجه داستان در هر دوره و تبعات آن است، ما امروز در فرایند طرح‌ریزی‌مان به آن احتیاج داریم و اشکالی ندارد. برخی دیگر می‌گویند متوجه هستیم که مقداری عدم قطعیت وجود دارد و ما ترجیح می‌دهیم تصویر واضح‌تری داشته باشیم. اگر ارزش بیشتری وجود داشته باشد نمی‌خواهیم عجولانه بهره‌وری شما را از آن‌چه که هست کم‌تر در نظر بگیریم. هرچند فعلاً عددی مثل ۲۰ درجه داستان در هر دوره را به عنوان سرعت در طرح‌ریزی قرار می‌دهیم و بر اساس آن زمان‌بندی می‌کنیم. اما برنامه داریم که طرح‌ریزی را در چهار تا شش هفته‌ی آینده بر اساس سرعت مشاهده شده به‌روزرسانی کنیم و می‌دانیم که این عدد قطعی تعهد شماست که می‌توانید به آن دست پیدا کنید. چون بر اساس داده‌های تاریخی و به طور خاص داده‌های پروژه است.بسیار خوب. نزدیک به پایان هستیم. سؤال آخر. ما در مورد اسکرام زیاد صحبت کردیم. اگر در اسکرام برآورد کنیم، معمولاً پوکرِ طرح‌ریزی (Planning Poker) را داریم،‌ یعنی تعداد زیادی از افراد برآورد می‌کنند. آیا این خوب است؟ و اگر بله، چرا؟بله قطعاً پوکرِ طرح‌ریزی رویکرد مثبتی است که می‌تواند خوب عمل کند. پوکرِ طرح‌ریزی مثالی از خانواده‌ای از روش‌های برآورد کردن است که با عنوان روش‌های تصمیم‌گیری گروهی ساخت‌یافته (Structured Group Decision Making Techniques) شناخته می‌شوند که در واقع همانی است که به نظر می‌رسد. افراد را در گروهی کنار هم قرار می‌دهد و ساختاری حول نحوه‌ی تصمیم‌گیری آنان شکل می‌دهد. پوکرِ طرح‌ریزی مقرراتی دارد که این ساختار را فراهم می‌کند. این مقررات شامل چیزهایی مثل این است که از مقیاس اعداد فیبوناچی استفاده می‌کنیم، هر کدام از ما جداگانه برآوردهایمان را می‌کنیم و همزمان نتیجه را نشان می‌دهیم. ممکن است مقرراتی در مورد این‌که اگر افراد بازه‌ای از برآورد داشتند یا هر کسی برآورد متفاوتی داشت، وجود داشته باشد یا وجود نداشته باشد. این یک راه انجام آن است. من فکر می‌کنم می‌تواند خوب جواب دهد. تیم‌هایی را دیده‌ایم که بخش پوکر را به معنای کلمه تعبیر می‌کنند و به اتاق کنفرانس می‌روند و عینک‌های سبز می‌گذارند و :-) فایده‌ای برای من ندارد اما اگر یک فعالیت خسته‌کننده را کمی جذاب‌تر می‌کند فکر می‌کنم ایرادی نداشته باشد.یکی از چیزهایی که در مورد پوکرِ طرح‌ریزی دوست دارم این است که تصمیم‌گیری گروهی ساخت‌یافته یک راه برای توصیف آن است. راه دیگر توصیف آن می‌تواند یک جلسه باشد. جلسات برای سوزاندن بی‌ثمر وقت بدنام شده‌اند. اکثر افراد، خصوصاً افراد فنی واقعاً از جلسات بیزار هستند. یکی از چیزهایی که من در مورد پوکر طرح‌ریزی دوست دارم این است که اگر آن را به نحوی که باید، انجام دهید، دستورالعملی برای اجرای یک جلسه‌ی خوب است. سرعت پوکرِ طرح‌ریزی باید خیلی زیاد باشد. باید روی برآورد کردن فقط در مقیاس تعیین شده تمرکز کنید و اقلام درون انباره را بررسی کنید و این باعث ادامه‌ی گفتگو می‌شود. این به آن معنی نیست که در همه‌ی موارد، هیچ‌گاه گفتگو از خط خارج نمی‌شود، اما اگر آن را بر اساس مقررات انجام دهید، ساختاری واقعاً ساخت‌یافته برای اجرای یک جلسه‌ی خوب است. دلیلی برای این‌که کسی بی‌حوصله شود وجود ندارد چون به طور منظم و پی‌درپی در حال برآورد کردن ویژگی بعدی هستند.حالا که این‌ها را گفتم و با این‌که پوکرِ طرح‌ریزی را دوست دارم و هیچ‌وقت تلاش نمی‌کنم تیمی را که از آن استفاده می‌کند و آن را دوست دارد و برای آن‌ها خوب جواب می‌دهد، را از انجام آن باز دارم اما این تنها راه ممکن برآورد کردن نیست. در کلاس‌های شرکت من یک روش جایگزین که ما تدریس می‌کنیم «دم را به برآورد بچسبان» نام دارد (این اصلاح از بازی کودکانه‌ی دم را به الاغ بچسبان برگرفته شده است-مترجم). در این روش ما مقیاسی را روی دیوار داریم که اعداد فیبوناچی روی آن نوشته شده‌اند. داستان‌های مختلف در کاغذ یادداشت‌ها نوشته شده‌اند. سپس در یک فرایند گروهی تصمیم می‌گیریم که یک کاغذ یادداشت در کجای دیوار قرار می‌گیرد، در عدد ۵، در عدد ۸، در عدد ۱۳ یا … . این مثال دیگری از روش تصمیم‌گیری گروهی ساخت‌یافته است. جزئیات آن متفاوت‌ است اما موفقیت خوبی با استفاده از این روش داشته‌ایم. من نمی‌گویم که این روش از پوکر طرح‌ریزی بهتر است یا بدتر. بعضی از گروه‌هایی که با آن‌ها کار می‌کنیم آن روش را دوست دارند. مثلاً برخی گروه‌ها این‌که به جای ایستادن، می‌نشینید و چنین چیزهایی را بیشتر دوست دارند. فکر می‌کنم در حالت کلی روش‌های تصمیم‌گیری گروهی ساخت‌یافته یکی از روش‌های خوب برای برآورد و قطعاً نسبت دادن درجه داستان‌ها به طور خاص، هستند.بسیار خوب. آیا چیز مهمی هست که من یادم رفت از شما بپرسم؟خوب، برآورد موضوع گسترده‌ای است. در‌واقع، یک موضوع اصلی‌ در مهندسی نرم‌افزار است که من را در سال‌های ابتدایی حرفه‌ام به موضوعات ساخت‌یافته‌تر و رسمی‌تر در مهندسی نرم‌افزار علاقه‌مند کرد. بنابراین من تمایل دارم بخش زیادی از توسعه‌ی نرم‌افزار را از دریچه‌ی برآورد بنگرم. یکی از دلایلی که به نظرم برآورد جالب است این است که اگر تیم پروژه در برآورد، ضعیف عمل می‌کند، می‌تواند دلایل متعددی وجود داشته باشد. اما اگر در برآوردها خوب عمل می‌کنند معمولاً به این معنی است که خوب برآورد کرده‌اند اما همچنین به این معنی است که خیلی چیزهای دیگر را هم خوب انجام می‌دهند. بنابراین فکر می‌کنم دریچه‌ی برآورد، دریچه‌ی جالبی برای از نظر گذراندن مهندسی نرم‌افزار به طور کلی باشد. اگر برآورد را به خوبی درک کنید، راه زیادی را در درکِ درست توسعه‌ی نرم‌افزار به طور کلی پیموده‌اید. بنابراین این چیزی است که حدود سی سال من را به این موضوع علاقه‌مند نگه داشته است. دوست دارم این گفتگو به سایر افراد در گرایش به برآورد و سرمشق‌های مهندسی نرم‌افزار کمک کرده باشد.فکر می‌کنم این‌طور باشد. به جز کتاب‌تان منبع دیگری هم دارید که شنوندگان ما باید در مورد برآورد نرم‌افزار بدانند؟کتاب من در بردارنده‌ی اکثر مفاهیم مهم در مورد برآورد است. در سال ۲۰۰۶ منتشر شده است و در آن زمان برخی از سرمشق‌های اسکرام به هیچ‌وجه به توسعه‌یافتگی امروز نبودند و برآورد در اسکرام به نسبت آن‌چه که در کتاب توضیح داده‌ام پیش‌رفت کرده است. شرکت من یک کلاس آموزشی آنلاین در مورد برآورد دارد که من آن را تدریس می‌کنم، ممکن است افراد به آن علاقه‌مند باشند. یکی از چیزهای مورد علاقه‌ی من یک مطلب است که چند سال پیش در مورد یک پروژه‌ی تابستانی برای ساختن یک قلعه برای بچه‌هایم، نوشتم. فکر می‌کنم چند نکته‌ی جالب در مورد برآورد در آن پروژه وجود داشت. فکر می‌کنم یکی از جالب‌ترین مطالبی باشد که نوشته‌ام :-)خوب است. استیو از شما متشکرم که در برنامه حضور داشتید.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>سید مرتضی هاشمی</author>
                <pubDate>Fri, 12 Nov 2021 01:11:51 +0330</pubDate>
            </item>
                    <item>
                <title>رسیدگی به خطاها (قسمت اول)</title>
                <link>https://virgool.io/se-radio/%D8%B1%D8%B3%DB%8C%D8%AF%DA%AF%DB%8C-%D8%A8%D9%87-%D8%AE%D8%B7%D8%A7%D9%87%D8%A7-%D9%82%D8%B3%D9%85%D8%AA-%D8%A7%D9%88%D9%84-nhigimxh99mb</link>
                <description>مطلبی که می‌خوانید ترجمه‌ی قسمت ۷ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این اپیزود، مارکوس ولتر با  مارکوس آرنو در مورد خطاها و رسیدگی به آنها در سطح معماری صحبت می‌کنند. آن‌ها در مورد انواع خطاها، گروه‌های افرادی که باید آن‌ها را بشناسند، و راهکارهای سطح بالای اثبات‌شده در این مورد بحث می‌کنند. در اپیزود بعدی جنبه‌های فنی‌تر رسیدگی به خطا از قبیل اصطلاحاتی که در کار با خطاها وجود دارد و مقایسه استثناهای چک‌شده (Checked Exception) و غیر چک‌شده  (Unchecked Exception) بررسی می‌شود.خطا چیست؟ از چه تشکیل یافته؟ چگونه باید آن را رسیدگی (Handle) کنیم؟ابتدا باید بگویم که رسیدگی کردن خطا بخش مهمی از تولید سیستم است که عموماً نادیده گرفته می‌شود. آمار نشان می‌دهد که ۸۰٪ کد برنامه در ارتباط با رسیدگی خطا و حالت‌های استثنا (Exception) است. عموماً نوشتن کد برای آنچه سیستم باید در شرایط خوب انجام دهد، ساده است و شرایط دیگر مربوط به خطا و حالت‌های استثنا و جاهایی که کار بدرستی پیش نمی‌رود، معمولاً بخوبی مشخص نمی‌شوند و نوشتن آنها بسیار سخت‌تر است.خطا چیست؟ خطا هر چیزی است که جلوی کار مورد انتظار سیستم را بگیرد. ۳ نوع مختلف خطا وجود دارد. اولین خطا که ما برنامه‌نویسان کاملاً با آن آشنا هستیم باگ ها هستند. اگر چیزی در برنامه بنویسیم که مطابق با آنچه می‌بایست نباشد، باگ داریم مثلاً اگر فراموش کنیم که شرایط مرزی را چک کنیم. این مورد، یقیناً مانع کار مورد انتظار سیستم می‌شود. نوع دیگر خطا که کاملاً با باگ متفاوت است، ورودی‌های غیرمجاز است. اگر در برنامه دیالوگی داشته باشید که فیلدی داشته باشد که قرار باشد در آن یک تاریخ وارد شود و به جای آن، یک متن وارد شود، حتما مانع عملکرد مورد انتظار سیستم می‌شود. کاری که می‌بایست انجام دهید این است که ورودی‌ها را پردازش کرده و آن را چک کنید. نوع دیگر خطاها به این صورت هستند که زیرساخت‌‌ها کار نمی‌کنند. بعنوان مثال، دسترسی نوشتن به فولدری که نیاز دارید در آن بنویسید را ندارید یا اینکه شبکه کار نمی‌کند و مواردی از این قبیل.شما گفتید که ۸۰٪ کد برنامه‌ها مربوط به رسیدگی خطا است. سئوالی که پیش می‌آید این است که آیا این موضوع در طول زمان تغییر کرده است؟ آیا زبان‌‌های برنامه‌نویسی بهتر، این مقدار را کاهش داده است یا این آمار همواره پایدار بوده است؟من از تحقیقاتی که این موضوع را در طی زمان، بررسی کرده باشد خبر ندارم. اگر در طی زمان این مورد کمتر شده باشد، من متعجب خواهم شد زیرا اینها (خطاها) چیزهایی است که نیاز داریم به آنها فکر کنیم. منظورم این است که مثلاً رسیدگی به شرایط مرزی یا بررسی زیرساخت‌ها کارهایی است که همواره نیاز است انجام شود. ممکن است برخی از این امور در طی زمان به کتابخانه‌ها و فریم‌ورک‌ها منتقل شده باشند، اما هنوز سهم زیادی باید درنظر گرفته شوند.در ارتباط با ۳ نوع خطایی که معرفی کردید آیا نیاز است که آنها را به شکل‌های متفاوت رسیدگی کنیم؟ آیا مهم است که بتوانیم آنها را از هم تشخیص دهیم؟ چرا اینها را همان ابتدای بحث مطرح کردید؟اول از همه باگ ها را داریم. باگ ها را نمی‌توان واقعاً رسیدگی کرد! منظورم این است که اگر باگی وجود داشته باشد نمی‌توانید با اقدامات امنیتی اطمینان یابید که به چیزی جز یک core dump یا یک پیام غیر قابل فهم می‌رسید. در مورد باگ‌ها، فقط می‌توانیم بصورت  برازند‌ه‌ای رفتار سیستم را در یک خروجی مربوط به دیباگ گزارش دهیم.  البته قطعاً این کاری نیست که می‌خواهیم با ورودی‌های غیرمجاز انجام دهیم.  از آن زمانی که انتظار می‌رفت اگر کاربر در یک فیلد تاریخ، یک متن را وارد  کرد، سیستم از کار بیافتد، مدت‌ها گذشته است. در این موارد کاربران انتظار  خطا ندارند. آنها انتظار دارند که فقط پیغامی بیاید که ورودی نامعتبر است و  لطفاً مجدد وارد کنید و مواردی از این قبیل.خطاهای مرتبط با زیرساخت‌ها، هم چیزهایی هستند که کاربران ممکن است نتوانند در مورد آنها همکاری کنند. ممکن است نیاز باشد نوعی تلاش مجدد انجام دهید.ممکن است کاربران نتوانند آنها را برطرف کنند اما بخواهید به آنها اطلاع  دهید که مثلاً به اینترنت وصل نشده‌اید و بنابراین نمی‌توانید با کسی صحبت  کنید.بله، دقیقاً. این نوع دیگری از اطلاع‌رسانی‌هایی است که کاربر دریافت می‌کند.چه استراتژی‌هایی برای رسیدگی خطا وجود دارد؟اگر بتوانیم، خیلی ساده؛ به کاربرانمان اهمیت نمی‌دهیم. گاهی مواقع، به نظر می‌رسد در برخی سیستم‌های بزرگ همین روش انجام می‌شود. شوخی کردم :-) انواع  مختلفی از افراد وجود دارند که به رسیدگی خطا، به گزارش خطا و مطلع شدن از  آن علاقه‌مند هستند. رسیدگی خطا باید تا جایی که می‌شود بصورت  برازنده‌ای انجام شود. سیستم باید هر کاری که می‌تواند انجام دهد تا  وظیفه‌اش را انجام دهد اما اگر نمی‌تواند و واقعاً کار سختی است باید نیازمندی‌های گروه‌های مختلف در نظر گرفته شود.گروه اول کاربران نهایی هستند: کسانی که از سیستم‌های نرم‌افزاری استفاده می‌کنند. وقتی داریم خطا را رسیدگی می‌کنیم، نیاز این گروه باید همواره در بالای لیست اولویت قرار گیرد. ما می‌خواهیم به آنها بگوییم که چه  اتفاقی افتاده اما به زبانی که برایشان قابل درک باشد. اگر خطا در ورودی  باشد می‌خواهیم به آنها بگوییم اما اگر خطا به علت باگ هم باشد باز هم می‌خواهیم این را بگوییم. اگر خطایی بعلت باگ رخ داده است مناسب نیست که  فقط پنجره بسته شود و سیستم برود یا حتی اینکه پنجره ارسال فیدبک را باز کنیم.  بهتر است که بگوییم یک خطای داخلی رخ داده است. ما خیلی متأسفیم که این  اتفاق رخ داده است. ما بر روی آن کار می‌کنیم و لطفاً برنامه را از نو اجرا کنید. یا شاید بهتر باشد این امکان را بدهیم که کارشان را ذخیره کنند  مثلاً بگوییم که یک نسخه کپی موقتی از کارتان در آدرس فلان ذخیره شده است.  نیازهای کاربران نهایی باید مهمترین نیازمندی‌ها باشد.فقط بعنوان یک نظر در این مورد: به نظر من در برخی موارد مثلاً در مورد  سیستم‌های تعبیه شده بهتر است که در هنگام وقوع خطا، کار را متوقف کنیم تا  اینکه یک کار غلط انجام دهیم. مطمئناً در برخی شرایط، یک استراتژی رسیدگی  خطا، توقف برنامه است.شما قطعاً درست می‌گویید که بهتر است کاری نکنیم تا اینکه بخواهیم کار غلطی  بکنیم ولی عموماً این شرایط مربوط به سیستم‌های غیرتعاملی و سیستم‌های  تعبیه شده است.عموماً این سیستم‌ها نوعی حالت امن از خطا (Fail Safe) هم دارند که اگر بخشی از سیستم  خراب شود، همان بخش، از کار می‌افتد اما بخش‌های دیگر سیستم همچنان در یک  حالت عملکرد سطح پایین‌تر به کارشان ادامه می‌دهند. سیستم همچنان کار می‌کند، هواپیما به پروازش ادامه می‌دهد! اما نمی‌توانید همه کارهای قبلی  را انجام دهید.دومین گروه که به رسیدگی خطا علاقه‌مند هستند، مدیرسیستم‌‌ها  (Administrator) هستند خصوصاً در سیستم‌های تعبیه شده یا غیرتعاملی، اینها  کسانی هستند که باید از خطا آگاه شوند. آنها خیلی راحت فراموش می‌شوند.  منظورم این است که اگر سیستمی میزان کیفیت خدمتش (Quality of Service)  کاهش یابد یا اینکه سیستمی مشکل خطای شبکه دارد، خیلی مهم است که مدیرسیستم  مطلع شود تا این امکان فراهم شود که تشخیص دهد چه مشکلی پیش آمده است  مثلاً با کار کردن با نرم‌افزار مدیریت سیستم یا با بررسی لاگ‌هایی که  می‌توان بصورت خودکار آنها را مرور کرد یا هر روش دیگری. بهرحال خیلی مهم  است که چک کنیم بوسیله روش‌های اطلاع‌رسانی، مدیر‌سیستم‌ها از خطاها مطلع  شوند. این گروه، افرادی هستند که خیلی مواقع به آنها بی‌توجهی می‌شود.و گروه سومی که نیاز است مورد توجه قرار گیرند و از آنچه رخ داده باخبر  شوند برنامه‌نویسان هستند. واضح است که این گروه باید در سطوح کاملاً  محلی و تکنیکی اطلاع یابند. هر برنامه‌نویسی حتی شده با نوشتن در خروجی  استاندارد (Standard Out)، لاگ‌هایی به منظور دیباگ کردن سیستم نوشته است.  اما خیلی مهم است که در سطح معماری این موضوع جدی گرفته شود و برای آن  برنامه‌ریزی شود زیرا به سادگی ممکن است خطایی در بخشی از سیستم رخ دهد و  تنها به صورت محلی ثبت شود و تصویر کلی از دست برود و اطلاعات مربوط به دیگر  بخش‌های سیستم از دست رفته باشد یا جزییاتی که برای دیباگ کردن مورد نیاز است فراهم نباشد.رسیدگی خطا، وظیفه چه کسی است؟ همانطور که شما اشاره کردید، گروه‌های مختلفی وجود دارند. چه کسی آنها را رسیدگی می‌کند و چرا؟دو دیدگاه در مورد استراتژی‌های رسیدگی خطا وجود دارد. البته ابتدای کار بگذارید بگویم که من دارم فرض می‌کنم که در زبان برنامه‌نویسی، امکان پَرت کردن استثنا  (Exception) را داریم زیرا اگر بخواهیم فقط با بازگشت (Return) و فراخوانی (Call) و علت (Cause) کار کنیم در آن صورت مجبور خواهیم بود که خطاها را خیلی محلی و جزیی رسیدگی کنیم. پس بیایید فرض کنیم که از امکان رسیدگی به استثنا (Exception Handling) استفاده می‌کنیم. در  این صورت، همچنان به دو روش می‌توانیم کار کنیم. روش اول این است که هر بخشی  از کد مسئول انجام کار خودش است و اگر نتواند کارش را انجام دهد، یک  استثنا، پَرت می‌کند. اینکار خیلی مرتبط با طراحی از طریق قرارداد (Design By Contract) است که برتراند مایر ارائه کرده است.هر قسمت از نرم‌افزار مثلاً یک کلاس یا یک متد، یک قرارداد ارائه می‌کند که  اگر ورودی صحیح باشد، خروجی معینی را تولید می‌کند و به عنوان بخشی از  قرارداد مشخص می‌کند برای اینکه بگوید کاری را نمی‌تواند  انجام دهد، در چه شرایطی چه نوع استثنایی را پَرت می‌کند. هر قسمتی برای اینکه بتواند مشخصاً قراردادی که به بقیه دنیا ارائه کرده است را برآورده کند نیاز خواهد  داشت که استثناها را بصورت محلی رسیدگی کند.یعنی اگر به عنوان مثال عملگری داشته باشید، مشخص می‌کنید که این عملگر  استثناهایی از نوع A و B و C را پَرت می‌کند و عملگر می‌بایست همه  مشکلات داخلی را رسیدگی کند و فقط این نوع استثناها را گزارش دهد. آیا  منظورتان این است؟بله، این طراحی از طریق قرارداد است: روش محلی رسیدگی به استثناها.البته طراحی از طریق قرارداد فراتر از این می‌رود جایی که به صورت رسمی، عبارت‌های بولی (Boolean) می‌آورید  که شرایط اولیه را بیان می‌کنند. احتمالاً در اپیزود‌های بعدی به آن می‌پردازیم.بله، قطعاً. باید در اپیزودهای بعدی جزییات بیشتری از آن را بررسی کنیم. اما به رسیدگی به استثناها برگردیم. اگر شما دیدگاه محلی به آن داشته باشید و آن را به صورت محلی انجام دهید این خطر وجود دارد که در چنین  کدی، همه‌جا، بلاک‌های دریافت (Catch) ایجاد شود. یعنی دوسوم کد، بلاک‌های دریافت شود که واقعاً نوع جدیدی از استثنا ایجاد نمی‌کنند بلکه آنها را بدون اینکه  واقعاً رسیدگی کنند، مجدداً بسته‌بندی می‌کنند. این باعث می‌شود که خواندن  کد خیلی خیلی سخت شود و باعث می‌شود یک خط کد، به ۳۰-۴۰ خط کد افزایش یابد و  این خصوصاً برای قابلیت خوانایی و قابلیت نگهداری کد مشکل ایجاد می‌کند و  واقعاً ارزشی به سیستم نمی‌افزاید زیرا تمام آنچه انجام شده بسته‌بندی دوباره آنها  (Re-wrap) بوده است. به مرور، من دیدگاه دیگری نسبت به  رسیدگی استثناها پیدا کردم و آن تصویر کلی این است که بگذارم همه استثناها در پشته فراخوانی‌ها (Call Stack) بالا بروند و اصلاً  آنها را به صورت محلی رسیدگی نکنیم.بیایید نگاهی به انواع خطاها بیاندازیم. اگر خطا از نوع باگ باشد هیچ مزیتی  در بسته‌بندی کردن باگ در استثناهای (Exception) خاص مربوط به برنامه ما نیست. دوباره و دوباره بسته‌بندی کردن آن در حین عبور از پشته فراخوانی‌ها (Call Stack) مزیتی ندارد. باگ، باگ است و عموماً در یک سطح بالای کد و بالای پشته رسیدگی می‌شود و باعث می‌شود که یک پیغام بالا بیاید و طراحی از طریق  قرارداد برای باگ‌ها مزیتی ندارد.این همان چیزی است که قبلاً هم گفتید. شما نمی‌توانید انتظار بعضی خطاها را  داشته باشید. نمی‌توانید  خطای اشاره‌گر خالی (Null Pointer) را همه جا دریافت کرده (Catch) و  آن را به چیزی دیگری بسته‌بندی کنید زیرا شما انتظار آن را ندارید. اگر  انتظارش را داشتید، جلوی وقوعش را می‌گرفتید. درست است؟بله، دقیقاً. اشاره‌گر خالی یک چیز واضحی است اما به عنوان مثال دیگر، اگر نوعی مکانیزم بازتاب (Reflection)  داشته باشید، هرچیزی ممکن است رخ دهد. مثلاً پیغامی که ارسال می‌کنید توسط شیء شناسایی نشود یا اینکه متد موردنظر وجود نداشته باشد. معنی ندارد که اینها را به یک نوع استثنا (Exception) دیگر بسته‌بندی کنیم. خیلی مواقع، اگر آن متد وجود ندارد، پس باگ است. در جاوا، کامپایلر شما را اجبار می‌کند که این استثناها را به‌نوعی رسیدگی کنید اما در خیلی موارد، تنها باگ است و معنی ندارد که آنها را به صورت محلی رسیدگی کنید.مورد دیگر، ورودی غیرمجاز است. این موارد می‌بایست یکپارچه شوند. اگر دیالوگی دارید که فیلدهایش می‌توانند غیرمجاز باشند، یک حلقه حول فیلدهای ورودی وجود خواهد داشت که هرکدام از آنها را بررسی می‌کند و یک پیغام یکپارچه می‌سازد. اینجا نیز از مواردی است که نیازی به دوباره و دوباره بسته‌بندی کردن استثناها نیست.مورد سوم خطاهای مربوط به زیرساخت‌ها است مثلاً مشکلات کار با پایگاه داده یا  مشکلات کار با شبکه. در این شرایط، واقعاً مفید است که در بالاترین سطح،  استثنا اصلی را همچنان داشته باشیم. اغلب، این همان موردی است که ما به  آن علاقه‌مندیم. اگر یک مشکل شبکه‌ای وجود دارد، مثلاً فرض کنید که اتمام مهلت در سرویس نام (Naming Service Timeout) داریم. این واقعاً همان چیزی است  که ما می‌خواهیم در سطح واسط کاربر داشته باشیم تا آن را به کاربر نمایش دهیم بنابراین نیازی نیست که ۵ لایه استثناهای دیگر خاص برنامه به دور آن  بپوشانید. یک الگوی طراحی وجود دارد که می‌گوید که استثناهای یک لایه خاص از  برنامه باید فقط مفاهیم همان لایه را استفاده کنند یعنی اگر به عنوان مثال مولفه‌ای دارید که آدرس افراد را نگه می‌دارد و این مولفه داخل خودش از پایگاه داده استفاده می‌کند، این الگو می‌گوید که مولفه ذخیره‌سازی  Person می‌بایست استثناهایی مثلاً از نوع‌های PersonNotFound ،PersonInvalid و PersonNotStored داشته باشد و نباید چیزهای مربوط به  زیرساخت‌ها و سطوح زیرین معماری را برگرداند. شما می‌گویید این کار بی‌معنی  است و باید اجازه داد آن استثناهای های سطح پایین فنی تا سطوح بالای  معماری بالا بیایند.شما اکنون دارید در مورد الگوی معماری لایه‌ای صحبت می‌کنید. الگوی معماری  لایه‌ای در کتاب POSA معرفی شده است. قطعاً در مورد آن، معنی نمی‌دهد اما مرزهایی که دریافت (Catch) استثناها (Exception) و بسته‌بندی مجدد آنها، در آنجا معنی می‌دهد، عموماً مرزهای بین تیم‌ها و مرزهای بین زیرسیستم‌ها در سطوح  خیلی بالا در سیستم‌های خیلی بزرگ است. در آنجا قطعاً معنی می‌دهد که آنها  را دریافت و مجدداً بسته‌بندی کنیم. اگر مثلاً در سایت آمازون، نوعی خطای  پایگاه داده رخ دهد برای من مهم نیست. من فقط می‌خواهم بدانم که مشکلی در پیدا کردن کتابی که دنبالش بوده‌ام رخ داده است. در چنین شرایطی، اضافه  کردن این تجریدها معنی می‌دهد. اما در این سال‌ها یک گرایش وجود داشته است  که از این الگو در مقیاس‌های کوچک و کوچک‌تر و کوچک‌تر حتی در جایی که  یکسری کلاس‌های منفرد، نقش زیرسیستم‌ها را دارند، استفاده شود. و این  واقعاً مشکل‌زا است. در داخل تیم واحدی از افراد که قرار است خطاها را  بفهمند و اشکالزدایی کنند و داخل یک تیم واحد از مدیرسیستم‌ها، بسته‌بندی‌کردن مجدد خطاها معنی نمی‌دهد. ساده‌تر و بهتر است که همان اطلاعات استثنا (Exception) اصلی را داشته باشیم.شما به این مطلب اشاره کردید که رسیدگی به خطا، چیزی نیست که بتوانید آن را  کاملاً محلی انجام دهید و چیزی است که باید جزیی از معماری باشد. درست  است؟بله، دقیقاً. خیلی مهم است که رسیدگی به خطا در تمامی معماری سیستم با سبک یکسان و یکنواختی انجام شود. این که روش یکسانی برای انجام کارها وجود داشته باشد. زیرا خصوصاً مدیر‌سیستم‌ها و کاربران نهایی انتظار دارند که خطاهای مختلف به روش یکسانی نمایش داده شوند. برنامه‌نویسان این طور نیستند.  خروجی‌های دیباگ را هرکس به سبک خودش می‌نویسد. این مطلب می‌تواند با مبحث طراحی برآمده از مدل (Model Driven) مرتبط باشد زیرا آن روش یکی از روش‌هایی است که معماری یکسان اجبار می‌شود که مبحثی است که در اپیزودهای گذشته در مورد آن صحبت کرده‌ایم.اندی لانگ‌شاو هم چند الگوی خوب در مورد استراتژی‌های رسیدگی به خطاها نوشته است (برای مطالعه این مجموعه الگوها می‌توانید به این لینک و این لینک مراجعه نمایید -مترجم). شاید بتوانیم در اپیزودهای آینده او را هم برای مصاحبه بیاوریم.بله، ایده خوبی است.بسیار خوب، یک مطلب اصلی که من از این بحث آموختم دریافت کردن (Catch) در سطوح بالا بود. درست می‌گویم؟بله، دقیقاً. این یکی از الگوهای موردعلاقه من از مجموعه الگوهای لانگ‌شاو است. ایده همان چیزی است که من هم‌اکنون توضیح دادم. اینکه در  همه جای کد، بلاک‌های دریافت کوچکی نداشته باشیم که تلاش می‌کنند به خطاهایی  رسیدگی کنند که واقعاً نمی‌توانند به آنها رسیدگی کنند و بجای آن یک بلاک دریافت در بالای پشته فراخوانی‌ها (Call Stack) داشته باشیم که همه رسیدگی به خطاها را انجام دهد و فقط زمانی که واقعاً می‌توانیم رسیدگی به خطاها را بصورت محلی انجام  دهیم این کار را بکنیم. اگر لازم است که بصورت محلی، اطلاعاتی به آن  بیافزاییم این کار را بکنیم اما در نهایت، رسیدگی اصلی به خطاها در این بلاک دریافت سطح بالا انجام شود.ولی این تنها برای خطاهایی مفید است که نمی‌توان برای آنها تلاش مجدد داشت  زیرا ممکن است بخواهیم استراتژی‌های ترمیمی (Recovery) داشته باشیم. آنجا  معنی می‌دهد که دریافت (Catch) را در سطوح پایین انجام دهیم و برایش کاری کنیم.بله، قطعاً. اگر می‌توانید تلاش مجدد داشته باشید این کار را بکنید. اگر می‌توانید بصورت محلی خطا را به طرز معنی‌داری رسیدگی کنید این کار را  بکنید. اما خیلی از موارد هستند که نمی‌توان خطاها را محلی رسیدگی کرد.  نکته این است که اگر چیزی هست که نمی‌شود رسیدگی کرد، اَدای آن را  درنیاورید! و بعد، خوب است که یک نقطه در بالای پشته داشته باشید که  همه چیز را دریافت (Catch) کند و پردازش‌ها را آنجا انجام دهد. برای برنامه‌های با  واسط گرافیکی، آنجا، مکانی در نزدیکی حلقه رخدادها (Event Loop) خواهد بود و در برنامه‌های دسته‌ای (Batch) هم، احتمالاً یک حلقه اصلی سطح بالا دارید که بر روی داده‌ها، می‌چرخد که جایی خواهد بود که بلاک دریافت سطح بالا قرار خواهد گرفت.مطلب دیگری که ارزش ذکر کردن دارد این است که رسیدگی به خطاها چیزی است که  نباید بیش از حد، خودکارسازی شود. یک بحثی که همیشه در سیستم‌های  توزیع‌شده مطرح بوده، این است که این سیستم‌ها تا چه میزان باید شفاف باشند. کاربران باید بدانند که فراخوانی بر روی یک شیء بر روی یک  سیستم راه دور (Remote)  انجام شده و به همین علت خطاهای دیگری از قبیل عدم دسترسی  شبکه می‌تواند رخ دهد.آنچه شما می‌گویید این است که نباید تلاش کنیم آن را مخفی کنیم. ما  نمی‌خواهیم افراد فراموش کنند که بر روی یک سیستم توزیع‌شده یا سیستم دیگری  با یک معماری پیچیده قرار دارند. شما می‌خواهید افراد اینها را بدانند.بله، قطعاً. سیستم‌های توزیع‌شده‌ای که توزیع‌شدگی شفاف (Transparent  Distribution) داشته باشند، وهمی بود که در صده ۱۹ به آن علاقه‌مند بودند. من فکر می‌کنم، الان این مرحله را گذرانده‌ایم.بنابراین خطاها و استثناها در واسط گرافیکی (GUI) رسیدگی می‌شوند. درست است؟تا حدی، این قاعده سرانگشتی خوبی است. برای خیلی از برنامه‌ها که خیلی بزرگ  نباشند، همین روش کفایت می‌کند، البته اگر GUI داشته باشید. وقتی  می‌خواهید از این قاعده سرانگشتی استفاده کنید البته می‌بایست توجه داشته  باشید همان طور که چند بار تذکر دادیم اگر می‌توانید یک خطا را بصورت محلی  رسیدگی کنید این کار را بکنید. اگر می‌توانید بعد از یک اتمام مهلت (Timeout) تلاش مجدد داشته باشید یا ترمیم داشته باشید اینکار را بکنید. گاهی مواقع بهتر است که  نتیجه را حدس بزنید.جالب شد. منظورتان از حدس زدن نتیجه چیست؟من یکبار بر روی سیستمی کار می‌کردم که دسترس‌پذیری بالا (High  Availability) ارجحیت داشت. اگر پایگاه داده در دسترس نبود یا اگر سروری، در دسترس نبود، بهتر بود که ریسک می‌کردیم تا اینکه از کار افتادن  سیستم را برای کاربر مشخص کنیم. ریسک مالی، این را الزام می‌کرد.مثلاً در شرایطی که تصمیم‌گیری‌های بله/خیر دارید. اگر برای آن محاسباتی  دارید که نرخ سود را محاسبه می‌کند اما نمی‌توانید این محاسبات را انجام دهید در این صورت خیلی معنی نمی‌دهد که به کاربر پاسخ دهید: خطا، دوباره درخواست کنید.بله، شاید برای محاسبه نرخ سود این طور باشد. در برخی سیستم‌های تعبیه شده نیز ممکن است شرایطی باشد که بهتر باشد به جای اینکه سیستم را پایین بیاوریم، حدس‌هایی بزنیم. البته شما باید بدانید که چه کار می‌کنید.  باید یک منطق محکم پشت آن باشد. قطعاً شرایطی وجود دارد که حدس زدن پاسخ یا دادن پاسخ‌های قلابی بهتر از پایین آوردن سیستم است.نکته دیگر این است که به مرز بین ماشین‌ها، از منظر مدیریت سیستم‌ها، توجه داشته باشید. مهم است که قبل از عبور از مرزها، جهت رسیدگی مدیرسیستم، کارهایی انجام شود. به عنوان مثال در بسیاری از سیستم‌های توزیع‌شده، یعنی  سیستم‌های کلاینت/سرور، اگر مدیرسیستم ماشین کلاینت، با مدیرسیستم ماشین  سرور متفاوت باشد، آنگاه اگر مشکلی در سرور باشد، خیلی مهم است که این مشکل  قبل از ترک سرور، لاگ زده شود. زیرا اگر لاگ در ماشین کلاینت زده شود،  برای افرادی که مدیریت ماشین سرور را به عهده دارند، در دسترس نخواهد بود.این الگوی دیگری از الگوهای لانگ‌شاو است: الگوی لاگ در مرزهای سیستم. درست است؟بله، دقیقاً. مطلب دیگر، لاگ زدن در مرز تیم‌هاست. اگر بخش‌های مختلف سرور، توسط تیم‌های مختلفی رسیدگی می‌شود، باید لاگ‌ها داخل این مرزها  نگهداری شود. همه چیز مربوط به گروه هدف است. برای چه‌کسی رسیدگی خطا را  انجام می‌دهیم؟ چه کسی به آن علاقه‌مند است؟ چگونه می‌توانیم اطمینان یابیم  که اطلاعاتی که می‌خواهیم، به دست گروه خاصی که این کارها را برایشان انجام می‌دهیم، می‌رسد؟بسیار خوب، گام بعدی در بحث رسیدگی به خطا این خواهد بود که به جزییات عمیق‌تر استراتژی‌ها بپردازیم. مواردی مانند اینکه چه زمانی می‌خواهید استثناها، پَرت شوند؟ چه زمانی از  استثناهای چک‌نشده (Unchecked Exception) استفاده می‌کنید؟  اما اینها را برای اپیزود بعدی می‌گذاریم. درسته؟بله، و همین طور مباحثی از این قبیل که چطور سلسله‌مراتب استثناها را بسازیم و اینکه چه مقدار منطق در آن‌ها قرار دهیم.من فکر می‌کنم که از شما شنیدم که مقداری نسبت به این ایده که همه انواع استثناها، از نوع چک‌شده باشند انتقاد دارید زیرا این شما  را مجبور می‌کند که آنها را دریافت (Catch) کنید زیرا در غیر این صورت کامپایلر ایراد  می‌گیرد. اما نمی‌توانید بغیر از بسته‌بندی مجدد آن با استثناهای دیگر و دوباره پَرت کردن آنها کاری کنید. فکر می‌کنم در هنگام بحث در مورد این  امور سطح پایین، عقاید غیرمتعارفی داشته باشید.یقیناً. قطعاً یک بحث چالشی خواهیم داشت.مطلب دیگری هست که بخواهید بگویید؟فقط یک مطلب مهم این است که رسیدگی خطا را بصورت جدی انجام دهید. برای  طراحی آن در سطح معماری، زمان بگذارید و همه کسانی که می‌بایست از خطاها  مطلع شوند را درنظر بگیرید. آنها فقط برنامه‌نویسان نیستند بلکه کاربران  نهایی و مدیرسیستم‌ها هم هستند.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Thu, 04 Nov 2021 16:48:46 +0330</pubDate>
            </item>
                    <item>
                <title>بدهی فنی</title>
                <link>https://virgool.io/se-radio/se-radio-technical-debt-s1zmfbyyrobz</link>
                <description>مطلبی که می‌خوانید ترجمه‌ی  قسمت ۲۲۴ از رادیو مهندسی نرم‌افزار است. رادیو مهندسی نرم‌افزار هر یکی دو هفته یک بار مصاحبه‌ای درباره‌ی یکی از موضوعات حوزه‌ی مهندسی نرم‌افزار با افراد خبره و با تجربه در موضوع مورد بحث ترتیب می‌دهد.در این اپیزود که در آوریل ۲۰۱۵ منتشر شده است، سوِن یوهان و ابرهارد ولف در مورد بدهی فنی (Technical Debt) صحبت می‌کنند. آن‌ها در نوشتن مقاله‌ای در مورد بدهی فنی با هم همکاری کرده‌اند. این قسمت به شکل مصاحبه نیست بلکه سوِن و ابرهارد با هم بحث را پیش می‌برند.سوِن، چند کلمه در مورد خودت به ما بگو.اسم من سوِن یوهان است و به عنوان توسعه‌دهنده‌ی نرم‌افزار در Trifork در آمستردام کار می‌کنم. همچنین دست‌اندرکار کنفرانس‌های GOTO هستم و خوشحالم که میزبان ریزسرویس‌ها در جلسه‌ی آمستردام هستم.بله، خیلی جالب به نظر می‌رسد. من ابرهارد ولف هستم. من مستقل کار می‌کنم (Freelance). همچنین رئیس هیأت مشاوره‌ی فناوری در Adesso AG هستم. من در کنفرانس‌ها (اکثراً در آلمان) سخنران هستم و اخیراً کتابی در مورد تحویل مستمر نوشتم. همچنین دست‌اندرکار کنفرانس‌های GOTO و چند کنفرانس دیگر هستم.اجازه بدهید به موضوع بپردازیم. بدهی فنی به وضوح با کیفیت نرم‌افزار ارتباط دارد. بنابراین قبل از این‌که وارد عمق بحث بدهی فنی بشویم باید در مورد کیفیت صحبت کنیم. انواع مختلفی از کیفیت وجود دارد. یک نوع از آن کیفیت خارجی است. این کیفیتی است که می‌تواند توسط کاربر یا مشتری مشاهده شود. ممکن است کارایی، امنیت، مقیاس‌پذیری، پایداری و ... باشد. [این نوع کیفیت] می‌تواند توسط کاربر اندازه‌گیری و مورد آزمایش قرار بگیرد؛ چون ویژگی‌ای از محصول است. چیزی است که باید توسط مالک محصول یا افرادِ حوزه‌ی کسب و کار مدیریت شود. چون آن‌ها هستند که به کیفیت و چگونگی دریافت آن توسط مشتری علاقه‌مند هستند. مثل خریدن یک خودرو است که ویژگی‌هایی دارد؛ [کیفیت] صرفاً یکی از ویژگی‌های محصول است.قسمت پیچیده‌تر در توسعه‌ی نرم‌افزار کیفیت داخلی است. کیفیت داخلی فقط توسط توسعه‌دهندگان یا افراد فنی قابل مشاهده است. [کیفیت داخلی] هر چیزی است که گسترش و نگه‌داری کد را سخت‌تر یا آسان‌تر می‌کند. ممکن است تست‌هایی باشد که وجود دارند یا ندارد، چون اگر تست داشته باشیم، تغییر کد آسان‌تر است. ممکن است سبک معماری یا مشکلات آن باشد. همچنین مربوط به مشکلات کد است، این‌که کد بیش از حد پیچیده یا بیش از حد ساده است. شبهه‌ای که در مورد آن وجود دارد این است که توسط هیچ‌کس به جز افراد فنی قابل مشاهده نیست. این به آن معنی است که مدیریت کیفیت داخلی در واقع دشوار است. چون اگر فردی فنی نباشید، درک این کیفیت و تأثیر آن روی فرایند توسعه سخت است. این چیزی است که در مورد بدهی فنی هم مهم است.سوِن می‌خواهی در این مورد صحبت کنی؟بله. اساساً می‌توان گفت بدهی فنی تشبیهی برای توصیف کد نامطلوب است. [اصطلاح] بدهی اشاره‌ای به بدهی مالی دارد و از آن استفاده می‌کنیم تا [مفهوم] این کیفیت داخلی و ریسک کد را به افراد غیرفنی منتقل کنیم. توسعه‌دهندگان همواره در مورد کدهای باکیفیت و خوب صحبت می‌کنند اما افراد غیرفنی عموماً فایده‌ی آن را درک نمی‌کنند. به نظر آن‌ها «نرم‌افزار خوب کار می‌کند، چرا باید در کیفیت سرمایه‌گذاری کنم؟!». تشبیه بدهی فنی به ما کمک می‌کند که توضیح دهیم اگر بخواهیم بر اساس کد نامطلوب چیزی بسازیم، این باعث می‌شود توسعه‌های بعدی گران تمام شوند؛ زمان بیشتری صرف پیاده‌سازی یک ویژگی به کدی که خیلی خوب نیست، می‌شود. همچنین دیر یا زود این کیفیت داخلی تبدیل به کیفیت خارجی می‌شود؛ این هم مسئله‌ی است که باید بفهمانیم. مثلاً اگر کد بدی داشته باشیم، باگ‌های بیشتر و بیشتری خواهیم داشت و کند می‌شویم و این مشکل به تدریج به ذی‌نفعان و پروژه هم منتقل می‌شود. بنابراین بدهی فنی در حقیقت مشکل توسعه‌دهنده نیست، یک مشکل در سطح شرکت است. اگر بدهی فنی زیادی داشته باشید، در شرایط بحرانی تمام تیم مهندسی متوقف می‌شود. فکر می‌کنم خیلی از شرکت‌ها این را تجربه کرده باشند؛ فرضاً سامانه‌های [نوشته‌شده] با COBOL که امکان تغییر چیزی را در آن نداشتند.بنابراین می‌شود ادعا کرد که بدهی فنی یکی از موارد کلیدی در موفقیت تجاری نرم‌افزارهای توسعه‌داده‌شده است. این اصطلاح توسط وارد کانیگهام در سال ۱۹۹۲ ابداع شد. او چنین چیزی گفت: «انتشار اولین کد مثل بدهکار شدن است. کمی بدهی، سرعت توسعه را بهبود می‌بخشد؛ به شرطی که در اولین فرصت با بازنویسی کد، تسویه شود... خطر زمانی رخ می‌دهد که تسویه نشود. هر دقیقه که صرف کد نامطلوب شود به عنوان بهره تلقی می‌شود. تمامی یک سازمان مهندسی می‌تواند تحت بار بدهی این کد نامستحکم، به حالت توقف کشانده شود، [خواه این اشکال] از نوع شئ‌گرایی باشد یا نباشد.» (متن کانینگهام را می‌توانید از این لینک ببینید -مترجم)‌ این به وضوح می‌گوید که تشبیه بدهی فنی ارتباط نزدیکی با بدهی مالی دارد و مربوط به انتشار سریع یک چیز و در نتیجه بدهکار شدن است. بعداً باید این بدهی را با بهبود کیفیت، تسویه کنید و اگر این کار را نکنید مجبور به پرداخت نرخ بهره هستید چون بهره‌وری شما کاهش پیدا می‌کند و توسعه‌تان کند می‌شود. و همان‌طور که سوِن الان گفت این تشبیه مناسبی برای صحبت با مدیریت است چون آن‌ها با اصطلاحات مالی آشنا هستند. با استفاده از این اصطلاحات راحت‌تر است که به آن‌ها بگوییم این مثل رفتن به بانک است. برای مدتی سود دارد اما در نهایت باید آن را بازپس دهید؛ اصل و بهره‌ی آن را. این‌طور بود که این اصلاح ابداع شد. اما تعریف دیگری هم وجود دارد. درست است سوِن؟دقیقاً، دقیقاً. انجمن محققین ترجیح می‌دهند از تعریف مک‌کانل استفاده کنند. او می‌گوید: بدهی فنی‌ای که رویکردی در طراحی یا ساخت باشد در کوتاه‌مدت عملی است. اما یک زمینه‌ی فنی ایجاد می‌کند که در آینده انجام کار در آن به نسبت الان زمان بیشتری خواهد گرفت، این شامل افزایش هزینه در گذر زمان هم هست. فکر می‌کنم این تعریفی است که اکثر ما از بدهی فنی می‌دانیم. کاری را سریع و کثیف انجام می‌دهیم و چیزی در کوتاه‌مدت به دست می‌آوریم اما می‌دانیم که در درازمدت گریبان‌گیرمان خواهد شد.این بیش از حد معمول است. فکر می‌کنم بعد از توضیح تشبیه، مهم‌ترین بخش این است که چطور با بدهی فنی برخورد کنیم؟ همان‌طور که گفتم، [بدهی فنی] یکی از کلیدهای کسب و کار موفق در توسعه‌ی نرم‌افزار است. بنابراین سؤال این است که چطور با آن برخورد می‌کنید؟ احتمالاً اولین سؤال این است که آیا اصلاً چیز بدی است؟اگر درباره‌اش فکر کنید، بدهکار شدن اغلب چیز بدی نیست. اگر برای مثال یک خانه بخرید، می‌توانید مقداری از پول‌تان را پس‌انداز کنید چون دیگر اجاره پرداخت نمی‌کنید و این نوع از سرمایه‌گذاری ممکن است چیز خوبی باشد. به همین‌خاطر است که در صنعت، وام وجود دارد. به شما پول می‌دهند تا در ماشین‌آلات بهتر یا هر چیز دیگر سرمایه‌گذاری کنید و بهره‌وری را بهبود دهید و تولید را بیشتر کنید و آن را پس دهید. بنابراین بدهی لزوماً چیز بدی نیست. در برخی موارد -اگر دوباره به تشبیه بنگریم- ممکن است بد باشد. اگر صرفاً برای خرید کالاهای تجملی، یا هدیه سال نو یا ... بدهکار شوید، این پول سرمایه‌گذاری نشده است، صرفاً خرج شده و رفته است. بنابراین در ارتباط با تشبیه در توسعه‌ی نرم‌افزار همیشه معنی ندارد که بدهی را پرداخت کنیم. چرا این‌طور است؟ علت این است که در مقایسه با بدهی عادی نرخ بهره‌ای که شما پرداخت می‌کنید تنها زمانی تغییر می‌کند که شما کد را تغییر می‌دهید. بنابراین همان‌طور که گفتیم کیفیت داخلی مربوط به این است که کد چقدر قابل تغییر است. اگر کد را تغییر ندهید کیفیت داخلی و بدهی فنی اصلاً اهمیت ندارد. بنابراین تسویه‌ی بدهی فنی در بخش‌هایی از کد که تغییر نمی‌کنند اصلاً معنی ندارد.مسئله‌ی دیگری هم وجود دارد که یکی از بخش‌های نامهربان بازیِ توسعه‌ی نرم‌افزار است و آن، این است که شخصی که بدهی را پرداخت می‌کند لزوماً کسی که آن را تحمیل کرده نیست. بنابراین اگر در یک پروژه، یک تیم نرم‌افزاری را تولید می‌کند و تیم متفاوتی قرار است بعداً نگه‌داری را انجام دهد، تیمی که پیاده‌سازی را انجام می‌دهد نرخ بهره و بدهی فنی را پرداخت نمی‌کند؛ تیم نگه‌داری این کار را خواهد کرد. در این مورد ممکن است به نفع تیم پیاده‌سازی باشد که بدهی فنی را انباشت کند، چون سریع‌تر پیش می‌روند و هرگز به جنبه‌ی منفی آن بر نخورند، چون این کار تیم نگه‌داری است. این یکی از مشکلاتی است که ممکن است در رابطه با بدهی فنی داشته باشید؛ کسی که بدهی فنی را به وجود می‌آورد ممکن است بعداً مسئول آن نباشد.همچنین مدتی پیش گفتگویی با وارد کانینگهام درباره‌ی بدهی فنی داشتیم و او گفت: خب، در واقع بدهی فنی یک راهبرد است. چرا یک راهبرد است؟ چون می‌توانیم با بدهکار شدن به سرعت به هدف کسب و کار برسیم. چون ممکن است به بازار فرستادن چیزی خیلی مهم‌تر از مثلاً داشتن کد بی‌نقص و دیر رسیدن باشد. اما می‌توانیم چیزی را در بازار بفرستیم و اگر اولین بار باشد ببینیم که اصلاً به درد می‌خورد یا نه. فکر می‌کنم جالب است که مثلاً اریک ریس نویسنده‌ی کتاب The Lean Startup در کتابش توضیح می‌دهد که وقتی در استارتاپ کار می‌کرد همیشه خوشحال بود که کد بی‌نقصی نوشته است اما در نهایت هیچ‌کس از آن استفاده نمی‌کرد. بنابراین عملکردی که با کد بی‌نقصش ساخته بود کاملاً بدون استفاده بود. پس بهتر است چیزی را سریع بنویسید و به کاربر برسانید و ببینید که آیا برای کسی مفید است؟ اگر برای کسی مفید است آن وقت است که بدهی فنی را پرداخت می‌کنیم. اگر کد بی‌نقصی برای عملکردی که نمی‌دانیم مفید است یا نه بنویسیم هدر دادن زمان است. هنریک نیبرگ از Spotify حدود یک سال پیش در بلاگش چیزی نوشت: اگر عملکرد کد بی‌نقص «واقعاً» مفید نباشد، ما آن را زباله در نظر می‌گیریم. کاری که آن‌ها می‌کنند این است که یک عملکرد را خیلی سریع راه‌اندازی می‌کنند در حالی که ظاهر خوبی ندارد و آن را به مشتری می‌رسانند. اگر کاربر آن را دوست داشت و خواست از آن استفاده کند آن را Refactor می‌کنند و بهبود می‌دهند. این راهبردها را مدام و مدام می‌بینیم. فکر می‌کنم یک نمونه‌ی مشهور آمازون و تویتر باشد. فکر می‌کنم در تویتر این حس وجود دارد که انگار همیشه دارند سامانه‌شان را بازنویسی می‌کنند :-) چون فکر می‌کنم در ابتدا یک برنامه Ruby on Rails بود و الان یک سامانه‌ی اشتراک پیام است. آمازون هم در ابتدا سامانه‌ی کاملاً متفاوتی به نسبت آن‌چه که الان هست، بود. بله، فکر می‌کنم یک راهبرد باشد.و ضمناً این چیزی است که وقتی من با معماران نرم‌افزار صحبت می‌کنم، تذکر می‌دهم. به آن‌ها تمرین‌هایی می‌دهم، اغلب آن‌ها راه‌حل‌هایی ارائه می‌دهند که مقیاس‌پذیری را در نظر می‌گیرد و فکر می‌کنند که مقیاس‌پذیری نگرانی اصلی‌شان است در حالی که در واقع باید روی زمان رسیدن به بازار تمرکز بیشتری داشته باشند. در غیر این‌صورت به نقطه‌ای که به مقیاس‌پذیری نیاز داشته باشند، نخواهند رسید. چون احتمالاً قبل از آن شرکت ورشکست می‌شود فرصت کسب و کار از دست خواهد رفت. بنابراین همان‌طور که می‌بینید همیشه بد نیست. با این حال باید به نحوی با بدهی فنی روبرو شوید. یکی از ایده‌های بزرگی که من به آن برخوردم ایده‌ی اریک ایوانز بود که به خاطر کتاب Domain Driven Design مشهور است. بخشی از کتاب هست که تقریباً همه آن را می‌دانند؛ درباره زبان و مخازن کد و … . بخش دیگری هم در کتاب هست که به نظر نمی‌رسد خیلی‌ها آن را خوانده باشند. درباره‌ی طراحی راهبردی و طراحی زمخت‌تر است. اساساً او می‌گوید اولاً نمی‌توانید یک سطح از کیفیت در تمام بخش‌های سامانه داشته باشید. اگر به آن فکر کنید در واقع کاملاً واضح است. چون توسعه‌دهندگان خوب و بد در تیم‌تان دارید. حتی اگر تیم خیلی خوبی داشته باشید باز هم توسعه‌دهندگان بهتر و بدتری خواهید داشت. بنابراین چون افراد متفاوتی در تیم دارید نمی‌توانید کیفیت یکسانی در تمام سامانه داشته باشید. چه کار می‌شود کرد؟ می‌توانید این‌که کدام بخش‌ها کیفیت بهتری داشته باشند را به شانس بسپارید یا این‌که درباره‌ی آن تصمیم آگاهانه‌ای بگیرید. یک راه برای روبرو شدن با بدهی فنی این است که بپرسید چه بخش‌هایی از سامانه واقعاً در تغییرپذیری اهمیت دارند؟ این اطلاعات را می‌شود در داده‌های تاریخی پیدا کرد، مثلاً این‌که تغییرات اخیر در کدام قسمت‌ها بوده است. یا می‌توانید از منظر کسب و کار به آن بنگرید،‌ در کدام بخش‌ها اگر تغییرات سریع‌تری داشته باشیم به ما مزیت رقابتی می‌دهد؟ مثلاً نحوه‌ی ترابری مهم است و در این مورد بخشی از سامانه که کار ترابری را انجام می‌دهد باید دارای کیفیت داخلی بالایی باشد. اریک ایوانز در کتابش تعداد کمی الگو دارد که در این رابطه صحبت می‌کنند. او می‌گوید می‌توانید یک زمینه‌ی کران‌دار (Bounded Context) داشته باشید که در آن یک مدل حوزه‌ی خاص معتبر است. می‌توانید میان زمینه‌های کران‌دار یک لایه ضد فساد داشته باشید. اگر همان سامانه‌ی ترابری را در نظر بگیریم و فرض کنیم یک مدل حوزه‌ی خوب در آن دارید که خیلی پیشرفته است و کد آن کیفیت بالایی دارد و بخش دیگری هم در سامانه هست که مثلاً با مشتریان سر و کار دارد و نرم‌افزاری عادی است که کیفیت پایینی دارد و مدل حوزه‌ی خیلی زشتی دارد. برای این‌که مطمئن شوید که این مدل حوزه‌ی زشت به سامانه‌ی ارزشمند ترابری شما نشت نمی‌کند، بهتر است یک لایه‌ی ضد فساد داشته باشید که این دو مدل را از هم جدا می‌کند و تفسیر بین آن‌ها را انجام می‌دهد. او در این مورد سلول‌ها را مثال می‌زند؛ مثل موجودات که از سلول‌ها ساخته شده‌اند، سامانه‌ی شما هم از تعدادی زمینه‌ی کران‌دار متفاوت تشکیل شده است. هر سلول غشائی دارد که مثل لایه‌ی ضد فساد است. [این غشاء] اطمینان حاصل می‌کند مشکلات خارجی به سلول (زمینه‌ی کران‌دار) نشت نمی‌کنند و آن‌ها به وضوح از هم جدا هستند. می‌توانید سلول‌ها (زمینه‌های کران‌دار) را با کیفیت بالایی داشته باشید و اگر مشکل کیفیت داشته باشید، در کد پخش نخواهد شد. این راه مناسبی برای توسعه‌ی راهبردی کیفیت در بدهی فنی است. تصمیم می‌گیرید کدام بخش‌ها مهم هستند، از آن‌ها مراقبت می‌کنید و بهترین توسعه‌دهندگان‌تان روی آن کار می‌کنند. کیفیت آن را از نزدیک پایش می‌کنید و ... بخش‌های دیگری هم هستند که ممکن است برای آن‌ها حتی از نرم‌افزارهای متداول، نرم‌افزارهایی که خریده‌اید یا از سامانه‌های میراثی خود (Legacy Systems) یا هر چیز دیگر استفاده کنید. فکر می‌کنم این راه جالبی برای توسعه‌ی راهبردی کیفیت یک سامانه‌ی نسبتاً پیچیده باشد.البته یک سؤال این است که اصلاً چرا بدهی فنی داریم؟ آیا نمی‌شود از همان ابتدا یک نرم‌افزار بی‌نقص داشته باشیم؟ فکر می‌کنم تقریباً هر توسعه‌دهنده‌ای بخواهد کار عالی ارائه دهد. فکر نکنم نگرش کسی این باشد که کار کم کیفیت ارائه دهد. منظورم این است که همه‌ی ما می‌خواهیم کارهای خوب انجام دهیم. [پس] چرا کار کم کیفیت ارائه می‌دهیم در حالی که می‌خواهیم کار با کیفیت ارائه دهیم؟ چند دلیل برای آن وجود دارد. واضح‌ترین دلیل برای اکثر ما توسعه‌دهندگان فشار زمانی است. ما می‌خواهیم که کار خیلی خوبی انجام دهیم، اما زمان نداریم. باید انتشار دهیم و ضرب‌العجل داریم. بنابراین برای این که سریع‌تر باشیم کیفیت را قربانی می‌کنیم. تست کردن را از قلم می‌اندازیم، یا فقط تست‌های خودکار را. به طراحی خوب به طرز عمیقی فکر نمی‌کنیم. در اکثر مواقع این منجر به کیفیت نامطلوب می‌شود. نکته‌ی دیگر این است که ما داریم آگاهی از نحوه‌ی انجام کار را از دست می‌دهیم. اگر از یک فناوری جدید برای نخستین بار استفاده می‌کنیم و از آن درک کمی داریم، به ناچار از آن به طرز اشتباهی استفاده خواهیم کرد حتی اگر نیت‌مان خیر باشد. همچنین اگر حوزه‌ی کسب و کار را خیلی خوب نشناسیم منجر به طراحی‌های عجیب می‌شود. چیزی هم مثل پوسیدگی نرم‌افزار وجود دارد. اگر یک نرم‌افزار عالی داشته باشیم مثلاً EJB 2.0 که شاید ۱۵ سال پیش خوب بود. اما الان کمی تاریخ مصرف گذشته است.فکر می‌کنم یک مطالعه‌ی برآوردی جالب در دانشگاه Turku بود که از افراد در فنلاند پرسیدند بدهی فنی شما از کجا سرچشمه می‌گیرد؟ خیلی جالب بود. چون نگفتند فشار زمانی. همچنین نگفتند که فناوری را نمی‌شناختیم. آن‌ها گفتند نیازمندی‌ها را درک نکردیم‌یا اساساً فهم درستی از حوزه‌ی کسب و کار نداشتیم بنابراین بدهی فنی از نیازمندی‌های درک نشده نشأت می‌گیرند. البته آن‌ها این‌ را هم گفتند که معماری بدی داشتیم، یا معماری [به خوبی] انتقال داده نشده بود. این‌ها دلایل اصلی بدهی فنی برای آن‌ها بود.در واقع این خیلی جالب است. چون در مقطعی من هم تصور می‌کردم که معماری است که منبع اصلی بدهی فنی است. اما یک زمان از خود پرسیدم چه چیزی است که تغییر نرم‌افزار را دشوار می‌کند؟ پاسخی که به آن دادم تست‌ها بودند. اگر من حق انتخاب بین سامانه‌ای که معماری بدی دارد ولی تست‌های زیادی دارد و سامانه‌ای که یک معماری عالی دارد ولی هیچ تستی ندارد، سامانه‌ای که من برای تغییر انتخاب می‌کنم آنی است که معماری بدی دارد ولی تست دارد. این هم یکی از جاهایی است که من خیلی مطمئن نیستم بدهی فنی را چطور تعریف کنم و فقط حول آن صحبت می‌کنم. کیفیت کد و معماری در اینجا اجزای سنتی هستند.بله. نمی‌دانم. اخیراً از فیلیپه کوچتن مبدع RUP شنیدم که درباره‌ی آن صحبت می‌کرد. او برای بسیاری کارهای معماری شناخته شده است. او گفت حتی اگر تعداد زیادی موارد تست (Test Case) داشته اما معماری بدی داشته باشید، نمی‌توانید فرض کنید که می‌توانید کیفیت بهتر را با پیرایش کردن (Refactor) در سامانه وارد کنید. چون اگر معماری اشتباه باشد، مثلاً سبک اشتباهی را انتخاب کرده باشید، پیرایش کردن به شما کمکی نمی‌کند. واقعاً باید سامانه را از نو بنا کنید. در واقع من نمی‌دانم، سؤال خوبی است: کدام بدتر است؟ معماری بد با موارد تست یا معماری بهتر بدون موارد تست؟این یکی از چیزهایی است که می‌توانید در مورد آن به تفصیل بحث کنید. در ارتباط با منشأ بدهی فنی، مدل دیگری هم هست که مارتین فاولر آن را معرفی کرده است. واضح است که او برای چیزهای زیادی در صنعت ما شناخته شده است. او بدهی فنی را در چهار ربع‌دایره تقسیم کرد. این ربع‌دایره‌ها بر اساس این‌که بدهی فنی، به طرزی غیرمسئولانه یا معقول تحمیل شده است، از هم جدا می‌شوند. اساساً سؤال این است که به اندازه‌ی کافی زمان برای فکر کردن به بدهی فنی وجود داشت؟ آیا صرفاً [تصمیمی] غیرمسئولانه بود و افراد تحت فشار زیادی بودند یا این‌که معقولانه بود؟ حتی در مواردی که زمان زیادی داشته باشید هم -همان‌طور که کمی بعد خواهیم دید- می‌توانید بدهی فنی داشته باشید. و [سؤال دیگر این‌که] آیا عمدی بود یا غیرعمدی؟ این‌که آیا تصمیمی آگاهانه بود که افراد گفتند ما بدهی فنی را می‌پذیریم و کار را انجام می‌دهیم یا این‌که به نحوی [خود به خود] اتفاق افتاد؟ ما زمان برای طراحی نداریم بنابراین به هر نحوی شده آن را انجام می‌دهیم. سرانجام سامانه‌ای به جای می‌ماند که بد طراحی شده است. اما شما می‌دانستید با این شرایط مواجه خواهید شد؛ بنابراین، این تصمیمی آگاهانه بود. اما اگر این تصمیم گرفته شد چون زمان کافی وجود نداشت، غیرمسئولانه‌ی عامدانه است. در مقابل، [تصمیم] معقول عامدانه یعنی این‌که الان باید انتشار دهیم و با پیامدهای آن مواجه شویم. بنابراین هر چند زمان کافی وجود داشت، باز هم این کار را کردیم و تصمیمی عامدانه بود، می‌دانستیم به لحاظ فنی بدهکار خواهیم شد و این کار را انجام دادیم. بدهی غیرمسئولانه‌ی غیرعمدی [چیزی مثل این است:] لایه بندی یعنی چه؟! واضح است که [این نوع بدهی فنی] چیزی است که در آن شما وقت کافی برای فکر کردن به تصمیم و عواقب آن صرف نمی‌کنید. تصمیم‌تان آگاهانه نبود چون حتی نمی‌دانستید که این یک مشکل است، شما اصلاً لایه بندی را نمی‌شناختید و در نتیجه یک سامانه‌ی بدون لایه‌بندی و شلوغ دارید. چون در واقع خیلی به آن فکر نکردید. بدهی عاقلانه‌ی غیرعامدانه این است که سامانه‌ای دارید و در بازنگری متوجه می‌شوید باید آن را به شکل دیگری می‌ساختید. معماری‌ای که استفاده کردید در زمانی خود مناسب بود اما بعداً در حین پیاده‌سازی به طراحی کاملاً متفاوتی درباره‌ی سامانه رسیدید که بهتر بود. در بازنگری روشن می‌شود که بدهی فنی زیادی دارید و مسئله این است که این فکر قبلاً به ذهن شما نرسیده بود. بنابراین زمان کافی داشتید و تصمیم عاقلانه بود اما در عین حال غیرعمدی هم بود چون نحوه‌ی عملکرد و واقعیت‌های معماری در آن زمان واضح نبود.چیزی که فکر می‌کنم در این مورد خیلی جالب است این است که در ابتدای بحث در مورد تعریف بدهی فنی صحبت می‌کردیم؛ در این مورد که بدهی فنی را متحمل می‌شویم تا سریع‌تر انتشار دهیم. بنابراین این تصمیمی آگاهانه است. بنابراین تعریف اصلی بدهی فنی می‌گوید که تصمیمی آگاهانه است. بدهکار می‌شویم و در عوض برای مدتی سریع‌تر انتشار می‌دهیم و بعداً بدهی را تسویه می‌کنیم. چیزی که فکر می‌کنم در مورد مدل ربع‌دایره‌های مارتین فاولر جالب است -اگر کمی در آن دقیق‌تر شوید- این است که او می‌گوید این همیشه درست نیست. برخی مواقع برای شما واضح است که باید کار را به نحو دیگری انجام می‌دادید، چون در بازنگری وقتی به مسئله و نحوه‌ی حل مسئله‌تان، و نتیجه‌ی کار بنگرید، همه چیز واضح است. همچنین من برداشتی متفاوتی از بدهی فنی پیدا می‌کنم چون او می‌گوید غیرمسئولانه است. او نمی‌گوید که زمان کافی نداریم، مسئله صرفاً این است که شما برای پیشبرد کار به حدی تحت فشارید که بدهی فنی انباشت می‌شود. این تصمیمی آگاهانه نیست، این صرفاً اتفاقی است که می‌افتد، چون زمان زیادی تحت فشار هستید. فکر می‌کنم بخش جالب قابل برداشت در اینجا این است که منشأهای متفاوتی برای بدهی فنی وجود دارد و مدل ساده‌ای که می‌گفت ما کیفیت را فدای سرعت می‌کنیم در واقع چیزی نیست که همیشه اتفاق می‌افتد. فکر می‌کنم مسئله‌ای که سوِن مطرح کرد نکته‌ی مهمی است. اگر کار را با سامانه‌ای شروع کنید و از فناوری‌ای نظیر EJB 2.0 استفاده کنید در حالی که نسخه‌ی جدیدتری از EJB وجود دارد یا کتابخانه‌ی دیگری وجود دارد که مورد علاقه‌ی شما است، قطعاً به لحاظ فنی خود را بدهکار کرده‌اید. چون راه‌های راحت‌تری برای انجام کارها وجود دارد و راهی که شما انتخاب کرده‌اید بدهی فنی محسوب می‌شود. [در گذشته] هیچ راهی برای جلوگیری از این بدهی فنی وجود نداشت چون فناوری، جدید و در حال پیشرفت است. بنابراین به نظر این نشانه‌ای است که این تشبیه شکست می‌خورد. البته سؤال بعدی این است داشتن یک سامانه‌ی بدون بدهی واقع‌بینانه است؟ فکر کنم شما بخواهید در این مورد صحبت کنید. درست است سوِن؟دقیقاً. آیا امکان دارد که سامانه‌ای بدون بدهی فنی داشته باشیم؟ منظورم این است که خیلی اوقات به چیزهایی از قبیل «بدهی فنی بس است»، «چطور بدهکار نباشیم، در ۱۰ مرحله»، «چه کنیم تا بدهکار نباشیم؟» و ... بر می‌خورم. فکر می‌کنم دستیابی به سامانه‌ای بدون بدهی غیر ممکن است. فکر می‌کنم باید بپذیریم که بدهی فنی همواره وجود خواهد داشت. حتی اگر سامانه‌ای بدون بدهی وجود داشت، چطور به آن دست می‌یابید؟ احتمالاً باید زمان و پول زیادی صرف کنید که لزوماً به موفقیت پروژه منجر نخواهد شد.در ارائه‌ای که در آمازون و تویتر داشتیم، آن‌ها به شدت موفق بودند در حالی که مقدار زیادی بدهی فنی وجود داشت. بنابراین فکر می‌کنم یکی از چیزهای جالب این است که بدهی فنی به هیچ وجه به موفقیت تجاری محصول گره نخورده است؛ می‌توان پروژه‌ای یا کسب و کاری از لحاظ تجاری موفق داشت که بر اساس نرم‌افزاری پر از مشکل استوار شده است؛ می‌شود بعداً آن را بازنویسی کرد. Extreme Programming این ایده را مطرح کرد که کیفیت را حداکثر قرار دهید و به هیچ وجه آن را فدا نکنید. این ممکن است ایده‌ی خوبی نباشد چون مقادیر زیادی منابع، پول و نیرو صرف بالا نگه‌داشتن کیفیت می‌کنید در حالی که ضرورتی ندارد و ممکن است اصلاً موفقیت تجاری را تحت تأثیر قرار ندهد. چون ممکن است چیزی باشد که کاربر اصلاً آن را نمی‌بیند. بنابراین بدهی فنی ممکن است بهترین تشبیه نباشد. سؤال همچنان این است که چرا به آن اهمیت می‌دهیم؟ چون در دراز مدت ممکن است بهره‌وری را تحت تأثیر قرار دهد و بدهی فنی صرفاً چیزی است که برای بهبود انتقال مطلب از آن استفاده می‌کنیم. ممکن است بهترین تشبیه نباشد، چون می‌توانید بگویید سیستم بدون بدهی غیر ممکن است و یا می‌توانید بگویید در بسیاری موارد حتی تصمیم آگاهانه‌ای در مورد بدهکار شدن وجود ندارد مثلاً در برخی موارد به علت فناوری جدید است که بدهی فنی رخ می‌دهد و نمی‌شود کاری در قبال آن کرد. بنابراین این تشبیه تاحدی معیوب است که شاید نیاز باشد به دنبال تشبیه دیگری باشیم. این موضوعی است که فلیکس مولر و من سعی داریم در حین پروژه‌ی کارشناسی ارشد روی آن کار کنیم (در این مقاله راجع به آن صحبت شده است -مترجم). ایده‌ی اصلی این است که اگر نمی‌توانیم از [تشبیه] بدهی فنی استفاده کنیم چون همیشه وجود دارد و چون گاهی تصمیم‌گیری آگاهانه در مورد آن وجود ندارد، پس چرا از تشبیه متفاوتی استفاده نمی‌کنیم؟ تشبیهی که ما پیشنهاد کردیم «بهبود در کیفیت» است. به جای این‌که در مورد بدهی صحبت کنیم...بهبود در کیفیت است یا سرمایه‌گذاری در کیفیت؟نکته‌ی خوبی بود، اساساً بهبود است اما از تشبیهی در دنیای تجاری استفاده می‌کنیم. بنابراین تشبیه مورد استفاده‌ی ما «سرمایه‌گذاری در کیفیت» است. منظور این است که اگر بدهی فنی همواره وجود دارد اگر همواره چیزی مربوط به کیفیت داخلی برای بهبود وجود دارد، چرا به آن در قالب سرمایه‌گذاری فکر نمی‌کنیم؟ ما در کیفیت سرمایه‌گذاری می‌کنیم. کسی را داریم که برای چند روز روی چیزی کار می‌کند، مثلاً تست‌های سامانه را بهبود می‌دهد که پنج روز طول می‌کشد و در قبال آن نتیجه‌ای حاصل می‌شود. مثلاً یک یا دو روز در هر اسپرینت (اشاره به دوره‌های توسعه در متدولوژی Scrum -مترجم) صرفه‌جویی می‌کنیم. این مثل هر سرمایه‌گذاری دیگری است. هدف این است که هزینه کاهش یابد. کاهش هزینه در واقع بهبود بهره‌وری منهای نیرویی است که در بهبود کیفیت سرمایه‌گذاری کردید.آخرین مسئله در این مورد مدل کیفیتی است که به نظر من مشابه آن است. مدلی به نام SQALE وجود دارد که در آن چیزی به نام هزینه‌های مداوا (Remediation Costs) دارند که به معنی نیروی لازم برای برطرف کردن مشکلات کیفیت است و همچنین هزینه‌های مداوا نکردن (Non-remediation Costs) را دارند که نیرویی است اگر مشکلات را برطرف نکنید نیاز دارید. بنابراین اگر پوشش کد بدی داشته باشید، هزینه‌ی مداوا برابر با بهبود پوشش تست‌ها خواهد بود و هزینه‌ی مداوا نکردن، بهره‌وری کم‌تر است چون باید زمانی بیشتری صرف برطرف کردن خطاها و ... کنید. فکر می‌کنم این مسئله‌ی جالبی باشد. فکر می‌کنم در اصل این مربوط به طرز فکر باشد. طرز فکر باید این باشد که اگر در چیزی سرمایه‌گذاری می‌کنم، مثلاً پوشش تست را بهبود می‌دهم، اگر خط‌ لوله‌ی تحویل مستمر را بهبود می‌دهم، یا اگر در کیفیت کد سرمایه‌گذاری می‌کنم، نباید آن را زر اندود کنم. باید کارهایی را انجام دهم که بهره‌وری را بالا نگاه می‌دارند و هزینه‌ی صرف‌شده را پس می‌دهند. اگر به کیفیت به این شکل بنگرید فکر می‌کنید راه مناسبی برای رسیدگی به بدهی فنی و کیفیت داخلی و همچنین انتقال مطلب به تصمیم‌گیرندگان و مدیران باشد.یکی از انتقادهایی که به این مدل هست این است که توسعه‌دهندگان باید همواره کیفیت را بالا نگاه دارند اما فکر می‌کنم هنوز مشکلات بزرگ‌تری هست که باید برطرف شوند و توسعه‌دهنده به تنهایی نمی‌تواند این کار را انجام دهد. آن‌ها باید با [بخش] تولید محصول هماهنگ باشند و چیزهایی از این قبیل. برای مثال اگر بخواهید خط‌لوله‌ی تحویل مستمر (Continuous Delivery Pipeline) داشته باشید چون می‌خواهید سریع به انتشار برسید، این نیروی خیلی زیادی می‌طلبد. این چیزی نیست که توسعه‌دهنده به تنهایی بتواند زیر بار آن برود و برای متقاعد کردن مدیریت برای سرمایه‌گذاری در آن، تشبیهی مثل سرمایه‌گذاری در کیفیت نیاز است که می‌گوید اگر این خط‌ لوله را داشته باشید کیفیت بهتری خواهیم داشت و خطاهای کمتر و بهره‌وری بیشتری خواهیم داشت. به این شکل، در گفتگویی که با مدیریت دارید به راه‌حل بهتری خواهد رسید. سؤال دیگر این است که چطور می‌توان بدهی فنی را تشخیص داد؟ شما در اینجا نظراتی دارید. درست است؟بله. در حقیقت برخی نظرات افراد دیگر را دزدیده‌ام :) برخی نشانه‌های واضح وجود دارند. مثلاً اگر کد پر از TODO و FixMe هاست این نشان می‌دهد که افراد برای تحویل عملکرد عجله داشتند اما در همین حال بسیاری موارد فرصت بهبود را می‌دیدند. یا اگر می‌خواهید کدی را تغییر دهید و توسعه‌دهنده می‌گوید: «من نمی‌توانم این کد را تغییر دهم چون این کد فلانی است!» شما به دردسر بزرگی افتاده‌اید. چون این بدین معنی است که شما خواستید که سریع پیش بروید و تنها یک توسعه‌دهنده همه چیز را در ذهنش دارد و آن را به اشتراک نگذاشته است و یک جزیره دانش شکل گرفته است. اگر آن توسعه‌دهنده با اتوبوسی تصادف کند دیگر هیچ کس نمی‌تواند چیزی را در کد تغییر دهد. اگر بخشی از کد فقط توسط افراد خاصی قابل تغییر باشد نشان‌دهنده‌ی این است که یک بدهی بزرگ فنی وجود دارد. همچنین اگر در راهروها می‌شنوید که بله ما هم عملکرد مشابه را داریم اینجا و آنجا داریم، پس بیایید کد را کپی کنیم و برخی قسمت‌های آن را تغییر دهیم. ممکن است بتوانید این کار را یکی دو بار انجام دهید اما اگر زیادی این کار را انجام دهید مخزن کدتان کاملاً غیر قابل نگه‌داری خواهد شد و تبدیل به یک کد اسپاگتی می‌شود. نشانه‌ی دیگر این است که توسعه‌دهنده‌ای می‌گوید: «دوست ندارم به این کد دست بزنم چون مطمئن نیستم اگر این کار را بکنم کلی چیز خراب نشود». این بدین معنی است که طراحی خیلی بدی دارید و نمی‌توانید تغییرات محلی برای نیازمندی‌های محلی انجام دهید چون همه چیز به نوعی به هم گره خورده است. شما در خطر هستید و در پیاده‌سازی نیازمندی‌های جدید خیلی کند عمل می‌کنید و رفع یک خطا، خطاهای دیگری را ایجاد می‌کند. تنها راه جلوگیری از آن تست گسترده است. نشانه‌ی دیگر در تیم‌های اسکرام است. آن‌ها [مفهومی به نام] سرعت (Velocity) دارند. اگر سرعت تیم مدام کاهش پیدا کند در حالی که تیم پایدار است باید از خود بپرسید چرا سرعت در حال کاهش است؟ در اکثر مواقع این به خاطر بدهی فنی است. و نکته‌ی دیگری هم که قبلاً گفتیم این است که نرم‌افزار پیر می‌شود: کتابخانه‌های قدیمی، JDK های قدیمی یا هر چیز قدیمی دیگر. اگر یک سیستم با طراحی بی‌نقص داشته باشید، ده سال دیگر به همان بی‌نقصی نخواهد بود. باید کتابخانه‌های آن را به‌روزرسانی کنید و ارتقاء دهید تا نیازمندی‌های جدید را برآورده کند و بتوان موفق بود. همچنین به نظر من بد است که بشنوید: «می‌توانیم این خطای مهم را رفع کنیم و فقط یک خط است یکی دو هفته طول می‌کشد تا منتشر شود». آن‌چه که واقعاً می‌خواهید این است که وقتی خطایی را برطرف می‌کند ده دقیقه یا یک ساعت بعد بتوانید نسخه‌ی جدید را انتشار دهید. اما اگر چرخه‌ای دو سه هفته‌ای دارید که بخش کوچکی از کد را تغییر دهید و آن را انتشار دهید، مشکل دارید. [مسئله دیگری که] خیلی مهم نیست اما جالب است این است که تست‌های کندی دارید که واضح است زمان می‌گیرد. اگر سیاستی دارید که می‌گوید حتماً باید تمامی تست‌ها را اجرا کنید قبل از این که کد خود را ثبت کنید -که به نظر من هر پروژه‌ای باید این سیاست را داشته باشد- خیلی فرق می‌کند که مجبور باشید یک دقیق صبر کنید، یا ده دقیقه، یا بیست دقیقه. تعدادی نشانه‌ی دیگر هم هست که شاید شما بخواهید در موردش صحبت کنید. مثل SonarQube یا Structure101اگر بخواهید به کیفیت کد نگاه کنید، SonarQube ابزار خوبی برای تحلیل کد است که کارهای متفاوتی انجام می‌دهد. تحلیل ایستای کد انجام می‌دهد، پوشش کد تست‌ها را بررسی می‌کند و خیلی کارهای دیگر. نکته‌ی جالب درباره‌ی آن این است که ابزارهای زیادی را ادغام می‌کند و به شما گزارش خوبی از میزان خوبی کدتان می‌دهد. اطلاعات تاریخی در اختیارتان می‌گذارد تا بفهمید که در حال بهبود هستید یا خیر. ابزارهای دیگر هم مثل Structure101 وجود دارند که من دوست‌شان دارم. همین‌طور Sonargraph که به شما اجازه می‌دهد معماری کدتان را تحلیل کنید. فقط کدتان را به آن می‌دهید -گاهاً کد کامپایل شده- و سپس می‌توانید معماری را ببینید، این‌که چقدر خوب است، چقدر وابستگی دارد، چقدر پیچیدگی دارد و می‌توانید بر اساس آن واکنش نشان دهید. این‌ها ابزارهایی هستند که می‌توانید از آن استفاده کنید. باز هم من فکر می‌کنم که مهم‌ترین چیز این است که کدی داشته باشیم که به سهولت قابل تست باشد. و اگر می‌خواهید بدهی فنی را تشخیص دهید، چیزی که باید به آن فکر کنید این است که چه چیزی بیشترین تأثیر را بر قابلیت نگه‌داری دارد؟ چه چیزی بیشترین تأثیر را بر تغییرپذیری دارد؟ چطور می‌توانم این‌ها را بهبود دهم؟ و این [مسائل] لزوماً وابسته به کد نیست. ممکن است مربوط به تست‌ها باشد، به خاطر پوشش پایین تست‌ها، تغییر آن سخت است چون نمی‌توانید از تغییرات‌تان مطمئن باشید. ممکن است چیزی را خراب کرده باشید و تا زمان انتشار متوجه آن نشوید. یا همان‌طور که گفتیم اگر استقرار یا تست‌های کندی داشته باشید، تغییرات کم‌تری می‌توانید در کد اعمال کنید چون قرار دادن آن تغییرات در محصول زمان زیادی می‌گیرد.ما در مورد شناسایی بدهی فنی صحبت کردیم. حالا سؤال این است که در قبال آن چه کار می‌توانیم انجام دهیم؟ فکر می‌کنم موضوع جالبی باشد. یکی از راه‌هایی که می‌توانید با بدهی فنی روبرو شوید این است که یک فعالیت حائل (‌Buffer Task) در هر دوره‌ی انتشار ایجاد کنید. مثلاً می‌گویید ده درصد از زمان را به تیم اختصاص دهیم تا روی مسائل فنی کار کند. چیزهایی که آن‌ها فکر می‌کنند باعث بهبود می‌شود. حتی می‌توانید مقدار بیشتری از بودجه‌تان را صرف بدهی فنی کنید. می‌توانید انتشار فنی (Technical Release) داشته باشید که صرفاً در آن کد را بهبود داده‌اید. این به این معنی است که نیروی صرف شده برای بدهی فنی به صورت متوازن پخش نشده است-مانند آن‌چه که در فعالیت حائل داشتیم که ده درصد هر اسپرینت را می‌گرفت، در اینجا یک اسپرینت کامل از هر دو یا سه اسپرینت است. ممکن است یک انباره‌ی فنی (Technical Backlog) (اشاره به انباره‌ی نیازمندی‌ها در Scrum -مترجم) از چیزهایی که باید بهبود داده شوند، داشته باشید. راه دیگر این است که اگر برای ویژگی‌های کسب و کار، یک وظیفه (Task) یا داستان کاربری (User Story) داریم در همان حال می‌توانیم بخشی از نیرو را در رسیدگی به بدهی فنی سرمایه‌گذاری کنیم. اساساً هدف این است که وقتی داستان جدیدی داریم و مثلاً می‌خواهیم فرایند ثبت‌نام را تغییر دهیم، در حین انجام تغییرات، کیفیت را بهبود دهیم به نحوی که پیاده‌سازی فرایند ثبت نام آسان‌تر شود. به این طریق بودجه‌ی بهبود کیفیت را در بخش‌هایی صرف می‌کنیم که تغییرات در آن‌ها انجام می‌شود. این چیزی است که بر هر مورد کاربرد تأثیر می‌گذارد و مدیریت می‌تواند در مورد آن تصمیم بگیرد. او می‌تواند بگوید من این داستان را نمی‌خواهم چون خیلی گران است، چون کیفیت خیلی پایین است و از این طریق به مدیر اجازه می‌دهید این‌گونه تصمیمات را بگیرد.دست آخر، کیفیت و بهبود آن باید یک تصمیم کسب و کار باشد. چون مربوط به اولویت‌بندی کیفیت و ویژگی‌هاست. همان‌طور که گفتیم این مسئله خیلی مهمی است. اگر کیفیت را بهبود دهید، در دراز مدت مفید خواهد بود، هرچند اگر واقعاً می‌خواهید یک ویژگی [زودتر] به اتمام برسد چون در غیر این‌صورت فرصت کسب و کار از دست می‌رود یا عواقب دیگری در کسب و کار دارد، دیگر کیفیت اهمیت پیدا نمی‌کند. بنابراین این سؤال که آیا باید در کیفیت سرمایه‌گذاری کنید یا نه باید یک تصمیم کسب و کاری باشد. مشکل این است که اگر ده درصد از زمان تیم را برای رسیدگی به کیفیت اختصاص دهید یا این‌که انتشار برخی نسخه‌ها را برای رسیدگی به کیفیت در نظر بگیرید دیگر یک تصمیم کسب و کار نیست در حالی که باید این‌طور باشد. فکر می‌کنم بخشی از مشکل رسیدگی به بدهی فنی، قادر ساختن کسب و کار به تصمیم‌گیری در مورد بخش‌هایی است که باید کیفیت بالاتری داشته باشند و سپس در آن سرمایه‌گذاری کنند. واضح است که این اشتباه است که تیم تصمیم‌گیری کند. ممکن است نتوانند این کار را انجام دهند یا ممکن است نتوانند بهترین تصمیم‌ها را بگیرند چون تصویر کلی را ندارند. فکر می‌کنم این علتی است که همراه کردن کسب و کار یکی از سخت‌ترین بخش‌هاست. ارتباط با مدیریت هم در قلب مسئله تشبیه بدهی فنی است، در واقع به همین دلیل، این تشبیه به کار برده شد. تا حدی هم مربوط به اعتماد است. اگر توسعه‌دهندگان بدانند چطور به کیفیت رسیدگی کنند و چطور آن را بالا نگاه دارند، می‌توان به آن‌ها اجازه داد که این تصمیم‌گیری‌ها را انجام دهند. در غیر این‌صورت باید نوعی تصمیم‌گیری کنید و بخواهید که برای سرمایه‌گذاری در کیفیت بودجه صرف شود و این می‌تواند خیلی سخت باشد. بنابراین فکر می‌کنم مربوط به اعتماد باشد. اما همچنین مربوط به سرمایه‌گذاری در جایی است که می‌توانید از آن نتیجه بگیرید و این چیزی است که کسب و کار باید از آن اطلاع داشته باشد و به آن فکر کند.بله. فکر می‌کنم اعتماد نکته‌ی مهمی است چون اغلب مواردی هست که توسعه‌دهندگان شکایت زیادی از کیفیت بد و چارچوب‌های بد دارند و می‌گویند باید این را بهبود دهیم، باید این چارچوب را عوض کنیم و ... حرفشان توسط مدیر شنیده می‌شود ولی مدیر می‌گوید این خیلی مهم نیست. اما اگر یک توسعه‌دهنده‌ی خیلی خوب داشته باشید که کسب و کار را بشناسد و این را ثابت کرده باشد و وقتی او می‌گوید: «باید مشکل آن‌ها را حل کنیم چون با این کد به جایی نمی‌رسیم، باید آن را پاک‌سازی کنیم» اگر افراد حوزه‌ی کسب و کار به این فرد یا گروه اعتماد داشته باشند آن وقت است که می‌توانیم ادامه دهیم. اگر مدیران به این افراد اعتماد داشته باشند می‌گویند: «اگر فلانی و بهمانی می‌گویند، پس مهم است و باید این کار را بکنیم. آن‌ها کسب و کار را به طور کلی می‌شناسند؛ شاید باید به آن‌ها گوش دهیم و به آن‌ها اجازه دهیم تصمیم بگیرند.»تا حدودی چیزی که می‌گویی درست است اما از سوی دیگر افراد حوزه‌ی کسب و کار تنها کسانی هستند که می‌توانند بگویند آیا سرمایه‌گذاری در کیفیت در حال حاضر امکان دارد یا خیر. چون ممکن است نیاز داشته باشند تعدادی ویژگی را منتشر کنند و همچنین همان‌طور که گفتیم بدهی فنی وابستگی زیادی به این دارد که کدام بخش‌های سیستم در آینده تغییر خواهند کرد و این چیزی است که توسعه‌دهندگان تا حدی می‌توانند از آن اطلاع داشته باشند. آن‌ها می‌دانند در چند نسخه‌ی بعدی چه خواهد شد اما بینش راهبردی بلند مدت چیزی است که کسب و کار باید به آن برسد. به همین علت است که من اعتقاد دارم مسئله فقط انتقال مسئولیت به توسعه‌دهندگان نیست و باید توسط توسعه‌دهندگان و حوزه‌ی کسب و کار باشد. چون هر کدام بخشی از اطلاعات را دارند پس باید در کنار هم قرار دهند تا به نتیجه برسند و بفهمند که باید کجا، کی و چطور در کیفیت سرمایه‌گذاری کنند.منظور من این بود که توسعه‌دهندگانی هستند که در حوزه‌ی مسئله خبره هستند و به نوعی راهبرد کسب و کار را می‌شناسند و این‌که سامانه به کجا رهنمون است. اگر افراد حوزه‌ی کسب و کار به این توسعه‌دهندگان اعتماد داشته باشند که می‌گویند باید در کیفیت سرمایه‌گذاری کنیم معمولاً حرفشان شنیده می‌شود. اما اگر کسب و کار را نفهمید خیلی دشوار است که این اعتمادسازی را انجام دهید.بله درست است. اگر چنین توسعه‌دهندگانی در تیم داشته باشید خیلی خوش‌شانس هستید. اما این مسئله همچنین انتظارات را از توسعه‌دهندگان تا حدی افزایش می‌دهد که من مطمئن نیستم خیلی‌ها بتوانند این کار را انجام دهند. چون شما فقط به دنبال افراد فنی خوب نیستید، بلکه کسانی که در مورد کسب و کار هم اطلاع دارند و یک فرد فنی خوب بودن به خودیِ خود به اندازه‌ی کافی دشوار است. اگر قرار باشد در مورد کسب و کار هم بدانید واقعاً سخت خواهد شد. برای همین است که من فکر می‌کنم در برخی موارد باید افراد حوزه‌ی کسب و کار و تیم فنی با هم در این مورد کار کنند که به همین علت خیلی سخت است.فکر می‌کنم یک نکته‌ی مهم دیگر باقی مانده باشد. این سؤالی است که فرانک بوشمان چندی پیش مطرح کرد. فرانک بوشمان بیشتر به خاطر کتاب معماری نرم‌افزار مبتنی بر الگو شناخته شده است. او می‌پرسد: بدهی فنی را باید تسویه کرد یا نه؟ به نظر من این مقاله خیلی جالب بود ولی متأسفانه به صورت رایگان در دسترس نیست و باید آن را از IEEE خریداری کنید. اما او می‌گوید: ما همواری بدهی فنی داریم؛ غیرقابل پیش‌گیری است. چطور با آن مواجه شویم؟ یعنی آیا آن را تسویه می‌کنیم یا نه؟ او سه پاسخ به این سؤال می‌دهد. حالت اول پرداخت بدهی است (Debt-free Payment). ما یک قطعه کد یا مؤلفه‌ی بد در سامانه داریم و تصمیم می‌گیریم کاملاً آن را Refactor کنیم یا ممکن است آن را جایگزین کنیم،‌ آن را دور بریزیم و از نو بسازیم یا به یک طراحی پایدار و خوب پیرایش کنیم. فقط زمانی باید این کار را بکنید که کد واقعاً بد است و شما می‌دانید که باید بر اساس آن در آینده به دفعات عملکردهای جدیدی بسازید. حالت دومی که پیشنهاد می‌کند تبدیل بدهی است. شما مؤلفه‌ای یا بخش از سامانه را دارید که بدهی فنی زیادی دارد اما جایگزینی آن راه‌حل عملی نیست. مثلاً یک برنامه‌ی میراثی سی ساله دارید که نمی‌توانید آن را دور بریزید، چون خیلی گران است، یا ریسک زیادی دارد اما می‌توانید بدهی را تبدیل کنید. یعنی سامانه را به چیزی بهتر اما نه بی‌نقص تبدیل کنید. این راه‌حل بهتر و نه بی‌نقص، نرخ بهره‌ی پایین‌تری دارد. بنابراین هنوز هم بی‌عیب نیست، هنوز هم باید برای توسعه‌ی آن هزینه کرد، اما خیلی خیلی بهتر از سامانه‌ی قبلی است و ما استطاعت ساختن راه‌حل بی‌نقص را نداریم چون زیادی گران است و زیادی ریسک دارد. و آخرین حالت که آن را زیاد می‌شنوم و فکر می‌کنم نکته‌ی درستی باشد این است که با آن کنار بیاییم و بهره‌ی آن را بپردازیم. می‌دانیم که کد خوبی نیست، اما آن را تحمل می‌کنیم. چون هر چند خیلی خوب نیست ولی نباید زمانی زیادی را هدر دهیم و هزینه‌ی پیرایش کد نامطلوب به کد بهتر از تحمل کردن آن بیشتر است. فکر می‌کنم این چیزی است که باید همیشه در ذهن داشته باشیم. آیا باید آن را بهبود دهیم؟ یا این‌که هزینه‌ی آن از تحمل کردن آن بیشتر است؟ فکر می‌کنم این مشارکت خیلی خوبی بود. فکر می‌کنم این همه چیز باشد. درست است؟بله، سوِن. خیلی ممنونم که وقت گذاشتی و با من در مورد بدهی فنی صحبت کردی.</description>
                <category>رادیو مهندسی نرم‌افزار</category>
                <author>سید مرتضی هاشمی</author>
                <pubDate>Thu, 28 Oct 2021 20:32:33 +0330</pubDate>
            </item>
            </channel>
</rss>