اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
سه دقیقه
زمانیکه متدی بیش از سه یا چهار پارامتر ورودی داشته باشد، به چنین مشکلی برخوردهایم. این بوی بد کد از دسته «کدهای متورم» است. کدهای متورم معمولا به مرور زمان ایجاد و کار را برای نگهداری کد سخت میکنند.
توجه به این نکته که کدهای متورم به مرور زمان به این وضعیت دچار میشوند امری ضروری در درک بهتر و جلوگیری از این حالت بد کد است.
این نوع کد بد بو معمولا در شرایط زیر ایجاد میشود:
- زمانیکه کارهای زیادی به مرور زمان به یک متد محول و پارامترهایی برای کنترل رفتار متد در شرایط مختلف ایجاد میشود.
- این الگوی بد میتواند محصول جانبی مستقل کردن کلاسها و متدها باشد. فرض کنید در بدنه متدی، شیءای نیاز است و مکانیزم ساخته شدن این شیء نیز در بدنه همان متد پیاده سازی شدهاست. برای جداسازی منطق ایجاد شیء مربوطه، ممکن است تصمیم به انتقال آن به کلاس استفاده کننده از متد باشد. به این صورت که در آن کلاس، شیء مورد نیاز این متد ایجاد شود و به صورت پارامتر به این متد ارسال شود. زمانیکه تعداد این پارامترها زیاد شدند باید دقت بیشتری به کد داشت.
طراحی کلاسها و متدها باید به گونهای باشد که تا حد امکان متدها از دادههای موجود در شیء خود استفاده کنند و در صورتیکه به هیچ طریقی داده مربوطه از طریق شیء آنها قابل دسترسی نبود، آن داده به صورت پارامتر به متد ارسال شود.
روشهای اصلاح این نوع کد بد بو
1) اگر در پارامترهای متد نوعی (type) وجود دارد که خود در زمان صدا زدن متد توسط روالی ایجاد میشود، میتوان در شرایط مناسب روال ایجاد پارامتر را در بدنه خود متد صدا زد (Replace parameter with method call).
به طور مثال به تکه کد زیر توجه کنید.
... var basePrice = _quantity * _itemPrice; var discountLevel = getDiscountLevel(); var finalPrice = discountedPrice (..., ..., ..., basePrice, discountLevel); ...
... var basePrice = _quantity * _itemPrice; var finalPrice = discountedPrice (..., ..., ..., basePrice); ...
2) اگر تعدادی پارامتر از یک شیء استخراج شده و به متد ارسال میشود، میتوان خود آن شیء را به صورت کامل به متد ارسال کرد (Preserve whole object).
... var dueDate = invoice.DueDate; var amount = invoice.Amount; var discount = invoice.Discount; var code = invoice.Code; var id = invoice.Id; IssuePayment(paymentType, id,dueDate,amount,discount,code); ...
در مثال بالا ملاحظه میکنید که مقادیر اطلاعاتی مورد نیاز برای صادر کردن یک پرداخت مانند نوع پرداخت و اطلاعات مبلغ و تاریخ پرداخت آن از invoice و مبداهای متفاوتی بدست آمدهاست. بخشی از اطلاعات را که از invoice بدست میآید، میتوان بجای دستیابی جداگانه و ارسال جداگانه آن، توسط کل شیء invoice انجام داد. به طوریکه کل شیء invoice به متد صدور پرداخت ارسال شود. مانند تکه کد زیر:
... IssuePayment(paymentType, invoice); ...
یکی از مزایای استفاده از چنین روشی کاسته شدن کدهای تکراری مورد نیاز برای فراخوانی متد است. همچنین خوانایی و قابلیت گسترش این مکانیزم نیز بالا خواهد رفت.
3) اگر تعداد پارامترهای زیادی وجود دارند، میتوان یک کلاس پارامتر ساخت و پارامترها را در آن کلاس تعریف، مقداردهی و به متد ارسال کرد (Parameter object).
جمع بندی
موارد مطرح شده برای رفع این بوی بد، در واقع روشهای مختلف Refactoring هستند که برای این شرایط پیشنهاد شدهاند. در مباحث مربوط به Refactoring این راه حلها به صورت مفصلتری بررسی شدهاند.
زمانیکه این بوی بد برطرف شد، معمولا شاهد کدی خواناتر و قابل توسعهتر خواهیم بود. همچنین احتمال اینکه کدهای تکراری حذف شوند و جلوی ایجاد کدهای تکراری جدید نیز گرفته شود، بسیار زیاد است.