استفاده از if/else در اغلب اوقات منجر به طراحی پیچیده می شود و در نهایت کدی خواهیم داشت که خوانایی کمتری دارد.
با این وجود، if/else به عنوان یک راهحل بالفعل برای تقسیمبندی و انشعاب کدها تبدیل شدهاست. که این مساله منطقی به نظر میرسد. این یکی از اولین چیزهایی است که به هر یک از توسعه دهندگان مشتاق آموزش داده میشود. متاسفانه، بسیاری از توسعه دهندگان هرگز به استراتژیهای مدیریتی مناسبتری پیشرفت نمیکنند.
برخی با این شعار زندگی میکنند: if/else یک چکش است و همه چیز میخ است.
ناتوانی در تعیین زمان استفاده از یک رویکرد مناسبتر، از جمله آن مواردی است که نیروی تازه کار (Junior) را از نیروی متخصص (Senior) متمایز میسازد.
من برخی از تکنیک ها و الگوها را به شما نشان می دهم که به این عمل هولناک پایان می دهد.
مثال زیر یک تصویر برجسته از آنچه اتفاق می افتد را نمایش میدهد هنگامی که شما درمانده هستید و فکر می کنید If-Else عالی است.
فقط با حذف بلوک else می توان آن را ساده کرد.
حرفه ای تری شد ، درست است؟
به طور مرتب متوجه خواهید شد که هیچ نیازی به یک بلوک دیگر وجود ندارد. مانند این مورد، شما میخواهید کاری انجام دهید که اگر یک شرط خاص برای شما برآورده شود فورا return شود.
اگر می خواهید براساس برخی ورودی های ارائه شده مقدار جدیدی به یک متغیر اختصاص دهید ، مزخرفات If-Else را متوقف کنید - رویکرد قابل خواندن تری وجود دارد.
با وجود سادگی ، افتضاح است. در ابتدا ، If-Else به راحتی با یک سوئیچ در اینجا جایگزین می شود. اما ، ما می توانیم با حذف Else-if و موارد دیگر این کد را حتی بیشتر ساده کنیم.
اگر else if و else را بردارید کدی تمیز و قابل خواندن برای ما باقی مانده است. توجه داشته باشید که من همچنین سبک را تغییر داده ام.
اغلب، من متوجهشدهام که اجرای یک متد در صورتی که با مقادیر نامعتبر فراهم شدهباشد، منطقی نخواهد بود.
فرض کنید که ما متد DetermineGender را از قبل داریم، با این شرط که مقدار ورودی ارایهشده باید همیشه ۰ یا ۱ باشد.
اجرای متد بدون اعتبار سنجی معنی ندارد. بنابراین ، قبل از اینکه اجازه دهیم متد به اجرای خود ادامه دهد ، باید برخی پیش شرط ها را بررسی کنیم.
با استفاده از تکنیک guard clause defensive coding مقادیر ورودی متد را بررسی خواهید کرد و تنها در صورتی پیش خواهید رفت که این متد را اجرا کنید.
در این مرحله ، ما اطمینان حاصل کرده ایم که منطق اصلی تنها در صورتی اجرا می شود که مقدار در محدوده مورد انتظار قرار گیرد.
هم اکنون IF ها با ternary operator جایگزین شده اند بنابراین دیگر منطقی نیست که در پایان پیش فرض "Unknown" وجود داشته باشد.
فرض کنید به شما بگویند که باید عملیاتی را انجام دهید که براساس برخی شرایط تصمیم گیری های متناسب دارد، و ما میدانیم که بعدا و در آینده باید عملیات بیشتری را به این موارد اضافه کنیم.
شاید یکی تمایل به استفاده از If-Else داشته باشد. و درست هم هست که اضافه کردن شرط جدید به این شروط کار راحتی است. با این حال این روش از نظر نگهداری طراحی خوبی نیست.
با دانستن اینکه بعداً باید عملیات جدید اضافه کنیم ، می توانیم If-Else را به یک dictionary تبدیل کنیم.
خوانایی بسیار افزایش یافته است و استدلال در مورد این کد آسان تر است.
توجه داشته باشید که ، dictionary فقط در داخل متد برای اهداف نمایشی قرار داده شده است.
این یک مثال کمی پیشرفته تر است.
اغلب، شما خودتان خواهید دید که باید بخشی از یک برنامه را گسترش دهید. به عنوان یک توسعه دهنده تازهکار، ممکن است تمایل داشته باشید این کار را فقط با اضافه کردن یک عبارت اضافی If-Else انجام دهید.
بیاید با یک مثال گویا جلو برویم. در اینجا ، ما باید یک نمونه Order را به عنوان یک رشته ارائه دهیم. اول ، ما فقط دو نوع نمایش رشته داریم ، JSON و متن ساده. استفاده از If-Else در این مرحله مسئله چندان مهمی نیست ، بنابراین ما می توانیم به راحتی جای دیگری را جایگزین کنیم.
با علم به اینکه ما باید این قسمت از برنامه را گسترش دهیم ، این روش قطعاً قابل قبول نیست.
کد بالا نه تنها اصل Open / Closed را نقض می کند ، بلکه بخوبی خوانده نمی شود و باعث سردردهای دائمی نگهداری می شود.
رویکرد صحیح روشی است که به اصول SOLID پایبند باشد - و ما این کار را با اجرای یک فرآیند dynamic type discovery، و در این مورد، الگوی استراتژی انجام میدهیم.
روند refactor این قطعه به شرح زیر است:
کدی که جایگزین مثال بالا می شود به این شکل است. و بله ، این کد بیشتر است.
من فقط قسمت دقیقی را نشان می دهم که جایگزین مثال If-Else خواهد شد.اگر علاقه مند به نحوه کامل این پیاده سازی هستید به این لینک رجوع کنید.
برگرفته شده از مدیوم Nicklas Millard