عنوان:

‫کدام روش بهینه‌تر است: Named Parameters یا Class Parameter؟


نویسنده: هادی مزارعی
تاریخ: ۱۴۰۴/۰۲/۲۵ ۲۱:۴۲
آدرس: www.dntips.ir
سلام

فرض:
1- کلاس‌های Domain شامل Proeprtyهای زیادی هستند
2- نمونه سازی از کلاس‌های Domain به منظور ثبت در بانک اطلاعاتی به دفعات زیادی انجام می‌شود
3- برنامه ممکن است در بهترین حالت 100 کاربر داشته باشد و تعداد تراکنش‌ در برنامه نسبتا بالاست

سوال:
زمانی که قرار است نمونه سازی از کلاس Domain انجام شود (با استفاده از متد public static Create) لازم است که مقادیر تمام propertyها به متد Create ارسال شود تا نمونه ایجاد و برگردانده شود. اما سوال اینه که کدام روش برای ارسال پارامتر مناسب‌تر است:
1- Named Paramter: شخصا حس میکنم کد کمی بهم ریخته و شلوغه میشه. اگر هم از نام پارامتر استفاده نکنم قطعا دردسر ترتیب مقداردهی چالش خواهد بود مخصوصا اگر پارارمترها زیاد باشند.
2- Class Parameter: شخصا فکر میکنم کد تمیزتر و خواناتر هستش و DTOی طراحی شده قابل استفاده مجدد جهت ارسال مقادیر در لایه‌های مختلف و متدهای متعدد خواهد بود.
3- Builder Pattern: اگر چه که پیاده‌سازی جالبیه ولی ضرورت ایجاد و استفاده از این الگو برای چه زمانی الزام آور میشه؟

تشکر

نظرات

  • وحید نصیری در ۱۴۰۴/۰۲/۲۵ ۲۲:۴۱
    برای انتخاب روش بهینه، با توجه به فرضیات مطرح شده:
    • تعداد Propertyهای زیاد: هر سه روش می‌توانند با Propertyهای زیاد کنار بیایند، اما Named Parameters با افزایش تعداد پارامترها به‌سرعت ناخوانا می‌شود.
    • تکرار بالای نمونه‌سازی: در سناریوهای با تراکنش بالا، عملکرد اهمیت دارد. Named Parameters و Class Parameter از نظر عملکرد مشابه هستند، اما Builder Pattern ممکن است به دلیل ایجاد شیء اضافی (Builder) هزینه ناچیزی داشته باشد.
    • خوانایی و نگهداری: Class Parameter و Builder Pattern هر دو کد تمیزتری تولید می‌کنند، اما Builder خوانایی بیشتری به‌ویژه برای Propertyهای اختیاری ارائه می‌دهد.
    • انتقال داده بین لایه‌ها: Class Parameter (DTO) به دلیل قابلیت استفاده مجدد، برای انتقال داده بین لایه‌ها (مثلاً از UI به سرویس) مناسب‌تر است.
    • پیچیدگی پیاده‌سازی: Named Parameters ساده‌ترین پیاده‌سازی را دارد، Class Parameter کمی پیچیده‌تر است (نیاز به DTO)، و Builder Pattern پیچیده‌ترین است.

    توصیه:
    با توجه به فرضیات (تعداد زیاد Propertyها، تکرار بالا، و احتمال نیاز به انتقال داده بین لایه‌ها)، Class Parameter (DTO) بهینه‌ترین گزینه به نظر می‌رسد. دلایل:
    • کد تمیز و خوانایی تولید می‌کند.
    • DTO آن قابل استفاده مجدد است و می‌تواند در لایه‌های مختلف برنامه استفاده شود.
    • نگهداری آن آسان است و با تغییرات در Propertyها، امضای متد Create ثابت می‌ماند.
    • برای مثال این‌ها مشکلات به همراه Named Parameters هستند:
      • شلوغی کد: با زیاد شدن Propertyها (مثلاً 10 یا بیشتر)، امضای متد و فراخوانی آن شلوغ و ناخوانا می‌شود.
      • ترتیب پارامترها: اگر از Named Arguments استفاده نشود، ترتیب پارامترها می‌تواند باعث خطا شود.
      • عدم قابلیت استفاده مجدد: پارامترها فقط برای این متد خاص هستند و نمی‌توان آن‌ها را به لایه‌های دیگر منتقل کرد.
      • نگهداری سخت: اگر Propertyهای کلاس تغییر کنند (اضافه یا حذف شوند)، امضای متد باید به‌روزرسانی شود.
    • در مقایسه با Builder Pattern، پیاده‌سازی ساده‌تری دارد و برای سناریوهایی که تمام Propertyها اجباری هستند، سربار غیرضروری ایجاد نمی‌کند.
    • برای نمونه در حین کار با Builder Pattern باید به این مشکلات دقت داشت:
      • پیچیدگی پیاده‌سازی: نیاز به تعریف کلاس Builder و متدهای مربوطه است که برای پروژه‌های کوچک ممکن است بیش از حد پیچیده باشد.
      • سربار نگهداری: اگر تعداد Propertyها زیاد باشد، Builder نیز بزرگ و پیچیده می‌شود.
      • عملکرد: در سناریوهای با تعداد تراکنش بسیار بالا، ایجاد شیء Builder و زنجیره متدها ممکن است هزینه محاسباتی کمی داشته باشد (هرچند معمولاً ناچیز است).

    چه زمانی از Builder Pattern استفاده کنیم؟ Builder Pattern زمانی الزام‌آور می‌شود که:
    • برخی Propertyها اختیاری باشند و نیاز به تنظیم انعطاف‌پذیر آن‌ها وجود داشته باشد.
    • نیاز به اعتبارسنجی پیچیده یا منطق خاص در زمان ساخت شیء باشد (مثلاً بررسی اینکه برخی Propertyها فقط در شرایط خاصی تنظیم شوند).

    جمع‌بندی: برای سناریوی شما، استفاده از Class Parameter (DTO) توصیه می‌شود، زیرا تعادل خوبی بین خوانایی، قابلیت نگهداری، و سادگی پیاده‌سازی ارائه می‌دهد. اگر در آینده نیاز به انعطاف‌پذیری بیشتر یا Propertyهای اختیاری پیدا کردید، می‌توانید به سمت Builder Pattern مهاجرت کنید. Named Parameters به دلیل شلوغی و مشکلات نگهداری، گزینه مناسبی برای این سناریو نیست.
  • یاسین اسدنژاد در ۱۴۰۴/۰۳/۰۱ ۱۲:۳۱
    از Dictionary<string, object> هم میتونید استفاده کنید. صرفا یک پیشنهاد هست. ولی خوب آقا وحید پیشنهاد و حرف منطقی گفتند.
    • هادی مزارعی در ۱۴۰۴/۰۳/۰۱ ۱۳:۲۲
      در استفاده از مقادیر object باید یکبار تبدیل هم انجام شود و دسترسی به مقادیر داخل دیکشنری براساس کلید مستلزم دانستن نام کلید هست. ضمن اینکه اگر تابعی را در دسترس یک توسعه دهنده قرار گیرد چطور باید متوجه شود که چه تعداد پارامتر و با چه نامی به متد ارسال شود؟ در هر دو حالت Named Arguments و یا Class Paramter یک وجه اشتراک هست که نام از پیش تعریف شده برای پارامتر و تعداد معلوم پارامترهای یک متد یا سازنده کلاس است. البته شاید برای نوع Dictionary بشه ثابت‌هایی از نوع string که مقدار آنها همان نام پارامتر هست تعریف کرد و از اونها برای key استفاده کرد که به نظرم تمیزی کد از بین میره.