فیلد موقتی یا Temporary field در دسته بندی الگوهای «
بد استفاده کنندگان از شیء گرایی» قرار میگیرد. در این الگوی بد، فیلدها یا خصوصیات یک کلاس، در شرایط خاصی مقدار گرفته و مورد استفاده قرار میگیرند و در بقیه شرایط خالی هستند.
زمانیکه در یک کلاس، متدی برای انجام فعالیت خود، تعدادی پارامتر ورودی زیادی نیاز داشته باشد، ممکن است برنامه نویس برای مواجه نشدن با تعداد پارامترهای زیاد ورودی، فیلدها یا خصوصیاتی را در کلاس مربوط به آن متد ایجاد کند. این فیلدها عملا فقط زمان صدا زدن آن متد مقدار گرفته و در بقیه شرایط خالی هستند.
خواندن و استفاده از این نوع کدها معمولا مشکل و چالش برانگیز است. زیرا خواننده شاهد فیلدهایی است که در اکثر مواقع خالی هستند. همچنین زمان استفاده از این کلاس نمیتوان از وجود مقادیر فیلدها یا خصوصیات آنها اطمینان لازم را داشت.
روشهای اصلاح این کد بد بو
برای اصلاح چنین بوی بدی به طور معمول دو راه وجود دارد.
اول: با در نظر گرفتن اینکه تمامی کد موجود در متد و فیلدهای مرتبط به آن قابلیت انتقال به کلاس خاص خودشان را دارند، میتواند کلاس مجزایی را برای آن متد و فیلدهای مربوطه ایجاد کرد.
دوم: برای فیلدها و خصوصیاتی که در خیلی مواقع خالی هستند، میتوان با روش
Null object برای وضعیت خالی بودن آن، یک شیء خالی بی اثر را ایجاد کرد.
به مثال زیر توجه کنید:
فرض کنید در حال تولید سیستمی هستید که در روال خاصی، نیاز به محاسبه پورسانت فروشندهها دارید. برای محاسبه پورسانت به موارد زیر نیاز است:
- لیست محصولات فروخته شده
- درصد کمیسیون خام
- تاریخ فروش
- شعبه فروش
- نوع پرداخت
به طور نمونه اگر فروشنده فروش نقدی ای انجام دهد، کمیسیون بیشتری نسبت به کمیسیون پیشفرض، به او تعلق خواهد گرفت و …
ممکن است طراحی اولیه برای چنین متدی به صورت زیر باشد:
public class Salesman
{
public void Method1()
{
return;
}
public void Method2()
{
return;
}
public void Method3()
{
return;
}
public decimal CalculateCommission(dynamic products, dynamic commissionRate, dynamic saleDate, dynamic branch, dynamic paymentType)
{
return decimal.MaxValue;
}
}
با مشاهده پارامترهای زیاد متد، برنامه نویس میتواند از روشهای اصلاح بوی بد «
تعداد زیاد پارامترهای ورودی» استفاده کند. یا اینکه برنامه نویس برای خلاصی از این کد بد بو، بجای ارسال پارامتر، فیلدهایی را در کلاس Salesman ایجاد کند؛ مانند کد زیر:
public class SalesmanV2
{
public IEnumerable<dynamic> Products { get; set; }
public dynamic CommisionRate { get; set; }
public dynamic SaleDate { get; set; }
public dynamic Branch { get; set; }
public dynamic PaymentType { get; set; }
public void Method1()
{
return;
}
public void Method2()
{
return;
}
public void Method3()
{
return;
}
public decimal CalculateCommission()
{
return decimal.MaxValue;
}
}
با این تغییر، پارامترهای متد CalculateCommision به خصوصیاتی در کلاس Salesman تبدیل خواهند شد. دقت کنید این کلاس متدهای دیگری برای فعالیتهای مختلف دارد.
در روشهای اصلاح این کد بد بو، اشاره به انتقال منطق متد مذکور به کلاس مجزا و مخصوص به خود شده بود. در واقع کد بد بوی «فیلد موقتی» ناشی از عدم رعایت اصل single responsibility است و محاسبه پورسانت را از نظر ذاتی میتوان وظیفهی اضافهای در این کلاس دانست. با توجه به اینکه میتوان محاسبه پورسانت را به صورت جداگانه پیاده سازی کرد. به چنین پیاده سازی ای خواهیم رسید.
public class SalesmanV3
{
public void Method1()
{
return;
}
public void Method2()
{
return;
}
public void Method3()
{
return;
}
}
public class CommissionCalculator
{
private IEnumerable<dynamic> _products;
private dynamic _commisionRate;
private dynamic _saleDate;
private dynamic _branch;
private dynamic _paymentType;
public CommissionCalculator(IEnumerable<dynamic> products, dynamic commisionRate,
dynamic saleDate, dynamic branch, dynamic paymentType)
{
_products = products;
_commisionRate = commisionRate;
_saleDate = saleDate;
_branch = branch;
_paymentType = paymentType;
}
}
در شرایط نادری، کد بد بوی «فیلد موقتی» ناشی از عدم رعایت اصل single responsibility نیست. در چنین شرایطی میتوان از null object برای رفع این بوی بد استفاده کرد.
جمع بندی
همانطور که در متن نیز اشاره شد، عدم رعایت اصل single responsibility میتواند منجر به چنین کد بد بویی شود. این کد بد بو با روشهای سادهای قابل اصلاح است. اصلاح چنین بویی خوانایی و قابلیت نگهداری کد را افزایش خواهد داد.