<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های محمد علی بزرگ‌زاده</title>
        <link>https://virgool.io/feed/@ma.bozorgzadeh</link>
        <description>توسعه‌دهنده نرم‌افزار</description>
        <language>fa</language>
        <pubDate>2026-06-16 10:38:39</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/58281/avatar/cKCkCf.png?height=120&amp;width=120</url>
            <title>محمد علی بزرگ‌زاده</title>
            <link>https://virgool.io/@ma.bozorgzadeh</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/%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/SahabPardaz/%D8%A8%D9%84%D9%87-%DA%AF%D8%B1%D9%81%D8%AA%D9%86-%D8%A7%D8%B2-%D8%AE%D9%88%D8%AF-pxt60cjkrcwv</link>
                <description>در این مطلب درباره کتاب «بله گرفتن از خود» می‌خوانیم. ابتدا کمی از نویسنده کتاب بگوییم. ویلیام اوری، یکی از شناخته‌شده‌ترین افراد در زمینه «مذاکره» است. او به عنوان مشاور، در برخی از پرتنش‌ترین مذاکرات با کشورهایی از قبیل شوروی و یوگوسلاوی سابق، چچن، اندونزی و ونزوئلا شرکت داشته است. تجربه‌های او محدود به مشاوره‌های سیاسی نبوده است. او به تدریس فنون مذاکره به رهبران اتحادیه‌های کارگری و مدیران اجرایی شرکت‌های بین‌المللی می‌پردازد و در زمینه مدیریت تنش و اختلاف‌ها از موارد فامیلی گرفته تا انواع اختلافات محلی یا کاری، در قالب کارگاه و مشاوره تجربه دارد. نخستین کتاب او با عنوان «بله گرفتن» که در سال ۱۹۸۱ منتشر شد با استقبال گسترده‌ای مواجه شد و بیش از ۱۳ میلیون نسخه چاپی فروش کرد. پس از آن چندین کتاب دیگر در این زمینه منتشر کرد. کتاب اخیر او با عنوان «بله گرفتن از خود» پس از ۳۵ سال و کسب تجربه‌های بسیار به نوعی نسخه کامل‌تر کتاب «بله گرفتن» به  شمار می‌رود. به اعتقاد ویلیام چیزی در کتاب نخست جا افتاده بود که اکنون آن را بهتر می‌شناسد و آن، نگرش به درون است. این که اگر بخواهیم بر دیگران تاثیر بگذاریم نخست باید بر خود تاثیر گذاریم و این که اگر بخواهیم مسیر مذاکره و حل‌و‌فصل اختلاف‌هایمان را با موفقیت طی کنیم باید رابطه‌مان را با خودمان به درستی شکل دهیم. البته باید دقت داشت که این کتاب صرفا در باب مذاکره به معنای خاص آن نیست بلکه می‌توان آموزه‌های آن را در بهبود هر نوعی از تنش‌ها و اختلاف‌ها به کار گرفت.در این کتاب، در ۶ گام این نوع نگرش به درون تشریح می‌شود که در ادامه به اختصار درباره هریک توضیح خواهم داد. در توضیح هر گام سعی کرده‌ام وفادار به نوع نگاه نویسنده باشم تا حتی‌الامکان تصویر صحیحی از آنچه در کتاب به آن پرداخته شده ایجاد کنم. جمع‌بندی و نظرات شخصی‌ام را در بخش مجزایی در انتهای مطلب آورده‌ام.گام اول: خودت را جای خودت بگذاراین را بسیار شنیده‌ایم که خودت را جای دیگری بگذار اما این که خودمان را جای خودمان بگذاریم چه معنی می‌دهد؟ مگر جای خودمان نیستیم؟ مطلب این است که خیلی مواقع ما کارهایی می‌کنیم که به ضررمان عمل می‌کند. نویسنده بارها از این عبارت استفاده می‌کند که «دشمن خودمان نباشیم بلکه متحد خودمان باشیم». در بسیاری مواقع، وقتی ما بر سر فرزند یا دوست و همکار قدیمی خود فریاد می‌زنیم یا با او قطع رابطه می‌کنیم یا به او اهانت می‌کنیم، به نفع خودمان عمل نمی‌کنیم. این باعث نمی‌شود که بهبودی در روابطمان ایجاد شود و برعکس گره اختلاف‌ها را تنگ‌تر می‌کند. پس ضروری است اول ببینیم که چه کاری واقعا به نفع ماست؟ چه هدفی داریم و آرامش و رضایت ما واقعا در چیست؟ از خود بپرسیم واقعا دنبال چه هستیم؟ برخلاف انتظار پاسخ به این سوال‌ها بدیهی نیست و ما را به تامل وا می‌دارد. خصوصا وقتی در لایه‌های نیازها و خواسته‌هایمان عمیق می‌شویم. اما چطور می‌توانیم این کار را بکنیم؟ نویسنده ۳ سرمشق در این زمینه دارد. نخست این که از بالا به خود نگاه کنید. در کتاب اصطلاح «زاویه دید از بالکن» به کار رفته است. این تمرینی است برای اینکه رفتارهای ما صرفا واکنش کنترل نشده به شرایط هیجانی و جو داغ حاکم بر تنش‌ها نباشد. سعی کنیم که کمی فاصله بگیریم. از زاویه دید کسی که به موضوع مسلط‌تر است و در آن غرق نشده است ببینیم. فردی که تحت تاثیر عصبانیت، حسادت یا دیگر هیجان‌ها قدرت واکنش هوشمندانه و منطقی را از دست نداده است.سرمشق دوم این است که همدلانه به خودمان گوش دهیم. این که صرفا خود را به واسطه ضعف‌ها سرزنش کرده و آماج اهانت‌ها و منفی‌بافی‌ها قرار دهیم مشکلی را حل نمی‌کند. اگر بخواهیم به خودمان کمک کنیم باید همانند یک دوست و با حس همدلی به خود گوش دهیم تا واقعا خودمان را بشناسیم. و سرمشق آخر این است که از نیازهای‌مان پرده برداریم. این با عمیق‌شدن در خواسته‌ها و افکارمان حاصل می‌شود. مثالی از کتاب بیاوریم:In my negotiation experience, I find that people usually know their position: I want a 15 percent raise in salary. Often, however, they have not thought deeply about their interests --their underlying needs, desires, concerns, fears, and aspirations: Do they want a raise because they are interested in recognition, or in fairness, or in career development, or in the satisfaction of some material need, or in a combination of these?هر چقدر در باب نیازها و علاقه‌مندی‌ها و نگرانی‌های خود عمیق‌تر شویم گزینه‌های خلاقانه‌ بیشتری برای برآورده کردن آن‌ها خواهیم یافت:The deeper you go in uncovering your underlying needs and interests, the more likely you are to invent creative options that can satisfy your interests. In the case of the raise, for example, if your interest is in recognition, then even if budgetary constraints prevent your boss from giving you as high a raise as you had hoped, you might still be able to meet your interest by obtaining a new title or a prestigious assignment. Uncovering interests opens up new possibilities that you might not have thought of before.دقت کنید اینکه خودمان را جای خودمان بگذاریم در مقابل این نیست که خودمان را جای دیگران بگذاریم بلکه هر دو لازم است. خود را جای خود می‌گذاریم تا بدانیم به دنبال چه هستیم. خود را جای دیگری می‌گذاریم تا بتوانیم به این مقصود برسیم. از طرفی، این که اوضاع را از دید طرف مقابل ببینیم خود در شکل گرفتن آن هدفی که دنبالش هستیم کمک می‌کند. شادی و سلامت دیگران، رضایت و حس خوب ما را هم در پی خواهد داشت و ما در عمق وجود خود از اینکه بتوانیم به دیگران کمک کنیم و مشکلاتشان را حل کنیم لذت می‌بریم. اینجاست که سوال «واقعا دنبال چه هستیم» به شناخت دیگران هم ارتباط پیدا می‌کند.گام دوم: بهترین جایگزین درونی بعدیت را بسازنویسنده، ۳۵ سال قبل  از این، در کتاب معروفش «بله گرفتن»، اصطلاح BATNA را معرفی کرده بود که مخفف Best Alternative To a Negotiated Agreement است. این اصطلاح که بعدها شهرت بیشتری یافت، به این معنا است که چنانچه مذاکرات به توافق نرسید بهترین گزینه جایگزین ما چه خواهد بود؟ در آنجا روی بعد بیرونی و مشهود BATNA تکیه می‌شد. به عنوان مثال من دوست دارم اتومبیل رفیقم را بخرم. اگر او حاضر نشد به قیمت متناسبی اتومبیل را به من بفروشد چه می‌کنم؟ در اینجا می‌توانم بهترین گزینه خرید بعدی خودم را مشخص کنم. حدی برای خودم مشخص کنم که بالاترین قیمتی که می‌توانم بپردازم چه مقدار است و اگر گرانتر از چه مقداری بود، بهتر است به سراغ گزینه بعدی بروم. اینکه پیش از تصمیم‌گیری و مذاکره، به BATNA فکر کرده باشم و آن را بدانم باعث می‌شود هنگام بحث و مذاکره، اضطراب کمتری داشته باشم. به هرحال می‌دانم در بدترین حالت چه اتفاقی می‌افتد و خودم را برای آن آماده کرده‌ام. همچنین کمک می‌کند که تصمیم بهتری بگیرم. از قبل تحلیل کرده‌ام که چه مرزهایی برایم قابل قبول است، کجا به نفعم است که نرمش نشان دهم و چه زمانی منطقی است که دست از این گزینه بکشم و به سراغ گزینه بعدی بروم. در این کتاب، نویسنده مفهوم جایگزین درونی یا inner BATNA را مطرح می‌کند. گاهی به سادگی نمی‌توان یک جایگزین جذاب و شدنی یافت. اما جایگزین‌های درونی، انعطاف بیشتری دارد  و دایره انتخاب‌ها را وسیع‌تر می‌کند. بسیاری را می‌بینیم که گزینه جایگزینی برای خود نمی‌سازند، نتیجه‌ای در ذهن دارند و تنها راهکارشان قبول کردن طرف مقابل است و در غیر این صورت واکنششان، سرزنش کردن آن طرف است. سرزنش فرد مقابل و قرار دادن خود در جایگاه قربانی چیزی را حل نمی‌کند. با این روش شما قدرت را از خود گرفته و به فرد مقابل اعطا کرده‌اید.پیشنهاد نویسنده به جای سرزنش، «توانایی در داشتن پاسخ» است. اینکه طرحی برای پاسخی سازنده داشته باشیم. نویسنده از لغت responsability استفاده می‌کند اما تصریح می‌کند که منظورش از این لغت، response-ability است. او از ما می‌خواهد که مالکیت زندگی خود را بپذیریم. آن را به تصمیم‌های دیگران واگذار نکنیم. اهمیتی ندارد که طبیعت و اطرافیان با من چه می‌کنند. این مهم است که من چه واکنشی نشان می‌دهم. بازی من بلکه زندگی من همین است. باید از حالت انفعال، درآمده و بر روی نقشی که خود می‌توانیم ایفا کنیم تمرکز کنیم.گاهی شاید جایگزین‌های بیرونی جذابی در دسترس نباشند، اما کسی نمی‌تواند جایگزین‌های درونی را از شما بگیرد: این که هر اتفاقی که بیافتد شما ایمان خود را از دست نمی‌دهید و دست از تلاش بر نمی‌دارید. این که به عمیق‌ترین نیازها و اهداف زندگی خود وفادار باقی می‌مانید.در یکی از  روایت‌های واقعی این فصل، با فردی مواجهیم که در یک حادثه بر روی یک مین به جا مانده از یک جنگ شش روزه می‌رود و پایش را از دست می‌دهد. او ماه‌های بدی را در بیمارستان با حس افسوس و ناامیدی سپری می‌کرده است. روزی سربازی که در تخت کناری او خوابیده جمله تاثیرگذاری می‌گوید: «این می‌تواند بدترین اتفاقی باشد که برای تو افتاده یا بهترین اتفاق. انتخابش با خود توست!»  فرد به ظاهر قربانی تحت تاثیر این جمله رویکرد جدیدی را در پیش می‌گیرد. او یک شبکه جهانی از بازماندگان مین‌های جنگی شکل می‌دهد و به واسطه خدماتی که در زمینه بهبود اوضاع قربانیان جنگ انجام می‌‌دهد برنده جایزه نوبل و از آن مهم‌تر برنده جایزه حس رضایت درونی از بازی کردن موثر نقش خود در زندگی می‌شود.   گام سوم: تصویرت را بازسازی کنحتما در این مورد شنیده‌اید که می‌توان در چالش‌ها و اختلاف‌ها به جای تصویر برنده-بازنده از ماجرا، تصویر برنده-برنده داشت. در تصویر برنده-بازنده  ماجرا را همچون یک صحنه نبرد خصمانه می‌دانیم که در آن تنها یک نفر پیروز می‌شود و لاجرم دیگری شکست خواهد خورد. اما در تصویر برنده‌-برنده نوعی نگاه حل مساله برای برآورده کردن نیازها و رضایت هر دو طرف داریم. مثالی از کتاب بزنیم:In my work as a mediator, I have found that one of the most effective negotiating strategies is to look for creative ways to expand the pie before dividing it up. For example, the two departments could explore ways in which, through greater cooperation, they could increase sales and justify an increase in the budget for both.اما مشکل اینجاست که پیروی از تصویر برنده-برنده یا تصویر همکاری سازنده در میانه منازعات و درگیری‌ها کار ساده‌ای نیست. در اینجا نیز، مانند گام قبلی، نویسنده برای حل این مشکل، ما را متوجه تصویر درونی‌مان از زندگی می‌کند. او اعتقاد دارد اگر تصویری مثبت از زندگی برای خود بسازیم، آن گاه به یاری آن می‌توانیم در صحنه‌های بیرونی نیز یک نگاه سازنده و برد-برد بسازیم و آن را حفظ کنیم. او از ما می‌خواهد به فرصت‌ها و امکاناتی که در پس ناملایمات وجود دارد توجه کنیم. در واقع، شادی خودمان را بسازیم. او به این جمله آبراهام لینکلن اشاره می‌کند که:I have come to realize that people are about as happy as they make up their minds to be. شاید در شادی‌ها و کامیابی‌های بیرونی محدودیت‌هایی وجود داشته باشد اما شادی‌هایی که مبتنی بر رضایت درونی است، نامحدود است و همه می‌توانند همزمان از آن سهم ببرند. گام چهارم: تمرکزت را حفظ کنساده است که در میانه مشاجرات، گرفتار رنجش‌های مربوط به گذشته یا عصبانیت از شرایط آینده شده و از تمرکز بر روی زمان حال وابمانیم؛ اما تنها زمانی که می‌توانیم در آن نقش بازی کنیم، احساس رضایت کنیم و جریان کار را در جهت بهبود اوضاع پیش ببریم زمان حال است. تنها در صورتی که بر زمان حال تمرکز داشته باشیم می‌توانیم فرصت‌ها را کشف کنیم. این تمرکز در زمان حال در روانشناسی به حالت «flow» موسوم است و قهرمانان ورزشی گاهی از آن تعبیر «zone» می‌کنند:If tennis players, for example, get preoccupied with their last point or the next point, they will not perform well. Being fully present --being in the zone-- they can surrender to the moment and play their best. اما چطور می‌توانیم این تمرکز را حفظ کنیم؟ چطور می‌توانیم با این مقاومت درونی که ما را درگیر پشیمانی از گذشته و نگرانی از آینده می‌کند مقابله کنیم؟ پیشنهاد نویسنده در اینجا نیز به رابطه شما با خودتان برمی‌گردد. اینکه یاد بگیرید که از گذشته‌ها بگذرید. در این بخش از کتاب، جمله‌ای تامل برانگیز از برنارد شاو نقل می‌‌شود:People become attached to their burdens sometimes more than the burdens are attached to them.برخی افراد همواره حس نفرت و کینه‌ای شدید از خاطرات گذشته را با خود حمل می‌کنند اما این احساسات پیش از آن که بخواهد به دیگری آسیب بزند خود ایشان را هدف قرار داده است. از این نظر بخشش پیش از هر چیز به نفع خود ماست و این تنها مربوط به بخشودن دیگران نیست. این شامل بخشش خودمان هم هست. نفرت از خود و خاموش کردن حس عزت نفس، نقش بسیار مخربی بر ما خواهد داشت. نویسنده دامنه این گذشت را حتی از این هم فراتر می‌‌برد. او از ما می‌خواهد به غیر از این که از متهم کردن خود و دیگران دست بر می‌داریم از متهم کردن سرنوشت و زمین و زمان هم عبور کنیم و تجربیاتی که زندگی در اختیارمان قرار می‌دهد را بپذیریم.مورد دیگری که باید با آن مقابله کنیم تا بتوانیم در زمان حال تمرکز کنیم، نگرانی افراطی در مورد آینده است. به این معنا که به این نگرانی‌ها مجالی بیش از حد آنچه شایسته‌اش است بدهیم تا این نگاه، تمامی افکار و احساسات ما را احاطه کند. ضرب‌المثل چینی که در حین این بحث در کتاب نقل شده، شنیدنی است:That the birds of worry and care fly over your head, this you cannot change, but that they build nests in your hair, this you can prevent.دقت داشته باشید که در اینجا در پی نفی کامل گذشته یا آینده نیستم. فکر کردن به هر کدام از این دو در جایگاه خود می‌تواند مفید باشد اما نه به شکلی که تمرکز ما بر روی مهمترین زمانی که در آن نقش داریم -زمان اکنون- را برهم زند:We can visit the past from time to time to learn from it and we can visit the future to plan and take necessary precautions, but we make our home in the only place where we can make positive change happen: in the present moment. گام پنجم: در هر صورت احترام بگذاریدهمه با قانون مقابله‌به‌مثل آشناییم. اگر کسی ما را طرد کند ما هم او را طرد می‌کنیم. اگر مهربان و محترم برخورد کند ما هم همین کار را می‌کنیم. نکته اینجاست که با این رفتار، رابطه‌ای که تخریب شده نمی‌تواند دوباره بازسازی شود. این چرخه‌ اعمال و عکس‌العمل‌های متقابل باعث خواهد شد که هر روز تنش و دلخوری بیشتری ایجاد شود. اما گاهی فقط نیاز است که یک نفر با نگرشی متفاوت دیگران را شگفت‌زده کرده و عملی برخلاف این چرخه معیوب انجام دهد تا در مسیر بازسازی قرار گیریم. نویسنده در فصل‌های مختلف کتاب، شواهد و مثال‌هایی می‌آورد که چطور یک جو سنگین و خصمانه تحت رفتار متفاوت یک نفر، تعدیل شده و مجالی برای همکاری در حل‌و‌فصل مشکلات ایجاد شده است. این تغییر مسیر، می‌تواند صرفا با گوش دادن همدلانه، درک شرایط و نیازهای طرف مقابل و اذعان به آن رخ دهد. نویسنده پیشنهاد می‌کند که از تعلیمات «گروه ویژه» در صحنه‌های گروگان‌گیری استفاده کنیم. تعلیماتی که در یکی از پرچالش‌ترین صحنه‌هایی که می‌توانیم تصور کنیم، کارایی خود را نشان داده است: What is their first rule? Be polite. Give the hostage taker a hearing. Listen with close attention and acknowledge his or her point of view. Do not react, even if, as often happens, the hostage taker goes on the verbal attack. Stay cool and courteous, patient and persistent. In other words, respect and accept the very person who is attacking and rejecting. Meet exclusion with inclusion.احترام گذاشتن به افراد به معنای قبول داشتن رفتار ایشان حتی به معنای دوست داشتن ایشان نیست. این در مثال گروگان‌گیرها هم روشن است:Accepting those who reject us does not mean saying yes to their demands; as the hostage negotiators show, it can often mean saying no, but in a positive manner that acknowledges the other person&#x60;s inherent dignity.احترام، نوعی حق انسانی است که ما برای ایشان قائلیم و آن را پاس می‌داریم. در واقع این نگرش، نوعی احترام به خودمان نیز هست زیرا این احترام به نوع بشر و حقوق اوست. گام ششم: بده و بستانیکی از بحث‌هایی که در این فصل کتاب می‌شود این است که ما اغلب در جمع‌های خانوادگی یا با رفقایمان از قانون بده و بستان پیروی می‌کنیم. محبت و خدماتمان را دریغ نمی‌کنیم و به شکل طبیعی حس رضایت شخصی و نتیجه کارمان را در رفتارهای متقابل می‌بینیم. اما وقتی نسبت‌های فامیلی یا رفاقت قبلی نداریم کمتر خیری می‌رسانیم. می‌خواهیم تا جایی که می‌شود دریافت‌کننده باشیم یا اگر چیزی می‌دهیم پیش از آن اطمینان یابیم که همان مقدار یا بیشتر را دریافت خواهیم کرد. نکته اینجاست که قانون بده و بستان فقط در جمع نزدیکان یا رفقای صمیمی کار نمی‌کند، اگر آن را در روابط با همکاران، مشتری‌ها، کارفرماها و حتی آن دسته از افرادی که با آن‌ها به چالش و اختلاف خورده‌اید به کار ببندید، همان نتیجه را خواهید دید. اما وقتی حسابگری و پرهیز و احتیاط، رفتار غالب دو طرف می‌شود عملا فرصت‌های همکاری و بهره‌مندی از همدیگر می‌سوزد. نویسنده از کتاب معروف «بده و بستان» اثر آدام گرانت شاهد می‌آورد. طبق تحقیقات، افرادی که شخصیت بخشنده دارند، یعنی افرادی که بدون حسابگری‌های افراطی و به شکل پیش‌فرض، دانسته‌ها، تجربیات، محبت و خدمات خود را عرضه می‌کنند در طی زمان نسبت به افرادی که شخصیت گیرنده دارند، پیشرفت بیشتری می‌کنند. این افراد غیر از آن که حس رضایت بهتری از زندگی دارند و بیشتر مورد احترام هستند در نهایت معمولا ثروتمند‌تر و دارای درجه شغلی بالاتر نسبت به هم دوره‌ای‌های خود خواهند شد:One study, for example, carried out by Grant concludes that salespeople who focus on giving genuine service to customers earn more than those who are in it primarily for the money. Another study showed that people who give away more money to charity tend to be happier and end up, on average, earning more. The research suggests that giving works in part because it increases the probability that someone else will do something good for you. Giving, it turns out, is the path to personal satisfaction, both inner and outer. پس این بار نیز دیدیم که افراد ناخواسته به ضرر خود عمل کردند. خواستند با استدلالی از بخشش طفره روند اما در نهایت ضرر کردند چون قوانین بازی و روابط اجتماعی را خوب به کار نمی‌گیرند یا این طور بگوییم چون خودشان را به عنوان یکی از همین انسان‌های خوب نشناخته‌اند و مورد کندوکاو قرار نداده‌اند.اما سوال این است که چطور می‌توان این رفتار بخشش‌گری را در خود ملکه کرد؟ گام‌ها و سرمشق‌های قبلی به شما در این ارتباط کمک می‌کند. چنانچه شما حس رضایت و شایستگی را از درون خود بگیرید، این رفتار، نتیجه طبیعی آن خواهد بود. در واقع شما نه فقط به خاطر بهره‌‌مندی‌های متقابل، بلکه به خاطر لذت و حس معنایی که به زندگی‌تان می‌دهد این کار را می‌کنید.در اینجا البته ذکر این نکته ضروری است که ما نباید در این خاصیت بخشندگی زیاده‌روی کنیم. این خوب است که همیشه بخواهیم بیش از طرف مقابل و پیش از او برای همکاری اقدام کنیم اما این درست نیست که از نیازها و خواسته‌های منطقی خود بگذریم یا از پیگیری افکار و ایده‌های خود دست شسته و خمیری در دست دیگران باشیم:While an adversarial approach may prove costly and ineffective, a soft accommodating approach typically does not work much better. If we give everything away to please the customers, we may not be in business long enough to serve the customer.به بیانی دیگر باید مراقب افرادی که می‌خواهند صرفا به رفتار دریافت‌کننده خود ادامه دهند باشیم:It is, of course, important to be intelligent in one&#x60;s giving and mindful of those who merely take, otherwise you may end up doing yourself a disservice.نظر شخصی‌ام در جمع‌بندی کتابکتاب متنی روان با مثال‌هایی اثرگذار دارد که به دل می‌نشیند اما به خاطر دارم در جلساتی که در ارتباط با این کتاب داشتیم نقدهایی هم می‌شد. یکی از مهم‌ترین آن‌ها این است که در این کتاب صحبتی از «مقاومت» و «عدالت‌خواهی» نیست. این درست است که در بسیاری از تنش‌ها، چنانچه یک طرف به صحبت‌های طرف مقابل همدلانه و بدون پیش‌قضاوت گوش دهد، با درک شرایط و نیازهای طرف مقابل و اذعان به آن می‌تواند چرخه تشدید شونده دشمنی‌ها را قطع کرده و مسیری برای تفاهم و یک نتیجه برد-برد باز کند. اما آیا همیشه این طور است؟ آیا همواره سوء تفاهم‌ها و عدم آگاهی‌ها ریشه مشکلات است؟ آیا همیشه چون یک نفر با گوش شنوا شدن پیش‌قدم نشده بحران ادامه یافته است؟ در کنار مثال‌های کتاب می‌توان مثال‌های دیگری هم گذاشت که تنها مقاومت و مبارزه بوده که باعث شده حقی پایمال‌شده، به صاحبانش برگردد. فکر می‌کنم هرچند تعلیمات این کتاب در بسیاری از اختلاف‌ها و نزاع‌ها کارگشاست اما نمی‌توان با افرادی که روحیه سطله‌جویی و زیاده‌خواهی پیدا کرده‌اند و ندای اخلاق در وجودشان خاموش شده همواره از در سازش و مدارا وارد شد.انتقاد دیگری که به این کتاب وارد می‌دانم این است که شما را از قضاوت خودتان منع می‌کند. گمان من این است که اشتباهی که در اینجا شده است این فرض است که هر نوع حسابرسی و قضاوت منفی از خود منجر به انفعال، عدم تحرک و کشته شده حس عزت نفس در فرد می‌شود. در حالیکه ما می‌توانیم اعمالمان را به قضاوت بنشینیم و خود را متهم کنیم اما همچنان خود را دوست هم بداریم و برای حل مشکلاتمان به خود کمک کنیم. با وجود این نقدها، با این کتاب ارتباط برقرار کرده و آن را دوست داشتم. به عنوان یک فرد شرقی و همین طور یک مسلمان بسیاری از مطالبی که در کتاب می‌خواندم برایم آشنا بود. فرهنگ مشرق زمین با مفاهیم مراقبه، مدارا، گذشت، تامل و سکوت، قرابت دیرینه دارد. آیین‌ها و حتی ورزش‌های شرقی جدا از این مفاهیم نیستند. تم اصلی کتاب شناخت و غور در خود است. از طرفی خودشناسی، یکی از مهمترین مفاهیم دینی ماست. در حدیثی از پیامبر اکرم (ص) هست که «هر کس خودش را بشناسد خدایش را شناخته است». فکر می‌کنم کلید درک این حدیث عبارتی از قرآن باشد که خداوند درباره انسان می‌فرماید: «از روح خودم در او دمیدم». از این جا مشخص می‌شود که چرا شناخت خود به شناخت خداوند می‌انجامد. وقتی خود را عمیقا مطالعه می‌کنیم گرایشاتی متعالی در خود می‌یابیم. چیزی که در این کتاب از آن به عنوان اهداف و انگیزش‌های درونی یاد می‌شود. مثلا اگر زیاد شدن حقوق و یا جایگاه و رتبه شغلی، اهداف و انگیزه‌های بیرونی باشد علاقه به کمک کردن به هم‌نوع و رفع دردهای بشر یا شاد کردن و باسواد کردن ایشان نوعی انگیزش درونی است. پس اینجاست که زمین بازی فراخ می‌شود نه اینکه صرفا تکنیک‌های بازی عوض شود. به همین جهت است که من هم با نویسنده کتاب هم‌عقیده می‌شوم که این کتاب از کتاب‌های قبلی‌اش کامل‌تر و مهم‌تر است.</description>
                <category>محمد علی بزرگ‌زاده</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Mon, 20 Dec 2021 21:54:55 +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>توسعه مبتنی بر تست (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/%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/SahabPardaz/%D8%AA%D8%AD%D9%88%DB%8C%D9%84-%D9%85%D8%B3%D8%AA%D9%85%D8%B1-kuaqvk8r1r4s</link>
                <description>چندی پیش، کتاب تحویل مستمر (Continuous Delivery) را با گروهی از همکاران خوانده و جلسات گپ‌وگفتی پیرامونش داشتیم. برای من کتاب پرفایده و تاثیرگذاری بود. پیش‌تر هم درباره‌ی برخی از سرفصل‌های این کتاب چیزهایی شنیده یا خوانده بودم؛ اما خواندن این کتاب کمک کرد تا ساختاری منظم‌تر از موضوع در ذهنم شکل گرفته و با الگوها، ضدالگوها و تکنیک‌های بیشتری آشنا شوم. به خاطر دارم که کمی بعد، وقتی جلساتی در شرکت با حضور نماینده‌هایی از تیم‌های مختلف برای تدوین مدل بلوغ کیفیت تولید نرم‌افزار داشتیم، یکی از کتاب‌هایی که ارجاعات فراوانی به آن می‌شد و راهگشایمان بود، همین کتاب بود. بارها برای من پیش آمده که مطالب این کتاب در جریان بهبود فرآیند‌های توسعه‌مان بکار آید از جمله وقتی می‌خواستیم تست‌های پذیرش (acceptance)  و کارایی (performance) را در سبد تست‌های خودکار محصولاتمان قرار دهیم و یا این اواخر وقتی می‌خواستیم مقدمات فنی تجزیه یک تیم بزرگ را آغاز کنیم؛ یعنی در راه شکستن یک سیستم بزرگ به چندین زیرسیستم که هر کدام حیطه‌ی کسب و کاری (business) مشخصی را هدف قرار دهند و هر کدام مولفه‌ها و پایپلاین استقرار (deployment pipeline) مستقل خود را داشته باشند. اما برویم سراغ کتاب.جهنم چه شکلی است؟اگر بخواهم درباره‌ی این کتاب صحبت کنم به نظر من بی‌شک پرده‌ی اول، تصویری از جهنم تیم‌های توسعه است. در جهنم توسعه‌دهنده‌ها، استقرار مولفه‌های نرم‌افزاری و مهیا کردن اولیه‌ی محیط آن‌ها به شکل دستی انجام می‌‌شود. فقط چند نفری هستند که فوت‌و‌فن این کار را می‌دانند؛ اما خود آن‌ها هم با دعا و ثنا کار را پیش می‌برند. به همین جهت است که از گام‌های استقرار، اتفاقات بدی که در حین آن می‌تواند بیفتد و راه‌حل‌هایش، سند مفصلی می‌سازیم؛ اما گویی با هر استقرار جدید با مشکلات و ناهماهنگی‌های تازه‌ای روبرو می‌شویم تا همواره سطح آدرنالین خونمان بالا بماند. گاهی خطاهایی داریم که آن‌ها را ظرف چند دقیقه برطرف کرده‌ایم؛ اما دو سه ساعت پراضطراب برای استقرار آن باید کار کنیم! در جهنم، خیلی از تست‌ها را به شکل دستی انجام می‌دهیم؛ اما وقت نمی‌کنیم همه‌ی آن‌ها را در همه‌ی ریلیزها دوباره چک کنیم، پس به اندکی از آن‌ها بسنده می‌کنیم؛ اما محیط عملیاتی گاه‌و‌بیگاه خطاهای جدیدی برایمان رو می‌کند. برخی خطاهایی که سابقا درست کرده بودیم ظاهرا دوباره برگشته؛ اما چه کنیم؟ ما نمی‌توانیم نبود همه خطاهای قبلی‌ خود را در همه‌ی ریلیزها دوباره به شکل دستی چک کنیم!ما یک محیط آزمایشگاهی داریم. اینقدر هم ساده‌دل نیستیم که همه چیز را اولین بار در محیط عملیاتی آزمایش کنیم؛ اما هر از چند گاهی می‌بینیم که آنچه در محیط آزمایشگاهی موفق بوده، در محیط عملیاتی با خطا مواجه می‌شود. از واکاری ریشه‌ی خطا در می‌یابیم که کانفیگ این دو محیط متفاوت است. این دو محیط با روال یکسانی کانفیگ نشده‌ و هر کدام به شکل دستی و با ترتیب و تاریخچه‌ای متفاوت برپا شده‌اند. تنظیمات پایگاه داده، اپ سرورها و سیستم‌عامل‌ها متفاوت است. گاهی خطاهایی حیاتی گزارش شده و باید به سرعت برطرف شود؛ اما واقعا عقلمان قد نمی‌دهد که مشکل چیست. پس باید تغییرات اخیر را بازگردانیم (rollback) که البته اضطرابش کمتر از استقرار اولیه‌ی این تغییرات نیست.در جهنم معمولا تصمیماتی می‌گیریم که شرایط را بدتر می‌کند. چون تست نکرده‌ایم، زمان ریلیز را عقب می‌اندازیم. چون زمان ریلیز را عقب می‌اندازیم کارهای جدیدی اضافه شده که آن‌ها هم تست می‌خواهند. بسته‌ای که در ریلیز قرار می‌گیرد، بزرگ شده و ریسک‌های بیشتری را در برمی‌گیرد. پس فیدبک‌ها با تاخیر می‌رسند؛ چه از ناحیه‌ی تسترها و چه از ناحیه‌ی مشتری‌ها. فیدبک‌ها زمانی می‌رسند که توسعه‌دهنده، دیگر آن مسئله و پیاده‌سازی‌اش را در حافظه‌ی نزدیک خود ندارد. تعاملات آدم‌ها در جهنم، خود بحث دیگری است. افراد در جهنم در سیلوهای مختلفی زندگی می‌کنند. سیلوهای مجزای مدیران محصول، برنامه‌نویس‌ها، پایگاه داده، تست، استقرار، امنیت و ... . افراد هر سیلو، بر این باورند که وظایف خود را به درستی انجام داده‌اند و سیلوهای دیگر را مقصر بروز مشکلات، دیرکردها و بحران‌ها می‌دانند. شاید فکر کنید قربانی این جهنم مشتری‌ها هستند؛ اما ترحم بر این توسعه‌دهنده‌ها جایزتر از مشتری‌هاست. اگر بگوییم مشتری‌ها حرارت این جهنم را حس می‌کنند، بی‌شک توسعه‌دهنده‌ها خود در این جهنم می‌سوزند.بهشت کجاست؟نسخه‌‌ی محصول و محیطی که می‌خواهیم آن نسخه را در آن مستقر کنیم را انتخاب کرده و دکمه‌ی استقرار را می‌زنیم. این فرآیند استقرار در بهشت است! بهشتی‌ها وقت خود را صرف کارهای تکراری نمی‌کنند. بهشتی‌ها به شدت از کارهای کسالت‌بار گریزانند؛ خصوصا اینکه  یک کار هم کسالت بار باشد و هم پراسترس. و به همین علت علاقمند به خودکارسازی (automation) هستند. در اینجا، مجموعه‌‌ی کاملی از تست‌های خودکار داریم که هم اطمینان و هم سرعت در رسیدن به اطمینان را به ارمغان می‌آورند. تست‌های واحد (unit)، تست‌های پذیرش (acceptance) و تست‌های ظرفیت (capacity)، از این دسته تست‌ها هستند. در اینجا مفهوم تست، فراتر از صرف تست مولفه‌های نرم‌افزار است. همه‌ی گام‌های ما در فرآیند توسعه و تحویل نیز تحت سیطره‌ی تست‌ها قرار دارند؛ یعنی تست اسکریپت‌های ‌build و package و deploy، تست فرآیند‌های migration و rollback، تست مهیا کردن و پیکربندی (configuration) محیط‌های مختلف و ... . دقت کنید که وقتی صحبت از پیکربندی می‌کنیم، به مجموعه‌ای وسیع از امور اشاره داریم. پیکربندی یعنی آنچه در یک محیط (عملیاتی یا تستی) بنا می‌شود از جمله: توپولوژی شبکه، سیستم‌عامل‌ها، انواع کتابخانه‌ها و برنامه‌های جانبی نصب شده بر روی سیستم‌ها، سرویس‌های زیرساختی، سرویس‌های شخص ثالث (third party)، مولفه‌های محصول، مخازن و پایگاه‌های داده و خاصه تنظیمات و  نسخه‌ی دقیق هر کدام از این مولفه‌ها. در بهشت، نه تنها پیکربندی به شکل خودکار انجام می‌شود بلکه اسکریپت‌های مربوط به بنا کردن یک محیط و تنظیماتی که قرار است اعمال شود، همگی شهروند درجه یک (first class citizen) هستند. آن‌ها هم مانند کدها در مخزن کد قرار می‌گیرند. بازبینی می‌شوند و تست دارند. و چون محیط‌های تست و عملیاتی با اسکریپت‌ها و روال‌های یکسانی برپا می‌شوند، کمتر پیش می‌آید که با اتفاقاتی روبرو شویم که برای اولین بار در محیط عملیاتی رو می‌شوند. آنچه در اینجا همواره می‌بینیم، تغییراتی کوچک است که به شکل خودکاری تست شده و به شکل مطمئنی تا محیط عملیاتی پیش می‌رود و روزانه بارها این روند تکرار می‌شود.در بهشت، همه خود را مسئول رساندن موفقیت‌آمیز امکانات و خدمات به مشتری‌ها دانسته و برای این کار با هم همکاری و تعامل دارند. اگر برای برآورده کردن اهداف کسب و کار لازم به تعاملات بیشتر بین برخی افراد باشد، آن‌ها به هم نزدیک‌تر می‌شوند و گاهی تا جایی پیش می‌رود که مرز بین سیلوها به کلی از بین رفته و افراد خود را در تیم واحدی با ماموریت یکسانی می‌بینند.مسیر ما به سمت بهشتمقصد مشخص است؛ اما چطور این مسیر را طی کنیم؟ سوالات و چالش‌های متعددی مطرح است:ما با تست‌های واحد، آشنایی زیادی داریم؛ اما انواع دیگری از تست‌ها هم هستند. مثلا تست‌های پذیرش (acceptance) که زبان و لحنی نزدیک به کاربران داشته و به شکل سیستمی در محیطی مشابه عملیات اجرا می‌شوند.  این دسته از تست‌ها را چگونه می‌توان توسعه داد؟‌ چه الگوها و پرکتیس‌هایی برای نوشتن تست‌های پذیرش وجود دارد؟ همین سوال در مورد تست‌های کارایی (performance) و بار (load) و فشار  (stress) هم مطرح است. این تست‌ها را چطور می‌شود توسعه داد و نگهداری کرد؟ و چگونه باید آن‌ها را در پایپلاین استقرار خود فراخوانی کرد؟ آیا می‌شود چک‌ها و تست‌های امنیتی را نیز به شکل خودکار و در پایپلاین استقرار انجام داد؟ برخی از این تست‌ها و تحلیل‌ها زمانگیر هستند. چطور می‌شود آن‌ها را طوری انجام داد که بتوانیم همچنان فیدبک‌های سریع و ریلیزهای متعدد و مستمر داشته باشیم؟ اگر قرار است از مزایای برخی از انواع تست‌های غیرماشینی مانند تست‌های کاوشگرانه (exploratory)، تست‌های جمعیتی (crowd testing) و dogfooding بهره ببریم، چطور می‌توانیم آن را با محیط خودکار و پرشتاب خود همراستا کنیم؟ برای استقرار تغییرات پیچیده چه راهکارها و تکنیک‌هایی وجود دارد؟ برای مثال تغییراتی را که با مهاجرت داده (data migration) یا حتی تغییر زیرساخت‌ها همراه است را چطور باید انجام دهیم؟ ...گاهی هم سوالات ما در جزییات و گام‌ها نیست. مشتاقیم با تصویر کلی (big picture) ماجرا آشنا شویم و می‌خواهیم بدانیم چگونه می‌توان این گام‌ها را به هم متصل کرده و یک پایپلاین استقرار را سروشکل داد. خوشبختانه این کتاب در هر دو جنبه‌ی یادشده گفتنی‌های زیادی برای ما دارد. به عنوان مثال در فصل ۵ با آناتومی پایپلاین استقرار آشنا می‌شویم و تصویر کلی در ذهنمان شکل می‌گیرد. فصل ۵ کتاب، صفحه ۱۱۱، آناتومی پایپلاین استقراردر مورد چالش‌های دیگر نیز به فراخور در فصل‌های مختلف بحث شده است. به عنوان مثال فصل‌های مستقلی در مورد هر یک از مباحث تست‌های پذیرش، تست‌های مربوط به ویژگی‌های غیرعملکردی (nonfunctional) و تحلیل‌های امنیتی، مدیریت داده و تکنیک‌های مربوط به مهاجرت داده‌ها، مدیریت زیرساخت‌ها و محیط و ... در نظر گرفته شده است. در این کتاب بسیاری از تکنیک‌هایی  را که در ارتباط با مباحث تست، خودکارسازی و استراتژی‌های استقرار و ریلیز شنیده‌اید مرور خواهید کرد و شاید با موارد جدیدی نیز روبرو شوید. برای نمونه، به برخی از تکنیک‌هایی که در این کتاب بحث می‌شود و هر کدام می‌تواند بالقوه پاسخ یکی از چالش‌های شما باشد، اشاره می‌کنم: استقرار آبی‌-سبز (blue-green deployment) برای رسیدن به مدت پایین بودن صفر (zero downtime).ریلیز قناری (canary release) برای کاستن از میزان ریسک ریلیز و همینطور تست کردن برخی جنبه‌های کارایی که در محیط‌های غیرعملیاتی قابل انجام نیست. تست A/B برای آشنایی با ترجیحات کاربران یا مقایسه نتایج عملکرد راه‌حل‌های مختلف با هم. فلگ زدن برای ویژگی‌ها (feature flag) و شاخه زدن مبتنی بر انتزاع  (branch by abstraction) برای اینکه بتوانیم هم به شکل مستمر کدهای جدید را در مخزن کد ادغام کنیم (continuous integration) و هم بتوانیم این را از دید مصرف‌کنندگان سرویس مخفی کرده و تا زمان عملیاتی شدن ویژگی‌های جدید، سرویس‌ها را به همان شکل سابق ارایه کنیم.تکنیک چرخ ضامن‌دار (ratcheting) برای وقتیکه می‌خواهیم خطاهای مربوط به تحلیل‌ها‌ی استاتیک را به صفر رسانده یا میزان پوشش تست را تا حد معینی افزایش دهیم؛ اما حجم بزرگی از کد جلوی روی‌ ما قرار دارد که نمی‌توانیم به یکباره این کار را انجام دهیم.تکنیک کش کردن لاگ‌های رخداد و ماخذ کردن رخدادها (event sourcing) به هنگام عقب‌گرد (revert) در مهاجرت داده‌ها (data migration).تکنیک استفاده از ماشین‌های مجازی (virtual machine) برای برپا کردن سریع محیط‌های تست طوریکه بتوانیم زیرساخت‌ها را با سرعت بالا بر اساس تصاویر (image) از پیش تهیه شده برپا کنیم....   گزیده‌ای از حکمت‌هااین کتاب ،چندان به ابزارها نمی‌پردازد. در برخی فصل‌ها اشاره‌ای گذرا به برخی ابزارهای متداول یک موضوع می‌کند؛ اما این صرفا از جهت آشنایی و اشاره است. تلاش اصلی کتاب، آشنا کردن مخاطب با اصول، پرکتیس‌ها، تکنیک‌ها و مهم‌تر از آن تحلیل مزایا و معایب راهکارهاست. به‌همین علت است که این کتاب که در سال ۲۰۱۰ نگاشته شده، همچنان برجسته‌ترین کتاب در حیطه‌ی مورد بحثش به حساب می‌آید. دوست دارم در پایان این نوشتار دست‌کم به عنوان نمونه هم که شده، برخی از اصول و به تعبیر من حکمت‌هایی را که در این کتاب مطرح شده، ذکر کنم. برخی از این اصول به تناسب موضوع چندین بار و در فصول مختلف کتاب تکرار شده‌اند:اسکلت و بنای اصلی پایپلاین استقرار خود را از همان ابتدای پروژه شکل دهید.مراحل پایپلاین را بر اساس ایده سریع شکست خوردن (fail fast) بنا کنید.از شاخه اصلی کدبیس فاصله نگیرید. تغییراتی کوچک داشته باشید که به شکل مستمر در کدبیس ادغام می‌شوند.همه چیز را در مخزن کد قرار دهید: کد، مستندات، اسکریپت‌های تولید مولفه‌ها و استقرار، تنظیمات محیط‌های مختلف، ... .خودکارسازی را بر مستندسازی ترجیح دهید. چیزی که خودکار شده  مستند، قابل ارزیابی و بازبینی، تکرار پذیر و با سرعت قابل اجراست و چون باید قابل اجرا باشد، به‌روز هم هست. انجام شده (done) به معنای منتشرشده در محیط عملیاتی (released) است و در غیر این‌ صورت، کار به پایان نرسیده است.هر نسخه از آرتیفکت‌های باینری شما باید تنها یکبار ساخته شود. ساختن مجدد یک نسخه از آرتیفکت برای استفاده در محیط‌های مختلف خطاست.اطمینان یابید که فرآيند استقرار شما، غیرحساس به تکرار (idempotent) است.تا جای ممکن استقرار موضوعات مختلف را همزمان نکنید. به عنوان مثال ویژگی‌های جدید و مهاجرت داده را همزمان نکنید.این بود معرفی کوتاه من از کتاب خواندنی تحویل مستمر. امیدوارم شما را به خواندن آن ترغیب کرده باشم و یا اگر آن را مطالعه کرده‌اید، این نوشتار یک یادآوری مسرت‌بخش بوده باشد. </description>
                <category>محمد علی بزرگ‌زاده</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Sun, 23 Aug 2020 11:02:43 +0430</pubDate>
            </item>
                    <item>
                <title>شرکت خلاقیت</title>
                <link>https://virgool.io/SahabPardaz/%D8%B4%D8%B1%DA%A9%D8%AA-%D8%AE%D9%84%D8%A7%D9%82%DB%8C%D8%AA-gzbeljjzwtlo</link>
                <description>مدتی پیش کتاب شرکت خلاقیت را با گروهی از همکاران خواندیم و جلسات گپ‌وگفتی درباره‌اش داشتیم. برای من کتابی تاثیرگذار و جذاب بود. مشتاق شدم چند پاراگراف از حال وهوای این کتاب بنویسم و به‌اشتراک بگذارم:اد کتمال در رشته‌های فیزیک و علوم کامپیوتر درس خوانده و از کودکی مجذوب انیمیشن‌های دیزنی‌ بوده است.  او این شانس را داشت که در هیجان‌انگیزترین محیط تحقیقاتی که تصور می‌کرد مشغول به کار شود. در واقع او و دیگر محققان جوان و باانگیزه، تولد این علم جدید را شکل می‌دادند: اولین الگوریتم‌ها در زمینه نور، حرکت، سه بعدی‌سازی و اولین انیمیشن‌های کوتاه تولید شده با کامپیوتر که رویاهایشان را به پرواز در‌ می‌آورد.اما یک سوال جدی در ذهن کتمال وجود داشت؛ اینکه چطور می‌شود این شور و هیجان، این میزان خلاقیت و نوآوری، این انگیزه و کارآمدی را همان‌طور که در گروه تحقیقاتی تجربه کرده بود، بعد از دانشگاه هم حفظ کرد؟ چگونه می‌شود یک شرکت خلاق و پیشرو را شکل داد؟ کتاب‌های مدیریتی آن  زمان را می‌خواند اما در این مورد چیزی پیدا نمی‌کرد. با خود فکر کرد که جواب خیلی هم پیچیده نیست. اگر همان فضا و همان اصول و ارزش‌ها را حفظ می‌کردند، همان نتایج را هم می‌گرفتند.در این کتاب با داستان پیکسار آشنا می‌شوید. داستان شرکتی که بر طبق این اصول بنا شد. در  درجه‌ی اول این افراد و آدم‌ها بودند که این شرکت را شکل می‌دادند. آدم‌هایی باهوش، با تخصص‌ها و سبک‌‌‌های مختلف کاری و با شور و انگیزه‌ی درونی. خیلی‌ها بر این تصورند که این ایده‌های ناب است که سازمان‌های موفق را می‌سازد اما کتمال افراد را مقدم بر ایده‌ها و سازنده‌ی آن‌ها می‌داند.If you give a good idea to a mediocre team, they will screw it up. If you give a mediocre idea to a brilliant team, they will either fix it or throw it away and come up with something better... Ideas come from people. Therefore, people are more important than ideas.بنابراین اولین وظیفه‌ی ما پیدا کردن و استخدام کردن این افراد است. افرادی که از خودمان بهتر هستند:Always take a chance on (hiring someone) better (than you), even if it seems threatening.البته تنها یافتن بهترین‌ها کافی نیست. باید دست آن‌ها باز باشد تا خودشان کارها را بر عهده گیرند:We want people to feel like they can take steps to solve problems without asking permission.و شما به‌عنوان یک مدیر، ضرر نخواهید کرد؛ چون راه را باز می‌کنید تا مشکلات بیشتری حل شود:If we allow more people to solve problems without permission, and if we tolerate (and don&#x27;t vilify) their mistakes, then we enable a much larger set of problems to be addressed.یادتان باشد هیچ وقت نمی‌توانید از این افراد بخواهید که یک کار معمولی انجام بدهند. آن‌ها برای اینکه انگیزه و اشتیاق داشته باشند؛ باید یک کار فوق‌العاده انجام بدهند. در اینصورت است که کار برایشان معنی و حس‌وحال پیدا خواهد کرد. برای آن‌ها لذتی با این قابل مقایسه نیست. پول و عناوین برای این آدم‌ها آنقدر مهم نیستند که اثربخشی و بی‌نظیر بودن کارشان اهمیت دارد. بیایید از خودشان بشنویم. از زبان یکی از بهترین کارگردان‌هایی که خاطرات انیمیشن ما را ساخته است:John coined a new phrase: &quot;Quality is the best business plan&quot;. What he meant was that quality is not a consequence of following some set of behaviors. Rather, it is a prerequisite and a mindset you must have before you decide what you are setting out to do.بنابراین هدف، ساختن چیزی فوق‌العاده است:Making something great is the goal.اگر هم گاهی درگیر امور پیش‌ پا افتاده و کسالت‌بار بشوند؛ تنها به این جهت است که راه را برای آن هدف حماسی‌ باز کنند:In order for greatness to emerge, there must be phases of not-so-greatness.کتمال این جنس آدم‌ها را  پیدا کرده و از آن‌ها دعوت به همکاری می‌کند. اما آنچه همواره ذهن او را درگیر خودش می‌کند فرهنگ و روابط کاری بین این آدم‌ها است. با وجود سابقه‌ی تحصیلاتی و تجربه‌ی کارهای فنی، اساس تفکرات و نکته‌ سنجی‌های مدیریتی اِد کتمال در همین حوزه‌ی فرهنگ کاری است. او توجه ویژه‌ای به صداقت و صراحت دارد. به این که محیطی داشته باشیم که افراد بدون ترس و واهمه نظراتشان را بیان کنند؛ بازخورد بدهند و در امور مشارکت کنند. در این راه با ریزبینی خاصی به جنگ هر چیزی می‌رود که این فرهنگ را تهدید می‌کند. می‌توانید حساسیتش را در چیدمان اتاق کنفرانس یا اتاق جلسات Brain Trust ببینید. او می‌گوید میز گرد بهتر از میز مستطیل است چون بالا و پایین و کانون توجه ندارد! کارگردان نباید در جلسات Brain Trust ایده‌ای را تخطئه کند یا با جانب‌داری از نظری، راه بحث‌های دیگر را ببندد. اگر با بیان هر ایده‌ی جدیدی افراد بر می‌گردند که نظر کارگردان یا پیش‌کسوت قهرمانشان را از صورتش بخوانند و حرف‌هایشان را با او تنظیم کنند؛ یعنی جلسه درست پیش نمی‌رود. حتی اگر استیو جابز باشی و این فضا را خراب کنی کتمال از تو می‌خواهد که در این جلسات شرکت نکنی! کتمال کار خود را محافظت از این فضا می‌داند:The way I see it, my job as a manager is to create a fertile environment, keep it healthy, and watch for the things that undermine it. I believe, to my core, that everybody has the potential to be creative -whatever form that creativity takes- and that to encourage such development is a noble thing.و استیو جابز اگر چه خودرایی‌هایی دارد، اما در عین حال خیلی باهوش است و این منطق را می‌فهمد و قبول می‌کند!When it comes to creative inspiration, job titles and hierarchy are meaningless.با خواندن کتاب شرکت خلاقیت، هم با یک مانیفست مدیریت، تیم‌سازی و سازمان‌سازی آشنا می‌شوید؛ هم اصول این فرهنگ کاری را می‌بینید و در جریان روایت داستان پیکسار و دیزنی قرار می‌گیرید. این یک داستان واقعی است و به همین علت است که در آن، چالش‌ها، تغییرها و امور پیش‌بینی‌ نشده خیلی بیشتر از موارد تحت‌کنترل و از پیش‌ قابل‌ برنامه‌‌ریزی، رسمیت دارند. کتمال نمی‌خواهد از چالش‌ها جلوگیری کند. اگر چالشی نباشد چیز جدیدی هم نیست. موفقیت و افتخاری هم نیست. کافی است که از پس این چالش‌ها برآییم:Management&#x27;s job is not to prevent risk but to build the ability to recover.کتاب در مورد خلاقیت است اما نگاه کتمال با نگاه رایج به خلاقیت متفاوت است. نگاه او این نیست که خلاقیت حاصل نبوغ آنی قهرمانان و اسطوره‌ها است. کتمال به عنوان فردی که سال‌ها با همین قهرمان‌های ما زندگی و کار کرده، این روایت ساده‌انگارانه و جعلی را قبول ندارد. از نظر او خلاقیت نتیجه‌‌ی یک فرآیند مداوم از تکرارها و بازخوردهای صریح است.Creativity has to start somewhere, and we are true believers in the power of bracing, candid feedback and the iterative process --reworking, reworking, and reworking again, until a flawed story finds it through-line or a hollow character finds its soul.بله؛ چهره‌ی واقعی آدم‌های خلاق را این گونه خواهیم دید که خود را وقف تلاشی مستمر می‌کنند.Creative people discover and realize their visions over time and through dedicated, protracted struggle. In that way, creativity is more like a marathon than a spring.و «شکست» ابزاری است که این آدم‌ها برای رسیدن به اهدافشان دارند. کتمال اشاره می‌کند که ما از کودکی شکست را امری نکوهیده و منفی می‌دانیم و این ریشه‌ای عمیق در روحیات و باورهای ما دارد. در بزرگسالی هرچند شکست را بپذیریم یا فردی را به خاطر آن توبیخ نکنیم؛ اما همچنان شکست را منفی می‌دانیم.اما خطر شکست نخوردن بیشتر است. افرادی که خواسته‌اند از هرگونه شکستی اجتناب کنند؛ به ناچار از ابداع و نوآوری پرهیز کرده‌اند.If you put your faith in slow, deliberative planning in the hopes it will spare you failure down the line: well, you&#x27;re deluding yourself. For one thing, it&#x27;s easier to plan derivative work, things that copy or repeat something already out there. So if your primary goal is to have a full worked out, set-in-stone plan, you are only upping your chances of being unoriginal. Moreover, you cannot plan your way out of problems. While planning is very important, and we do a lot of it, there is only so much you can control in a creative environment.این سیاست، احتمال شکست خوردن را بیشتر می‌کند:The attempt to avoid failure, in other words, makes failure more likely.کتمال در کتابش پیکسار را از وقتی ضعیف و بی‌حامی بود تا وقتی اسم و رسم و جایگاهی به پا کرده بود روایت می‌کند. رسیدن به دوران شکوفایی همانقدر که مسرت‌بخش است می‌تواند ترسناک هم باشد. وقتی به هدفمان رسیدیم، وقتی آن محصول بی‌نظیر و تحسین‌شده خود را ساختیم، پس از آن چه باید کرد؟ بسیاری از سازمان‌‌هایی که پس از چندی، روی موفقیت را می‌بینند؛ درست در همین مرحله راه خود را گم می‌کنند. سازمانی که اکنون بزرگ شده، چون دیو گرسنه‌ای است که باید سیر شود. افراد با خود می‌اندیشند که ما یک راه تجربه‌‌شده داریم؛ همان را تکرار می‌کنیم و این دیو ترسناک را آرام می‌کنیم. اما تکرار کردن در تضاد با خلاقیت و ابتکار و همچنین در تعارض با پیشرفت‌ها، دگرگونی‌ها و تغییرات جهان ماست و همین می‌تواند مسیر سقوط سازمان باشد. می‌توان به ایده‌ها و مسیرهای خلاقانه‌ی جدید فکر کرد اما آن‌ها هم اثبات‌‌ نشده‌‌ و خام هستند. اِد کتمال آن‌ها را بچه‌های زشتی می‌داند که هنوز نیاز به مراقبت دارند. باید برایشان خرج کنی و کژتابی‌هایشان را تحمل کنی تا بتوانند آینده را بسازند. کتمال مسیر درست را این می‌داند که هم دیو گرسنه را سیر کنی و هم از بچه‌ های زشت مراقبت کنی. البته این یک مراقبت معقول و منطقی است و قرار نیست برای همیشه ادامه داشته باشد.A new thing is hard to define; it&#x27;s not attractive, and it requires protection. When I was a researcher at DARPA, I had protection for what was ill-defined. Every new idea in any field needs protection. Pixar is set up to protect our director&#x27;s ugly baby. Of course you can&#x27;t protect the baby forever. At some point, it has to grow up and change into something, because the beast is still there. That&#x27;s a positive thing. Because sometimes the ugly baby would rather play in the sandbox forever.این‌ها جلوه‌هایی از یک کتاب خواندنی بود که نویسنده‌ی آن با علاقه و اشتیاق فراوان، بهترین حکمت‌ها و مهمترین رمز و رازهای شکست‌ها و کامیابی‌هایش را به خواننده تقدیم می‌کند.</description>
                <category>محمد علی بزرگ‌زاده</category>
                <author>محمد علی بزرگ‌زاده</author>
                <pubDate>Wed, 08 Apr 2020 00:24:16 +0430</pubDate>
            </item>
            </channel>
</rss>