عنوان:

‫بهترین روش تولید متن پیغام کدام است؟


نویسنده: هادی مزارعی
تاریخ: ۱۴۰۴/۰۸/۱۴ ۲۱:۱۰
آدرس: www.dntips.ir
  1. قراره یک پروژه Windows Application یا همان Windows Form از یک سرویس که با ASP.NET پیاده سازی شده کار کنه.
  2. تمام Handlerها در یک پروژه با نام Application پیاده‌سازی شده‌اند و Reference این پروژه شامل Domain, Infrastructure, Shared و... می‌باشد که بخش سرویس‌های وب هستند.
  3. تمام اعتبارسنجی‌ها (Validations) در Application انجام می‌شود و نتیجه بصورت یک ApiResponse برگردانده خواهد شد که این کلاس یک ویژگی از نوع List دارد که فهرست پیغام‌های تولید شده در لایه Application را برای Client برمی‌گرداند.
  4. اگرچه که پروژه Client نیازی به هیچگونه اعتبارسنجی ندارد (تمام در Application انجام می‌گیرد) ولی به جهت جلوگیری از ارسال درخواست‌های دارای اشکال، اندکی اعتبارسنجی از ورودی‌های کاربر در Formها انجام شده است.
  5. در حال حاضر متن تمام پیغام‌ها در لایه Application در خطی که اعتبارسنجی انجام می‌شود به ApiResponse اضافه می‌شود و در برنامه Client نیز در همان خط که اعتبارسنجی انجام می‌شود یک پیغام نمایش داده می‌شود.

آنچه که میتوانم انجام دهم
  1. ترجیح میدم از فایل‌های Resource استفاده نکنم.
  2. میتونم در یک کلاس، ثابت‌های رشته‌ای (string constant) تعریف کنم و در همه جا در دسترس باشند. مشکل من در نامگذاری ثابت‌ها است که بتوانم متن پیغام را در بخش‌های دیگر برنامه از نام ثابت بفهمم. البته ثابت‌ها یک مزیت دارند که در Intelisense و Tipsهایی که ویرایشگر کد نمایش می‌دهد، مقدار ذخیره شده در ثابت کامل نمایش داده می‌شود ولی لازمه‌ی این کار آنست که روی آن گزینه در منوی باز شده قرار گیرم.
  3. استفاده از متغیرهای static که مشابه constantهایی هستند که در بالا عنوان شد ولی در Intelisense مقدار کامل متغیر static نمایش داده نمی‌شود مگر آنکه از توضیحات xml استفاده کنم که کار اضافی است.

سوال
  1. چطور یک منبع متن پیغام (Message Text Source) ایجاد کنم؟ (تعداد پیغام‌ها تقریبا زیاد هستند)
  2. آیا واقعا ایجاد یک منبع متنی برای پیغام‌ها پیشنها می‌شود یا بهتر است در همان خط تولید شود؟ (جدا از سهولت تبدیل به زبان دوم).
  3. در صورتی که منبع متن پیغام پیشنهاد می‌شود آیا برای تمام Solution پیاده سازی شود و یا هر پروژه؟

نظرات

  • وحید نصیری در ۱۴۰۴/۰۸/۱۵ ۰۸:۵۸
    استفاده از یک منبع متمرکز برای متن پیغام‌ها، حتی با وجود عدم تمایل به استفاده از فایل‌های Resource، بسیار پیشنهاد می‌شود و بهترین روش است. این کار به مدیریت، خوانایی، و نگهداری کد کمک شایانی می‌کند، به‌ویژه با توجه به زیاد بودن تعداد پیغام‌ها.

    بهترین روش پیشنهادی: کلاس ثابت‌های رشته‌ای (String Constants Class) بهبودیافته

    با توجه به محدودیت‌ها و ترجیحات شما (عدم استفاده از فایل‌های Resource و نیاز به درک متن پیغام از روی نام ثابت)، استفاده از کلاس ثابت‌های رشته‌ای (String Constants) بهترین گزینه است، اما باید با یک ساختار نام‌گذاری قوی و تقسیم‌بندی منطقی همراه باشد تا مشکل نام‌گذاری حل شود.

    ۱. ساختار کلاس ثابت‌ها
    به جای تعریف همه ثابت‌ها در یک کلاس بزرگ، آن‌ها را بر اساس ماژول یا حوزه (Domain/Application Layer) یا نوع خطا/پیغام (مانند Validation, Success, Authorization) دسته‌بندی کنید.
    مثال ساختار:
    namespace Application.Shared.Messages
    {
        // برای پیغام‌های مرتبط با اعتبارسنجی عمومی
        public static class ValidationMessages
        {
            public const string FieldIsRequired = "ورود این فیلد اجباری است.";
            public const string InvalidLength_MinMax = "طول {0} باید بین {1} و {2} کاراکتر باشد."; // برای پیغام‌های دارای پارامتر
            public const string InvalidEmailFormat = "قالب ایمیل وارد شده صحیح نیست.";
        }
    
        // برای پیغام‌های مرتبط با عملیات موفقیت آمیز
        public static class SuccessMessages
        {
            public const string EntityCreated = "{0} با موفقیت ثبت شد.";
            public const string EntityUpdated = "{0} با موفقیت ویرایش شد.";
        }
    
        // برای پیغام‌های مرتبط با یک ماژول خاص (مثلاً کاربران)
        public static class UserMessages
        {
            public const string UsernameAlreadyExists = "نام کاربری قبلاً در سیستم ثبت شده است.";
            public const string UserNotFound = "کاربر مورد نظر یافت نشد.";
        }
    }

    ۲. تکنیک نام‌گذاری قوی برای بهبود InteliSense
    مشکل شما در نام‌گذاری ثابت‌ها برای درک متن پیغام حل می‌شود اگر:
    نام ثابت‌ها را بر اساس مفهوم خطا/پیغام بنویسید، نه تلاش برای بازتولید کل متن پیغام در نام.
    • به جای:public const string User_Required_Field_Error = "ورود نام کاربر اجباری است."
    • استفاده کنید:public const string FieldIsRequired = "ورود این فیلد اجباری است."
    استفاده از پارامترها (جایگزین‌ها): برای پیغام‌های پویا (مثلاً طول فیلد) از string.Format یا همان $ در C# استفاده کنید.
    • نام ثابت:InvalidLength_MinMax
    • متن ثابت:طول {0} باید بین {1} و {2} کاراکتر باشد.
    • نحوه استفاده:string.Format(ValidationMessages.InvalidLength_MinMax, "نام", 5, 50)
    این روش باعث می‌شود که با تایپ کردن ValidationMessages. لیستی از مفاهیم اعتبارسنجی را ببینید که بسیار خواناتر و منظم‌تر است و نیاز به فایل XML Doc اضافی را برای متغیرهای static از بین می‌برد. همچنین، مزیت کامل نمایش داده شدن متن در InteliSense ثابت‌ها حفظ می‌شود.


    پاسخ به سؤالات

    آیا واقعاً ایجاد یک منبع متنی برای پیغام‌ها پیشنهاد می‌شود؟
    بله، قطعاً پیشنهاد می‌شود.
    • نگهداری و مدیریت: اگر نیاز به تغییر یک پیغام (مثلاً تغییر املای یک کلمه) داشته باشید، فقط یک جا باید آن را تغییر دهید.
    • ثبات و استانداردسازی: تضمین می‌کند که پیغام‌های یکسان (مانند "این فیلد اجباری است") همیشه یک متن استاندارد و یکسان داشته باشند.
    • خوانایی کد (Readability): به جای دیدن یک رشته طولانی فارسی در دل کدهای اعتبارسنجی، یک نام ثابت مفهومی و تمیز مانند ValidationMessages.FieldIsRequired را می‌بینید که هدف کد را بهتر بیان می‌کند.
    • آمادگی برای چندزبانه شدن (حتی اگر الان مطرح نیست): در آینده اگر نیاز به زبان دوم پیش آمد، ساختار فعلی شما آماده است و تنها نیاز به تبدیل ثابت‌ها به Resource/Dictionary/DB است.

    در صورتی که منبع متن پیغام پیشنهاد می‌شود، آیا برای تمام Solution پیاده سازی شود و یا هر پروژه؟
    در لایه Shared (یا یک زیرپروژه مستقل برای اشتراک‌گذاری).
    • از آنجایی که شما یک لایه Shared دارید و این پیغام‌ها هم توسط لایه Application (که پیغام‌ها را تولید می‌کند) و هم توسط Client (برای اعتبارسنجی اولیه فرم‌ها) استفاده می‌شوند، بهترین محل، قرار دادن این کلاس‌های ثابت در لایه Shared است.
    • اگرچه Client شما اعتبارسنجی کامل را انجام نمی‌دهد، اما برای اعتبارسنجی‌های اولیه از این ثابت‌ها استفاده می‌کند.
    • این کار باعث می‌شود همه‌ی اجزای Solution به منبع واحد پیغام دسترسی داشته باشند و از دوباره‌کاری و ناسازگاری متون پیغام جلوگیری شود.

    خلاصه پیاده‌سازی
    • ایجاد یک پوشه/فضای نام (Namespace) مثلاً Messages در پروژه Shared.
    • ایجاد کلاس‌های ثابت رشته‌ای public static class (مثلاً ValidationMessages, SuccessMessages, UserMessages) در این Namespace.
    • استفاده از نام‌های ثابت مفهومی (مثل FieldIsRequired) به جای تلاش برای بازتولید متن کامل.
    • استفاده از string.Format در لایه Application و Client برای پیغام‌های پویا.
    • در لایه Application: هنگام پر کردن List پیغام‌های ApiResponse، از این ثابت‌ها استفاده کنید.
    • در برنامه Client: هنگام اعتبارسنجی‌های اولیه ورودی کاربر، از همین ثابت‌ها برای نمایش پیغام استفاده کنید.